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/ozone/platform/cast/surface_ozone_egl_cast.h"
12 using chromecast::CastEglPlatform
;
16 chromecast::Size
FromGfxSize(const gfx::Size
& size
) {
17 return chromecast::Size(size
.width(), size
.height());
20 // Hard lower bound on display resolution
21 gfx::Size
GetMinDisplaySize() {
22 return gfx::Size(1280, 720);
27 SurfaceFactoryCast::SurfaceFactoryCast(scoped_ptr
<CastEglPlatform
> egl_platform
)
28 : state_(kUninitialized
),
29 destroy_window_pending_state_(kNoDestroyPending
),
31 have_display_type_(false),
34 new_display_size_(0, 0),
35 egl_platform_(egl_platform
.Pass()) {
38 SurfaceFactoryCast::~SurfaceFactoryCast() {
39 DestroyDisplayTypeAndWindow();
42 void SurfaceFactoryCast::InitializeHardware() {
43 if (state_
== kInitialized
) {
46 CHECK_EQ(state_
, kUninitialized
);
48 if (egl_platform_
->InitializeHardware()) {
49 state_
= kInitialized
;
56 void SurfaceFactoryCast::ShutdownHardware() {
57 DestroyDisplayTypeAndWindow();
59 egl_platform_
->ShutdownHardware();
61 state_
= kUninitialized
;
64 intptr_t SurfaceFactoryCast::GetNativeDisplay() {
65 CreateDisplayTypeAndWindowIfNeeded();
66 return reinterpret_cast<intptr_t>(display_type_
);
69 void SurfaceFactoryCast::CreateDisplayTypeAndWindowIfNeeded() {
70 if (state_
== kUninitialized
) {
73 if (new_display_size_
!= display_size_
) {
74 DestroyDisplayTypeAndWindow();
75 display_size_
= new_display_size_
;
77 DCHECK_EQ(state_
, kInitialized
);
78 if (!have_display_type_
) {
79 chromecast::Size create_size
= FromGfxSize(display_size_
);
80 display_type_
= egl_platform_
->CreateDisplayType(create_size
);
81 have_display_type_
= true;
82 window_
= egl_platform_
->CreateWindow(display_type_
, create_size
);
84 DestroyDisplayTypeAndWindow();
86 LOG(FATAL
) << "Create EGLNativeWindowType(" << display_size_
.ToString()
92 intptr_t SurfaceFactoryCast::GetNativeWindow() {
93 CreateDisplayTypeAndWindowIfNeeded();
94 return reinterpret_cast<intptr_t>(window_
);
97 bool SurfaceFactoryCast::ResizeDisplay(gfx::Size size
) {
98 // set size to at least 1280x720 even if passed 1x1
99 size
.SetToMax(GetMinDisplaySize());
100 if (have_display_type_
&& size
!= display_size_
) {
101 DestroyDisplayTypeAndWindow();
103 display_size_
= size
;
107 void SurfaceFactoryCast::DestroyDisplayTypeAndWindow() {
109 egl_platform_
->DestroyWindow(window_
);
112 if (have_display_type_
) {
113 egl_platform_
->DestroyDisplayType(display_type_
);
115 have_display_type_
= false;
119 scoped_ptr
<SurfaceOzoneEGL
> SurfaceFactoryCast::CreateEGLSurfaceForWidget(
120 gfx::AcceleratedWidget widget
) {
121 new_display_size_
= gfx::Size(widget
>> 16, widget
& 0xFFFF);
122 new_display_size_
.SetToMax(GetMinDisplaySize());
123 destroy_window_pending_state_
= kSurfaceExists
;
124 SendRelinquishResponse();
125 return make_scoped_ptr
<SurfaceOzoneEGL
>(new SurfaceOzoneEglCast(this));
128 void SurfaceFactoryCast::SetToRelinquishDisplay(const base::Closure
& callback
) {
129 // This is called in response to a RelinquishDisplay message from the
130 // browser task. This call may come before or after the display surface
131 // is actually destroyed.
132 relinquish_display_callback_
= callback
;
133 switch (destroy_window_pending_state_
) {
134 case kNoDestroyPending
:
135 case kSurfaceDestroyedRecently
:
136 DestroyDisplayTypeAndWindow();
137 SendRelinquishResponse();
138 destroy_window_pending_state_
= kNoDestroyPending
;
141 destroy_window_pending_state_
= kWindowDestroyPending
;
143 case kWindowDestroyPending
:
150 void SurfaceFactoryCast::ChildDestroyed() {
151 if (destroy_window_pending_state_
== kWindowDestroyPending
) {
152 DestroyDisplayTypeAndWindow();
153 SendRelinquishResponse();
154 destroy_window_pending_state_
= kNoDestroyPending
;
156 destroy_window_pending_state_
= kSurfaceDestroyedRecently
;
160 void SurfaceFactoryCast::SendRelinquishResponse() {
161 if (!relinquish_display_callback_
.is_null()) {
162 base::ResetAndReturn(&relinquish_display_callback_
).Run();
166 const int32
* SurfaceFactoryCast::GetEGLSurfaceProperties(
167 const int32
* desired_list
) {
168 return egl_platform_
->GetEGLSurfaceProperties(desired_list
);
171 bool SurfaceFactoryCast::LoadEGLGLES2Bindings(
172 AddGLLibraryCallback add_gl_library
,
173 SetGLGetProcAddressProcCallback set_gl_get_proc_address
) {
174 if (state_
!= kInitialized
) {
175 InitializeHardware();
176 if (state_
!= kInitialized
) {
181 void* lib_egl
= egl_platform_
->GetEglLibrary();
182 void* lib_gles2
= egl_platform_
->GetGles2Library();
183 GLGetProcAddressProc gl_proc
= egl_platform_
->GetGLProcAddressProc();
184 if (!lib_egl
|| !lib_gles2
|| !gl_proc
) {
188 set_gl_get_proc_address
.Run(gl_proc
);
189 add_gl_library
.Run(lib_egl
);
190 add_gl_library
.Run(lib_gles2
);