Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / ozone / platform / cast / surface_factory_cast.cc
blobe0a728feafa535287c4d0f91ce2110829b186dc2
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;
16 namespace ui {
17 namespace {
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);
32 } // namespace
34 SurfaceFactoryCast::SurfaceFactoryCast(scoped_ptr<CastEglPlatform> egl_platform)
35 : state_(kUninitialized),
36 destroy_window_pending_state_(kNoDestroyPending),
37 display_type_(0),
38 have_display_type_(false),
39 window_(0),
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) {
51 return;
53 CHECK_EQ(state_, kUninitialized);
55 if (egl_platform_->InitializeHardware()) {
56 state_ = kInitialized;
57 } else {
58 ShutdownHardware();
59 state_ = kFailed;
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) {
78 InitializeHardware();
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;
90 if (!window_) {
91 chromecast::Size create_size = FromGfxSize(display_size_);
92 window_ = egl_platform_->CreateWindow(display_type_, create_size);
93 if (!window_) {
94 DestroyDisplayTypeAndWindow();
95 state_ = kFailed;
96 LOG(FATAL) << "Create EGLNativeWindowType(" << display_size_.ToString()
97 << ") failed.";
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;
114 return true;
117 void SurfaceFactoryCast::DestroyWindow() {
118 if (window_) {
119 egl_platform_->DestroyWindow(window_);
120 window_ = 0;
124 void SurfaceFactoryCast::DestroyDisplayTypeAndWindow() {
125 DestroyWindow();
126 if (have_display_type_) {
127 egl_platform_->DestroyDisplayType(display_type_);
128 display_type_ = 0;
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;
153 break;
154 case kSurfaceExists:
155 destroy_window_pending_state_ = kWindowDestroyPending;
156 break;
157 case kWindowDestroyPending:
158 break;
159 default:
160 NOTREACHED();
164 void SurfaceFactoryCast::ChildDestroyed() {
165 if (destroy_window_pending_state_ == kWindowDestroyPending) {
166 DestroyDisplayTypeAndWindow();
167 SendRelinquishResponse();
168 destroy_window_pending_state_ = kNoDestroyPending;
169 } else {
170 if (egl_platform_->MultipleSurfaceUnsupported()) {
171 DestroyWindow();
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,
190 gfx::Size size,
191 gfx::BufferFormat format,
192 gfx::BufferUsage usage) {
193 class CastPixmap : public NativePixmap {
194 public:
195 CastPixmap() {}
197 void* GetEGLClientBuffer() override {
198 // TODO(halliwell): try to implement this through CastEglPlatform.
199 return nullptr;
201 int GetDmaBufFd() override { return 0; }
202 int GetDmaBufPitch() override { return 0; }
203 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
204 int plane_z_order,
205 gfx::OverlayTransform plane_transform,
206 const gfx::Rect& display_bounds,
207 const gfx::RectF& crop_rect) override {
208 return true;
210 void SetScalingCallback(const ScalingCallback& scaling_callback) override {}
211 scoped_refptr<NativePixmap> GetScaledPixmap(gfx::Size new_size) override {
212 return nullptr;
214 gfx::NativePixmapHandle ExportHandle() override {
215 return gfx::NativePixmapHandle();
218 private:
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) {
232 return false;
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) {
240 return false;
243 set_gl_get_proc_address.Run(gl_proc);
244 add_gl_library.Run(lib_egl);
245 add_gl_library.Run(lib_gles2);
246 return true;
249 } // namespace ui