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 "ui/ozone/platform/cast/surface_ozone_egl_cast.h"
11 using chromecast::CastEglPlatform
;
15 CastEglPlatform::Size
FromGfxSize(const gfx::Size
& size
) {
16 return CastEglPlatform::Size(size
.width(), size
.height());
18 gfx::Size
ToGfxSize(const CastEglPlatform::Size
& size
) {
19 return gfx::Size(size
.width
, size
.height
);
23 SurfaceFactoryCast::SurfaceFactoryCast(scoped_ptr
<CastEglPlatform
> egl_platform
)
24 : state_(kUninitialized
),
25 destroy_window_pending_state_(kNoDestroyPending
),
28 default_display_size_(ToGfxSize(egl_platform
->GetDefaultDisplaySize())),
29 display_size_(default_display_size_
),
30 new_display_size_(default_display_size_
),
31 egl_platform_(egl_platform
.Pass()) {
34 SurfaceFactoryCast::~SurfaceFactoryCast() {
35 DestroyDisplayTypeAndWindow();
38 void SurfaceFactoryCast::InitializeHardware() {
39 if (state_
== kInitialized
) {
42 CHECK_EQ(state_
, kUninitialized
);
44 if (egl_platform_
->InitializeHardware()) {
45 state_
= kInitialized
;
52 void SurfaceFactoryCast::ShutdownHardware() {
53 DestroyDisplayTypeAndWindow();
55 egl_platform_
->ShutdownHardware();
57 state_
= kUninitialized
;
60 intptr_t SurfaceFactoryCast::GetNativeDisplay() {
61 CreateDisplayTypeAndWindowIfNeeded();
62 return reinterpret_cast<intptr_t>(display_type_
);
65 void SurfaceFactoryCast::CreateDisplayTypeAndWindowIfNeeded() {
66 if (state_
== kUninitialized
) {
69 if (new_display_size_
!= display_size_
) {
70 DestroyDisplayTypeAndWindow();
71 display_size_
= new_display_size_
;
73 DCHECK_EQ(state_
, kInitialized
);
75 CastEglPlatform::Size create_size
= FromGfxSize(display_size_
);
76 display_type_
= egl_platform_
->CreateDisplayType(create_size
);
78 window_
= egl_platform_
->CreateWindow(display_type_
, create_size
);
80 DestroyDisplayTypeAndWindow();
82 LOG(FATAL
) << "Create EGLNativeWindowType(" << display_size_
.ToString()
87 LOG(FATAL
) << "Create EGLNativeDisplayType(" << display_size_
.ToString()
93 intptr_t SurfaceFactoryCast::GetNativeWindow() {
94 CreateDisplayTypeAndWindowIfNeeded();
95 return reinterpret_cast<intptr_t>(window_
);
98 bool SurfaceFactoryCast::ResizeDisplay(gfx::Size size
) {
99 // set size to at least 1280x720 even if passed 1x1
100 size
.SetToMax(default_display_size_
);
101 if (display_type_
&& size
!= display_size_
) {
102 DestroyDisplayTypeAndWindow();
104 display_size_
= size
;
108 void SurfaceFactoryCast::DestroyDisplayTypeAndWindow() {
110 egl_platform_
->DestroyWindow(window_
);
114 egl_platform_
->DestroyDisplayType(display_type_
);
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(default_display_size_
);
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
);