Move VISUAL_STATE promise to activation
[chromium-blink-merge.git] / ui / ozone / platform / cast / surface_factory_cast.cc
blob6fdd7eff2953a3fcaeb570a37631a99137992f2c
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;
14 namespace ui {
15 namespace {
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);
25 } // namespace
27 SurfaceFactoryCast::SurfaceFactoryCast(scoped_ptr<CastEglPlatform> egl_platform)
28 : state_(kUninitialized),
29 destroy_window_pending_state_(kNoDestroyPending),
30 display_type_(0),
31 have_display_type_(false),
32 window_(0),
33 display_size_(0, 0),
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) {
44 return;
46 CHECK_EQ(state_, kUninitialized);
48 if (egl_platform_->InitializeHardware()) {
49 state_ = kInitialized;
50 } else {
51 ShutdownHardware();
52 state_ = kFailed;
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) {
71 InitializeHardware();
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);
83 if (!window_) {
84 DestroyDisplayTypeAndWindow();
85 state_ = kFailed;
86 LOG(FATAL) << "Create EGLNativeWindowType(" << display_size_.ToString()
87 << ") failed.";
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;
104 return true;
107 void SurfaceFactoryCast::DestroyDisplayTypeAndWindow() {
108 if (window_) {
109 egl_platform_->DestroyWindow(window_);
110 window_ = 0;
112 if (have_display_type_) {
113 egl_platform_->DestroyDisplayType(display_type_);
114 display_type_ = 0;
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;
139 break;
140 case kSurfaceExists:
141 destroy_window_pending_state_ = kWindowDestroyPending;
142 break;
143 case kWindowDestroyPending:
144 break;
145 default:
146 NOTREACHED();
150 void SurfaceFactoryCast::ChildDestroyed() {
151 if (destroy_window_pending_state_ == kWindowDestroyPending) {
152 DestroyDisplayTypeAndWindow();
153 SendRelinquishResponse();
154 destroy_window_pending_state_ = kNoDestroyPending;
155 } else {
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) {
177 return false;
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) {
185 return false;
188 set_gl_get_proc_address.Run(gl_proc);
189 add_gl_library.Run(lib_egl);
190 add_gl_library.Run(lib_gles2);
191 return true;
194 } // namespace ui