OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chromecast/ozone/surface_factory_cast.h" | |
6 | |
7 #include "base/callback_helpers.h" | |
8 #include "chromecast/ozone/cast_egl_platform.h" | |
9 #include "chromecast/ozone/surface_ozone_egl_cast.h" | |
10 | |
11 namespace chromecast { | |
12 namespace ozone { | |
13 | |
14 SurfaceFactoryCast::SurfaceFactoryCast(scoped_ptr<CastEglPlatform> egl_platform) | |
15 : state_(kUninitialized), | |
16 destroy_window_pending_state_(kNoDestroyPending), | |
17 display_type_(0), | |
18 window_(0), | |
19 default_display_size_(egl_platform->GetDefaultDisplaySize()), | |
20 display_size_(default_display_size_), | |
21 new_display_size_(default_display_size_), | |
22 egl_platform_(egl_platform.Pass()) { | |
23 } | |
24 | |
25 SurfaceFactoryCast::~SurfaceFactoryCast() { | |
26 DestroyDisplayTypeAndWindow(); | |
27 } | |
28 | |
29 void SurfaceFactoryCast::InitializeHardware() { | |
30 if (state_ == kInitialized) { | |
31 return; | |
32 } | |
33 CHECK_EQ(state_, kUninitialized); | |
34 | |
35 if (egl_platform_->InitializeHardware()) { | |
36 state_ = kInitialized; | |
37 } else { | |
38 ShutdownHardware(); | |
39 state_ = kFailed; | |
40 } | |
41 } | |
42 | |
43 void SurfaceFactoryCast::ShutdownHardware() { | |
44 DestroyDisplayTypeAndWindow(); | |
45 | |
46 egl_platform_->ShutdownHardware(); | |
47 | |
48 state_ = kUninitialized; | |
49 } | |
50 | |
51 intptr_t SurfaceFactoryCast::GetNativeDisplay() { | |
52 CreateDisplayTypeAndWindowIfNeeded(); | |
53 return reinterpret_cast<intptr_t>(display_type_); | |
54 } | |
55 | |
56 void SurfaceFactoryCast::CreateDisplayTypeAndWindowIfNeeded() { | |
57 if (state_ == kUninitialized) { | |
58 InitializeHardware(); | |
59 } | |
60 if (new_display_size_ != display_size_) { | |
61 DestroyDisplayTypeAndWindow(); | |
62 display_size_ = new_display_size_; | |
63 } | |
64 DCHECK_EQ(state_, kInitialized); | |
65 if (!display_type_) { | |
66 display_type_ = egl_platform_->CreateDisplayType(display_size_); | |
67 if (display_type_) { | |
68 window_ = egl_platform_->CreateWindow(display_type_, display_size_); | |
69 if (!window_) { | |
70 DestroyDisplayTypeAndWindow(); | |
71 state_ = kFailed; | |
72 LOG(FATAL) << "Create EGLNativeWindowType(" << display_size_.ToString() | |
73 << ") failed."; | |
74 } | |
75 } else { | |
76 state_ = kFailed; | |
77 LOG(FATAL) << "Create EGLNativeDisplayType(" << display_size_.ToString() | |
78 << ") failed."; | |
79 } | |
80 } | |
81 } | |
82 | |
83 intptr_t SurfaceFactoryCast::GetNativeWindow() { | |
84 CreateDisplayTypeAndWindowIfNeeded(); | |
85 return window_; | |
86 } | |
87 | |
88 bool SurfaceFactoryCast::ResizeDisplay(gfx::Size size) { | |
89 // set size to at least 1280x720 even if passed 1x1 | |
90 size.SetToMax(default_display_size_); | |
91 if (display_type_ && size != display_size_) { | |
92 DestroyDisplayTypeAndWindow(); | |
93 } | |
94 display_size_ = size; | |
95 return true; | |
96 } | |
97 | |
98 void SurfaceFactoryCast::DestroyDisplayTypeAndWindow() { | |
99 if (window_) { | |
100 egl_platform_->DestroyWindow(window_); | |
101 window_ = 0; | |
102 } | |
103 if (display_type_) { | |
104 egl_platform_->DestroyDisplayType(display_type_); | |
105 display_type_ = 0; | |
106 } | |
107 } | |
108 | |
109 scoped_ptr<ui::SurfaceOzoneEGL> SurfaceFactoryCast::CreateEGLSurfaceForWidget( | |
110 gfx::AcceleratedWidget widget) { | |
111 new_display_size_ = gfx::Size(widget >> 16, widget & 0xFFFF); | |
112 new_display_size_.SetToMax(default_display_size_); | |
113 destroy_window_pending_state_ = kSurfaceExists; | |
114 SendRelinquishResponse(); | |
115 return make_scoped_ptr<ui::SurfaceOzoneEGL>(new SurfaceOzoneEglCast(this)); | |
116 } | |
117 | |
118 void SurfaceFactoryCast::SetToRelinquishDisplay(const base::Closure& callback) { | |
119 // This is called in response to a RelinquishDisplay message from the | |
120 // browser task. This call may come before or after the display surface | |
121 // is actually destroyed. | |
122 relinquish_display_callback_ = callback; | |
123 switch (destroy_window_pending_state_) { | |
124 case kNoDestroyPending: | |
125 case kSurfaceDestroyedRecently: | |
126 DestroyDisplayTypeAndWindow(); | |
127 SendRelinquishResponse(); | |
128 destroy_window_pending_state_ = kNoDestroyPending; | |
129 break; | |
130 case kSurfaceExists: | |
131 destroy_window_pending_state_ = kWindowDestroyPending; | |
132 break; | |
133 case kWindowDestroyPending: | |
134 break; | |
135 default: | |
136 NOTREACHED(); | |
137 } | |
138 } | |
139 | |
140 void SurfaceFactoryCast::ChildDestroyed() { | |
141 if (destroy_window_pending_state_ == kWindowDestroyPending) { | |
142 DestroyDisplayTypeAndWindow(); | |
143 SendRelinquishResponse(); | |
144 destroy_window_pending_state_ = kNoDestroyPending; | |
145 } else { | |
146 destroy_window_pending_state_ = kSurfaceDestroyedRecently; | |
147 } | |
148 } | |
149 | |
150 void SurfaceFactoryCast::SendRelinquishResponse() { | |
151 if (!relinquish_display_callback_.is_null()) { | |
152 base::ResetAndReturn(&relinquish_display_callback_).Run(); | |
153 } | |
154 } | |
155 | |
156 const int32* SurfaceFactoryCast::GetEGLSurfaceProperties( | |
157 const int32* desired_list) { | |
158 return egl_platform_->GetEGLSurfaceProperties(desired_list); | |
159 } | |
160 | |
161 bool SurfaceFactoryCast::LoadEGLGLES2Bindings( | |
162 AddGLLibraryCallback add_gl_library, | |
163 SetGLGetProcAddressProcCallback set_gl_get_proc_address) { | |
164 if (state_ != kInitialized) { | |
165 InitializeHardware(); | |
166 if (state_ != kInitialized) { | |
167 return false; | |
168 } | |
169 } | |
170 | |
171 return egl_platform_->LoadEGLGLES2Bindings(add_gl_library, | |
172 set_gl_get_proc_address); | |
173 } | |
174 | |
175 } // namespace ozone | |
176 } // namespace chromecast | |
OLD | NEW |