1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/ozone/platform/cast/surface_factory_cast.h"
7 #include "base/callback_helpers.h"
8 #include "chromecast/public/cast_egl_platform.h"
9 #include "chromecast/public/graphics_types.h"
10 #include "ui/gfx/geometry/quad_f.h"
11 #include "ui/ozone/platform/cast/surface_ozone_egl_cast.h"
12 #include "ui/ozone/public/native_pixmap.h"
14 using chromecast::CastEglPlatform
;
18 chromecast::Size
FromGfxSize(const gfx::Size
& size
) {
19 return chromecast::Size(size
.width(), size
.height());
22 // Initial display size to create, needed before first window is created.
23 gfx::Size
GetInitialDisplaySize() {
24 return gfx::Size(1280, 720);
27 // Hard lower bound on display resolution
28 gfx::Size
GetMinDisplaySize() {
29 return gfx::Size(1280, 720);
34 SurfaceFactoryCast::SurfaceFactoryCast(scoped_ptr
<CastEglPlatform
> egl_platform
)
35 : state_(kUninitialized
),
36 destroy_window_pending_state_(kNoDestroyPending
),
38 have_display_type_(false),
40 display_size_(GetInitialDisplaySize()),
41 new_display_size_(GetInitialDisplaySize()),
42 egl_platform_(egl_platform
.Pass()) {
45 SurfaceFactoryCast::~SurfaceFactoryCast() {
46 DestroyDisplayTypeAndWindow();
49 void SurfaceFactoryCast::InitializeHardware() {
50 if (state_
== kInitialized
) {
53 CHECK_EQ(state_
, kUninitialized
);
55 if (egl_platform_
->InitializeHardware()) {
56 state_
= kInitialized
;
63 void SurfaceFactoryCast::ShutdownHardware() {
64 DestroyDisplayTypeAndWindow();
66 egl_platform_
->ShutdownHardware();
68 state_
= kUninitialized
;
71 intptr_t SurfaceFactoryCast::GetNativeDisplay() {
72 CreateDisplayTypeAndWindowIfNeeded();
73 return reinterpret_cast<intptr_t>(display_type_
);
76 void SurfaceFactoryCast::CreateDisplayTypeAndWindowIfNeeded() {
77 if (state_
== kUninitialized
) {
80 if (new_display_size_
!= display_size_
) {
81 DestroyDisplayTypeAndWindow();
82 display_size_
= new_display_size_
;
84 DCHECK_EQ(state_
, kInitialized
);
85 if (!have_display_type_
) {
86 chromecast::Size create_size
= FromGfxSize(display_size_
);
87 display_type_
= egl_platform_
->CreateDisplayType(create_size
);
88 have_display_type_
= true;
91 chromecast::Size create_size
= FromGfxSize(display_size_
);
92 window_
= egl_platform_
->CreateWindow(display_type_
, create_size
);
94 DestroyDisplayTypeAndWindow();
96 LOG(FATAL
) << "Create EGLNativeWindowType(" << display_size_
.ToString()
102 intptr_t SurfaceFactoryCast::GetNativeWindow() {
103 CreateDisplayTypeAndWindowIfNeeded();
104 return reinterpret_cast<intptr_t>(window_
);
107 bool SurfaceFactoryCast::ResizeDisplay(gfx::Size size
) {
108 // set size to at least 1280x720 even if passed 1x1
109 size
.SetToMax(GetMinDisplaySize());
110 if (have_display_type_
&& size
!= display_size_
) {
111 DestroyDisplayTypeAndWindow();
113 display_size_
= size
;
117 void SurfaceFactoryCast::DestroyWindow() {
119 egl_platform_
->DestroyWindow(window_
);
124 void SurfaceFactoryCast::DestroyDisplayTypeAndWindow() {
126 if (have_display_type_
) {
127 egl_platform_
->DestroyDisplayType(display_type_
);
129 have_display_type_
= false;
133 scoped_ptr
<SurfaceOzoneEGL
> SurfaceFactoryCast::CreateEGLSurfaceForWidget(
134 gfx::AcceleratedWidget widget
) {
135 new_display_size_
= gfx::Size(widget
>> 16, widget
& 0xFFFF);
136 new_display_size_
.SetToMax(GetMinDisplaySize());
137 destroy_window_pending_state_
= kSurfaceExists
;
138 SendRelinquishResponse();
139 return make_scoped_ptr
<SurfaceOzoneEGL
>(new SurfaceOzoneEglCast(this));
142 void SurfaceFactoryCast::SetToRelinquishDisplay(const base::Closure
& callback
) {
143 // This is called in response to a RelinquishDisplay message from the
144 // browser task. This call may come before or after the display surface
145 // is actually destroyed.
146 relinquish_display_callback_
= callback
;
147 switch (destroy_window_pending_state_
) {
148 case kNoDestroyPending
:
149 case kSurfaceDestroyedRecently
:
150 DestroyDisplayTypeAndWindow();
151 SendRelinquishResponse();
152 destroy_window_pending_state_
= kNoDestroyPending
;
155 destroy_window_pending_state_
= kWindowDestroyPending
;
157 case kWindowDestroyPending
:
164 void SurfaceFactoryCast::ChildDestroyed() {
165 if (destroy_window_pending_state_
== kWindowDestroyPending
) {
166 DestroyDisplayTypeAndWindow();
167 SendRelinquishResponse();
168 destroy_window_pending_state_
= kNoDestroyPending
;
170 if (egl_platform_
->MultipleSurfaceUnsupported()) {
173 destroy_window_pending_state_
= kSurfaceDestroyedRecently
;
177 void SurfaceFactoryCast::SendRelinquishResponse() {
178 if (!relinquish_display_callback_
.is_null()) {
179 base::ResetAndReturn(&relinquish_display_callback_
).Run();
183 const int32
* SurfaceFactoryCast::GetEGLSurfaceProperties(
184 const int32
* desired_list
) {
185 return egl_platform_
->GetEGLSurfaceProperties(desired_list
);
188 scoped_refptr
<NativePixmap
> SurfaceFactoryCast::CreateNativePixmap(
189 gfx::AcceleratedWidget w
,
191 gfx::BufferFormat format
,
192 gfx::BufferUsage usage
) {
193 class CastPixmap
: public NativePixmap
{
197 void* GetEGLClientBuffer() override
{
198 // TODO(halliwell): try to implement this through CastEglPlatform.
201 int GetDmaBufFd() override
{ return 0; }
202 int GetDmaBufPitch() override
{ return 0; }
203 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget
,
205 gfx::OverlayTransform plane_transform
,
206 const gfx::Rect
& display_bounds
,
207 const gfx::RectF
& crop_rect
) override
{
210 void SetScalingCallback(const ScalingCallback
& scaling_callback
) override
{}
211 scoped_refptr
<NativePixmap
> GetScaledPixmap(gfx::Size new_size
) override
{
214 gfx::NativePixmapHandle
ExportHandle() override
{
215 return gfx::NativePixmapHandle();
219 ~CastPixmap() override
{}
221 DISALLOW_COPY_AND_ASSIGN(CastPixmap
);
223 return make_scoped_refptr(new CastPixmap
);
226 bool SurfaceFactoryCast::LoadEGLGLES2Bindings(
227 AddGLLibraryCallback add_gl_library
,
228 SetGLGetProcAddressProcCallback set_gl_get_proc_address
) {
229 if (state_
!= kInitialized
) {
230 InitializeHardware();
231 if (state_
!= kInitialized
) {
236 void* lib_egl
= egl_platform_
->GetEglLibrary();
237 void* lib_gles2
= egl_platform_
->GetGles2Library();
238 GLGetProcAddressProc gl_proc
= egl_platform_
->GetGLProcAddressProc();
239 if (!lib_egl
|| !lib_gles2
|| !gl_proc
) {
243 set_gl_get_proc_address
.Run(gl_proc
);
244 add_gl_library
.Run(lib_egl
);
245 add_gl_library
.Run(lib_gles2
);