OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gl/gl_surface.h" | 5 #include "ui/gl/gl_surface.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
| 12 #include "base/memory/scoped_vector.h" |
12 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
13 #include "base/threading/worker_pool.h" | 14 #include "base/threading/worker_pool.h" |
14 #include "ui/gfx/native_widget_types.h" | 15 #include "ui/gfx/native_widget_types.h" |
15 #include "ui/gl/gl_context.h" | 16 #include "ui/gl/gl_context.h" |
16 #include "ui/gl/gl_image.h" | 17 #include "ui/gl/gl_image.h" |
17 #include "ui/gl/gl_image_linux_dma_buffer.h" | 18 #include "ui/gl/gl_image_linux_dma_buffer.h" |
18 #include "ui/gl/gl_implementation.h" | 19 #include "ui/gl/gl_implementation.h" |
19 #include "ui/gl/gl_surface_egl.h" | 20 #include "ui/gl/gl_surface_egl.h" |
20 #include "ui/gl/gl_surface_osmesa.h" | 21 #include "ui/gl/gl_surface_osmesa.h" |
21 #include "ui/gl/gl_surface_stub.h" | 22 #include "ui/gl/gl_surface_stub.h" |
22 #include "ui/gl/scoped_binders.h" | 23 #include "ui/gl/scoped_binders.h" |
23 #include "ui/gl/scoped_make_current.h" | 24 #include "ui/gl/scoped_make_current.h" |
24 #include "ui/ozone/public/native_pixmap.h" | 25 #include "ui/ozone/public/native_pixmap.h" |
| 26 #include "ui/ozone/public/ozone_platform.h" |
25 #include "ui/ozone/public/surface_factory_ozone.h" | 27 #include "ui/ozone/public/surface_factory_ozone.h" |
26 #include "ui/ozone/public/surface_ozone_egl.h" | 28 #include "ui/ozone/public/surface_ozone_egl.h" |
27 | 29 |
28 namespace gfx { | 30 namespace gfx { |
29 | 31 |
30 namespace { | 32 namespace { |
31 | 33 |
32 void WaitForFence(EGLDisplay display, EGLSyncKHR fence) { | 34 void WaitForFence(EGLDisplay display, EGLSyncKHR fence) { |
33 eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, | 35 eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, |
34 EGL_FOREVER_KHR); | 36 EGL_FOREVER_KHR); |
35 } | 37 } |
36 | 38 |
37 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow | 39 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow |
38 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL { | 40 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL { |
39 public: | 41 public: |
40 GLSurfaceOzoneEGL(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, | 42 GLSurfaceOzoneEGL(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
41 AcceleratedWidget widget) | 43 AcceleratedWidget widget, |
42 : NativeViewGLSurfaceEGL(ozone_surface->GetNativeWindow()), | 44 const gfx::SurfaceConfiguration& requested_configuration); |
43 ozone_surface_(ozone_surface.Pass()), | |
44 widget_(widget) {} | |
45 | 45 |
46 bool Initialize() override { | 46 // GLSurface: |
47 return Initialize(ozone_surface_->CreateVSyncProvider()); | 47 bool Initialize() override; |
48 } | 48 bool Resize(const gfx::Size& size) override; |
49 bool Resize(const gfx::Size& size) override { | 49 gfx::SwapResult SwapBuffers() override; |
50 if (!ozone_surface_->ResizeNativeWindow(size)) { | |
51 if (!ReinitializeNativeSurface() || | |
52 !ozone_surface_->ResizeNativeWindow(size)) | |
53 return false; | |
54 } | |
55 | |
56 return NativeViewGLSurfaceEGL::Resize(size); | |
57 } | |
58 bool SwapBuffers() override { | |
59 if (!NativeViewGLSurfaceEGL::SwapBuffers()) | |
60 return false; | |
61 | |
62 return ozone_surface_->OnSwapBuffers(); | |
63 } | |
64 bool ScheduleOverlayPlane(int z_order, | 50 bool ScheduleOverlayPlane(int z_order, |
65 OverlayTransform transform, | 51 OverlayTransform transform, |
66 GLImage* image, | 52 GLImage* image, |
67 const Rect& bounds_rect, | 53 const Rect& bounds_rect, |
68 const RectF& crop_rect) override { | 54 const RectF& crop_rect) override; |
69 return image->ScheduleOverlayPlane( | |
70 widget_, z_order, transform, bounds_rect, crop_rect); | |
71 } | |
72 | 55 |
73 private: | 56 private: |
74 using NativeViewGLSurfaceEGL::Initialize; | 57 using NativeViewGLSurfaceEGL::Initialize; |
75 | 58 |
76 ~GLSurfaceOzoneEGL() override { | 59 ~GLSurfaceOzoneEGL() override; |
77 Destroy(); // EGL surface must be destroyed before SurfaceOzone | |
78 } | |
79 | 60 |
80 bool ReinitializeNativeSurface() { | 61 bool ReinitializeNativeSurface(); |
81 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current; | |
82 GLContext* current_context = GLContext::GetCurrent(); | |
83 bool was_current = | |
84 current_context && current_context->IsCurrent(this); | |
85 if (was_current) { | |
86 scoped_make_current.reset( | |
87 new ui::ScopedMakeCurrent(current_context, this)); | |
88 } | |
89 | |
90 Destroy(); | |
91 ozone_surface_ = | |
92 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget( | |
93 widget_).Pass(); | |
94 if (!ozone_surface_) { | |
95 LOG(ERROR) << "Failed to create native surface."; | |
96 return false; | |
97 } | |
98 | |
99 window_ = ozone_surface_->GetNativeWindow(); | |
100 if (!Initialize()) { | |
101 LOG(ERROR) << "Failed to initialize."; | |
102 return false; | |
103 } | |
104 | |
105 return true; | |
106 } | |
107 | 62 |
108 // The native surface. Deleting this is allowed to free the EGLNativeWindow. | 63 // The native surface. Deleting this is allowed to free the EGLNativeWindow. |
109 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; | 64 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; |
110 AcceleratedWidget widget_; | 65 AcceleratedWidget widget_; |
111 | 66 |
112 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneEGL); | 67 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneEGL); |
113 }; | 68 }; |
114 | 69 |
| 70 GLSurfaceOzoneEGL::GLSurfaceOzoneEGL( |
| 71 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
| 72 AcceleratedWidget widget, |
| 73 const gfx::SurfaceConfiguration& requested_configuration) |
| 74 : NativeViewGLSurfaceEGL(ozone_surface->GetNativeWindow(), |
| 75 requested_configuration), |
| 76 ozone_surface_(ozone_surface.Pass()), |
| 77 widget_(widget) { |
| 78 } |
| 79 |
| 80 bool GLSurfaceOzoneEGL::Initialize() { |
| 81 return Initialize(ozone_surface_->CreateVSyncProvider()); |
| 82 } |
| 83 |
| 84 bool GLSurfaceOzoneEGL::Resize(const gfx::Size& size) { |
| 85 if (!ozone_surface_->ResizeNativeWindow(size)) { |
| 86 if (!ReinitializeNativeSurface() || |
| 87 !ozone_surface_->ResizeNativeWindow(size)) |
| 88 return false; |
| 89 } |
| 90 |
| 91 return NativeViewGLSurfaceEGL::Resize(size); |
| 92 } |
| 93 |
| 94 gfx::SwapResult GLSurfaceOzoneEGL::SwapBuffers() { |
| 95 gfx::SwapResult result = NativeViewGLSurfaceEGL::SwapBuffers(); |
| 96 if (result != gfx::SwapResult::SWAP_ACK) |
| 97 return result; |
| 98 |
| 99 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK |
| 100 : gfx::SwapResult::SWAP_FAILED; |
| 101 } |
| 102 |
| 103 bool GLSurfaceOzoneEGL::ScheduleOverlayPlane(int z_order, |
| 104 OverlayTransform transform, |
| 105 GLImage* image, |
| 106 const Rect& bounds_rect, |
| 107 const RectF& crop_rect) { |
| 108 return image->ScheduleOverlayPlane(widget_, z_order, transform, bounds_rect, |
| 109 crop_rect); |
| 110 } |
| 111 |
| 112 GLSurfaceOzoneEGL::~GLSurfaceOzoneEGL() { |
| 113 Destroy(); // EGL surface must be destroyed before SurfaceOzone |
| 114 } |
| 115 |
| 116 bool GLSurfaceOzoneEGL::ReinitializeNativeSurface() { |
| 117 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current; |
| 118 GLContext* current_context = GLContext::GetCurrent(); |
| 119 bool was_current = current_context && current_context->IsCurrent(this); |
| 120 if (was_current) { |
| 121 scoped_make_current.reset(new ui::ScopedMakeCurrent(current_context, this)); |
| 122 } |
| 123 |
| 124 Destroy(); |
| 125 ozone_surface_ = ui::OzonePlatform::GetInstance() |
| 126 ->GetSurfaceFactoryOzone() |
| 127 ->CreateEGLSurfaceForWidget(widget_) |
| 128 .Pass(); |
| 129 if (!ozone_surface_) { |
| 130 LOG(ERROR) << "Failed to create native surface."; |
| 131 return false; |
| 132 } |
| 133 |
| 134 window_ = ozone_surface_->GetNativeWindow(); |
| 135 if (!Initialize()) { |
| 136 LOG(ERROR) << "Failed to initialize."; |
| 137 return false; |
| 138 } |
| 139 |
| 140 return true; |
| 141 } |
| 142 |
115 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { | 143 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { |
116 public: | 144 public: |
117 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, | 145 GLSurfaceOzoneSurfaceless( |
118 AcceleratedWidget widget) | 146 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
119 : SurfacelessEGL(gfx::Size()), | 147 AcceleratedWidget widget, |
120 ozone_surface_(ozone_surface.Pass()), | 148 const gfx::SurfaceConfiguration& requested_configuration); |
121 widget_(widget), | 149 |
122 has_implicit_external_sync_( | 150 // GLSurface: |
123 HasEGLExtension("EGL_ARM_implicit_external_sync")), | 151 bool Initialize() override; |
124 last_swap_buffers_result_(true), | 152 bool Resize(const gfx::Size& size) override; |
125 weak_factory_(this) {} | 153 gfx::SwapResult SwapBuffers() override; |
126 | |
127 bool Initialize() override { | |
128 if (!SurfacelessEGL::Initialize()) | |
129 return false; | |
130 vsync_provider_ = ozone_surface_->CreateVSyncProvider(); | |
131 if (!vsync_provider_) | |
132 return false; | |
133 return true; | |
134 } | |
135 bool Resize(const gfx::Size& size) override { | |
136 if (!ozone_surface_->ResizeNativeWindow(size)) | |
137 return false; | |
138 | |
139 return SurfacelessEGL::Resize(size); | |
140 } | |
141 bool SwapBuffers() override { | |
142 glFlush(); | |
143 // TODO: the following should be replaced by a per surface flush as it gets | |
144 // implemented in GL drivers. | |
145 if (has_implicit_external_sync_) { | |
146 EGLSyncKHR fence = InsertFence(); | |
147 if (!fence) | |
148 return false; | |
149 | |
150 EGLDisplay display = GetDisplay(); | |
151 WaitForFence(display, fence); | |
152 eglDestroySyncKHR(display, fence); | |
153 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { | |
154 glFinish(); | |
155 } | |
156 | |
157 return ozone_surface_->OnSwapBuffers(); | |
158 } | |
159 bool ScheduleOverlayPlane(int z_order, | 154 bool ScheduleOverlayPlane(int z_order, |
160 OverlayTransform transform, | 155 OverlayTransform transform, |
161 GLImage* image, | 156 GLImage* image, |
162 const Rect& bounds_rect, | 157 const Rect& bounds_rect, |
163 const RectF& crop_rect) override { | 158 const RectF& crop_rect) override; |
164 return image->ScheduleOverlayPlane( | 159 bool IsOffscreen() override; |
165 widget_, z_order, transform, bounds_rect, crop_rect); | 160 VSyncProvider* GetVSyncProvider() override; |
166 } | 161 bool SupportsPostSubBuffer() override; |
167 bool IsOffscreen() override { return false; } | 162 gfx::SwapResult PostSubBuffer(int x, int y, int width, int height) override; |
168 VSyncProvider* GetVSyncProvider() override { return vsync_provider_.get(); } | 163 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override; |
169 bool SupportsPostSubBuffer() override { return true; } | |
170 bool PostSubBuffer(int x, int y, int width, int height) override { | |
171 // The actual sub buffer handling is handled at higher layers. | |
172 SwapBuffers(); | |
173 return true; | |
174 } | |
175 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { | |
176 glFlush(); | |
177 // TODO: the following should be replaced by a per surface flush as it gets | |
178 // implemented in GL drivers. | |
179 if (has_implicit_external_sync_) { | |
180 // If last swap failed, don't try to schedule new ones. | |
181 if (!last_swap_buffers_result_) { | |
182 last_swap_buffers_result_ = true; | |
183 return false; | |
184 } | |
185 | |
186 EGLSyncKHR fence = InsertFence(); | |
187 if (!fence) | |
188 return false; | |
189 | |
190 base::Closure fence_wait_task = | |
191 base::Bind(&WaitForFence, GetDisplay(), fence); | |
192 | |
193 base::Closure fence_retired_callback = | |
194 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired, | |
195 weak_factory_.GetWeakPtr(), fence, callback); | |
196 | |
197 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task, | |
198 fence_retired_callback, false); | |
199 return true; | |
200 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { | |
201 glFinish(); | |
202 } | |
203 return ozone_surface_->OnSwapBuffersAsync(callback); | |
204 } | |
205 bool PostSubBufferAsync(int x, | 164 bool PostSubBufferAsync(int x, |
206 int y, | 165 int y, |
207 int width, | 166 int width, |
208 int height, | 167 int height, |
209 const SwapCompletionCallback& callback) override { | 168 const SwapCompletionCallback& callback) override; |
210 return SwapBuffersAsync(callback); | |
211 } | |
212 | 169 |
213 protected: | 170 protected: |
214 ~GLSurfaceOzoneSurfaceless() override { | 171 struct Overlay { |
215 Destroy(); // EGL surface must be destroyed before SurfaceOzone | 172 Overlay(int z_order, |
216 } | 173 OverlayTransform transform, |
217 | 174 GLImage* image, |
218 EGLSyncKHR InsertFence() { | 175 const Rect& bounds_rect, |
219 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, | 176 const RectF& crop_rect); |
220 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, | 177 |
221 EGL_NONE}; | 178 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget) const; |
222 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); | 179 |
223 } | 180 int z_order; |
224 | 181 OverlayTransform transform; |
225 void FenceRetired(EGLSyncKHR fence, const SwapCompletionCallback& callback) { | 182 scoped_refptr<GLImage> image; |
226 eglDestroySyncKHR(GetDisplay(), fence); | 183 Rect bounds_rect; |
227 last_swap_buffers_result_ = ozone_surface_->OnSwapBuffersAsync(callback); | 184 RectF crop_rect; |
228 } | 185 }; |
| 186 |
| 187 struct PendingFrame { |
| 188 PendingFrame(); |
| 189 |
| 190 bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget); |
| 191 |
| 192 bool ready; |
| 193 std::vector<Overlay> overlays; |
| 194 SwapCompletionCallback callback; |
| 195 }; |
| 196 |
| 197 ~GLSurfaceOzoneSurfaceless() override; |
| 198 |
| 199 void SubmitFrame(); |
| 200 |
| 201 EGLSyncKHR InsertFence(); |
| 202 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame); |
| 203 |
| 204 void SwapCompleted(const SwapCompletionCallback& callback, |
| 205 gfx::SwapResult result); |
229 | 206 |
230 // The native surface. Deleting this is allowed to free the EGLNativeWindow. | 207 // The native surface. Deleting this is allowed to free the EGLNativeWindow. |
231 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; | 208 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; |
232 AcceleratedWidget widget_; | 209 AcceleratedWidget widget_; |
233 scoped_ptr<VSyncProvider> vsync_provider_; | 210 scoped_ptr<VSyncProvider> vsync_provider_; |
| 211 ScopedVector<PendingFrame> unsubmitted_frames_; |
234 bool has_implicit_external_sync_; | 212 bool has_implicit_external_sync_; |
235 bool last_swap_buffers_result_; | 213 bool last_swap_buffers_result_; |
| 214 bool swap_buffers_pending_; |
236 | 215 |
237 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_; | 216 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_; |
238 | 217 |
239 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); | 218 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); |
240 }; | 219 }; |
241 | 220 |
| 221 GLSurfaceOzoneSurfaceless::Overlay::Overlay(int z_order, |
| 222 OverlayTransform transform, |
| 223 GLImage* image, |
| 224 const Rect& bounds_rect, |
| 225 const RectF& crop_rect) |
| 226 : z_order(z_order), |
| 227 transform(transform), |
| 228 image(image), |
| 229 bounds_rect(bounds_rect), |
| 230 crop_rect(crop_rect) { |
| 231 } |
| 232 |
| 233 bool GLSurfaceOzoneSurfaceless::Overlay::ScheduleOverlayPlane( |
| 234 gfx::AcceleratedWidget widget) const { |
| 235 return image->ScheduleOverlayPlane(widget, z_order, transform, bounds_rect, |
| 236 crop_rect); |
| 237 } |
| 238 |
| 239 GLSurfaceOzoneSurfaceless::PendingFrame::PendingFrame() : ready(false) { |
| 240 } |
| 241 |
| 242 bool GLSurfaceOzoneSurfaceless::PendingFrame::ScheduleOverlayPlanes( |
| 243 gfx::AcceleratedWidget widget) { |
| 244 for (const auto& overlay : overlays) |
| 245 if (!overlay.ScheduleOverlayPlane(widget)) |
| 246 return false; |
| 247 return true; |
| 248 } |
| 249 |
| 250 GLSurfaceOzoneSurfaceless::GLSurfaceOzoneSurfaceless( |
| 251 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
| 252 AcceleratedWidget widget, |
| 253 const gfx::SurfaceConfiguration& requested_configuration) |
| 254 : SurfacelessEGL(gfx::Size(), requested_configuration), |
| 255 ozone_surface_(ozone_surface.Pass()), |
| 256 widget_(widget), |
| 257 has_implicit_external_sync_( |
| 258 HasEGLExtension("EGL_ARM_implicit_external_sync")), |
| 259 last_swap_buffers_result_(true), |
| 260 swap_buffers_pending_(false), |
| 261 weak_factory_(this) { |
| 262 unsubmitted_frames_.push_back(new PendingFrame()); |
| 263 } |
| 264 |
| 265 bool GLSurfaceOzoneSurfaceless::Initialize() { |
| 266 if (!SurfacelessEGL::Initialize()) |
| 267 return false; |
| 268 vsync_provider_ = ozone_surface_->CreateVSyncProvider(); |
| 269 if (!vsync_provider_) |
| 270 return false; |
| 271 return true; |
| 272 } |
| 273 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size& size) { |
| 274 if (!ozone_surface_->ResizeNativeWindow(size)) |
| 275 return false; |
| 276 |
| 277 return SurfacelessEGL::Resize(size); |
| 278 } |
| 279 gfx::SwapResult GLSurfaceOzoneSurfaceless::SwapBuffers() { |
| 280 glFlush(); |
| 281 // TODO: the following should be replaced by a per surface flush as it gets |
| 282 // implemented in GL drivers. |
| 283 if (has_implicit_external_sync_) { |
| 284 EGLSyncKHR fence = InsertFence(); |
| 285 if (!fence) |
| 286 return SwapResult::SWAP_FAILED; |
| 287 |
| 288 EGLDisplay display = GetDisplay(); |
| 289 WaitForFence(display, fence); |
| 290 eglDestroySyncKHR(display, fence); |
| 291 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { |
| 292 glFinish(); |
| 293 } |
| 294 |
| 295 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_); |
| 296 unsubmitted_frames_.back()->overlays.clear(); |
| 297 |
| 298 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK |
| 299 : gfx::SwapResult::SWAP_FAILED; |
| 300 } |
| 301 bool GLSurfaceOzoneSurfaceless::ScheduleOverlayPlane(int z_order, |
| 302 OverlayTransform transform, |
| 303 GLImage* image, |
| 304 const Rect& bounds_rect, |
| 305 const RectF& crop_rect) { |
| 306 unsubmitted_frames_.back()->overlays.push_back( |
| 307 Overlay(z_order, transform, image, bounds_rect, crop_rect)); |
| 308 return true; |
| 309 } |
| 310 bool GLSurfaceOzoneSurfaceless::IsOffscreen() { |
| 311 return false; |
| 312 } |
| 313 VSyncProvider* GLSurfaceOzoneSurfaceless::GetVSyncProvider() { |
| 314 return vsync_provider_.get(); |
| 315 } |
| 316 bool GLSurfaceOzoneSurfaceless::SupportsPostSubBuffer() { |
| 317 return true; |
| 318 } |
| 319 gfx::SwapResult GLSurfaceOzoneSurfaceless::PostSubBuffer(int x, |
| 320 int y, |
| 321 int width, |
| 322 int height) { |
| 323 // The actual sub buffer handling is handled at higher layers. |
| 324 SwapBuffers(); |
| 325 return gfx::SwapResult::SWAP_ACK; |
| 326 } |
| 327 bool GLSurfaceOzoneSurfaceless::SwapBuffersAsync( |
| 328 const SwapCompletionCallback& callback) { |
| 329 // If last swap failed, don't try to schedule new ones. |
| 330 if (!last_swap_buffers_result_) |
| 331 return false; |
| 332 |
| 333 glFlush(); |
| 334 |
| 335 SwapCompletionCallback surface_swap_callback = |
| 336 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted, |
| 337 weak_factory_.GetWeakPtr(), callback); |
| 338 |
| 339 PendingFrame* frame = unsubmitted_frames_.back(); |
| 340 frame->callback = surface_swap_callback; |
| 341 unsubmitted_frames_.push_back(new PendingFrame()); |
| 342 |
| 343 // TODO: the following should be replaced by a per surface flush as it gets |
| 344 // implemented in GL drivers. |
| 345 if (has_implicit_external_sync_) { |
| 346 EGLSyncKHR fence = InsertFence(); |
| 347 if (!fence) |
| 348 return false; |
| 349 |
| 350 base::Closure fence_wait_task = |
| 351 base::Bind(&WaitForFence, GetDisplay(), fence); |
| 352 |
| 353 base::Closure fence_retired_callback = |
| 354 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired, |
| 355 weak_factory_.GetWeakPtr(), fence, frame); |
| 356 |
| 357 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task, |
| 358 fence_retired_callback, false); |
| 359 return true; |
| 360 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { |
| 361 glFinish(); |
| 362 } |
| 363 |
| 364 frame->ready = true; |
| 365 SubmitFrame(); |
| 366 return last_swap_buffers_result_; |
| 367 } |
| 368 bool GLSurfaceOzoneSurfaceless::PostSubBufferAsync( |
| 369 int x, |
| 370 int y, |
| 371 int width, |
| 372 int height, |
| 373 const SwapCompletionCallback& callback) { |
| 374 return SwapBuffersAsync(callback); |
| 375 } |
| 376 |
| 377 GLSurfaceOzoneSurfaceless::~GLSurfaceOzoneSurfaceless() { |
| 378 Destroy(); // EGL surface must be destroyed before SurfaceOzone |
| 379 } |
| 380 |
| 381 void GLSurfaceOzoneSurfaceless::SubmitFrame() { |
| 382 DCHECK(!unsubmitted_frames_.empty()); |
| 383 |
| 384 if (unsubmitted_frames_.front()->ready && !swap_buffers_pending_) { |
| 385 scoped_ptr<PendingFrame> frame(unsubmitted_frames_.front()); |
| 386 unsubmitted_frames_.weak_erase(unsubmitted_frames_.begin()); |
| 387 swap_buffers_pending_ = true; |
| 388 |
| 389 last_swap_buffers_result_ = |
| 390 frame->ScheduleOverlayPlanes(widget_) && |
| 391 ozone_surface_->OnSwapBuffersAsync(frame->callback); |
| 392 } |
| 393 } |
| 394 |
| 395 EGLSyncKHR GLSurfaceOzoneSurfaceless::InsertFence() { |
| 396 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, |
| 397 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, |
| 398 EGL_NONE}; |
| 399 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); |
| 400 } |
| 401 |
| 402 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence, |
| 403 PendingFrame* frame) { |
| 404 eglDestroySyncKHR(GetDisplay(), fence); |
| 405 frame->ready = true; |
| 406 SubmitFrame(); |
| 407 } |
| 408 |
| 409 void GLSurfaceOzoneSurfaceless::SwapCompleted( |
| 410 const SwapCompletionCallback& callback, |
| 411 gfx::SwapResult result) { |
| 412 callback.Run(result); |
| 413 swap_buffers_pending_ = false; |
| 414 |
| 415 SubmitFrame(); |
| 416 } |
| 417 |
242 // This provides surface-like semantics implemented through surfaceless. | 418 // This provides surface-like semantics implemented through surfaceless. |
243 // A framebuffer is bound automatically. | 419 // A framebuffer is bound automatically. |
244 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl | 420 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl |
245 : public GLSurfaceOzoneSurfaceless { | 421 : public GLSurfaceOzoneSurfaceless { |
246 public: | 422 public: |
247 GLSurfaceOzoneSurfacelessSurfaceImpl( | 423 GLSurfaceOzoneSurfacelessSurfaceImpl( |
248 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, | 424 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
249 AcceleratedWidget widget) | 425 AcceleratedWidget widget, |
250 : GLSurfaceOzoneSurfaceless(ozone_surface.Pass(), widget), | 426 const gfx::SurfaceConfiguration& requested_configuration); |
251 fbo_(0), | 427 |
252 current_surface_(0) { | 428 // GLSurface: |
253 for (auto& texture : textures_) | 429 unsigned int GetBackingFrameBufferObject() override; |
254 texture = 0; | 430 bool OnMakeCurrent(GLContext* context) override; |
255 } | 431 bool Resize(const gfx::Size& size) override; |
256 | 432 bool SupportsPostSubBuffer() override; |
257 unsigned int GetBackingFrameBufferObject() override { return fbo_; } | 433 gfx::SwapResult SwapBuffers() override; |
258 | 434 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override; |
259 bool OnMakeCurrent(GLContext* context) override { | 435 void Destroy() override; |
260 if (!fbo_) { | |
261 glGenFramebuffersEXT(1, &fbo_); | |
262 if (!fbo_) | |
263 return false; | |
264 glGenTextures(arraysize(textures_), textures_); | |
265 if (!CreatePixmaps()) | |
266 return false; | |
267 } | |
268 BindFramebuffer(); | |
269 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_); | |
270 return SurfacelessEGL::OnMakeCurrent(context); | |
271 } | |
272 | |
273 bool Resize(const gfx::Size& size) override { | |
274 if (size == GetSize()) | |
275 return true; | |
276 return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps(); | |
277 } | |
278 | |
279 bool SupportsPostSubBuffer() override { return false; } | |
280 | |
281 bool SwapBuffers() override { | |
282 if (!images_[current_surface_]->ScheduleOverlayPlane( | |
283 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, | |
284 gfx::Rect(GetSize()), gfx::RectF(1, 1))) | |
285 return false; | |
286 if (!GLSurfaceOzoneSurfaceless::SwapBuffers()) | |
287 return false; | |
288 current_surface_ ^= 1; | |
289 BindFramebuffer(); | |
290 return true; | |
291 } | |
292 | |
293 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { | |
294 if (!images_[current_surface_]->ScheduleOverlayPlane( | |
295 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, | |
296 gfx::Rect(GetSize()), gfx::RectF(1, 1))) | |
297 return false; | |
298 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback)) | |
299 return false; | |
300 current_surface_ ^= 1; | |
301 BindFramebuffer(); | |
302 return true; | |
303 } | |
304 | |
305 void Destroy() override { | |
306 GLContext* current_context = GLContext::GetCurrent(); | |
307 DCHECK(current_context && current_context->IsCurrent(this)); | |
308 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | |
309 if (fbo_) { | |
310 glDeleteTextures(arraysize(textures_), textures_); | |
311 for (auto& texture : textures_) | |
312 texture = 0; | |
313 glDeleteFramebuffersEXT(1, &fbo_); | |
314 fbo_ = 0; | |
315 } | |
316 for (auto image : images_) { | |
317 if (image) | |
318 image->Destroy(true); | |
319 } | |
320 } | |
321 | 436 |
322 private: | 437 private: |
323 class SurfaceImage : public GLImageLinuxDMABuffer { | 438 class SurfaceImage : public GLImageLinuxDMABuffer { |
324 public: | 439 public: |
325 SurfaceImage(const gfx::Size& size, unsigned internalformat) | 440 SurfaceImage(const gfx::Size& size, unsigned internalformat); |
326 : GLImageLinuxDMABuffer(size, internalformat) {} | |
327 | 441 |
328 bool Initialize(scoped_refptr<ui::NativePixmap> pixmap, | 442 bool Initialize(scoped_refptr<ui::NativePixmap> pixmap, |
329 gfx::GpuMemoryBuffer::Format format) { | 443 gfx::GpuMemoryBuffer::Format format); |
330 base::FileDescriptor handle(pixmap->GetDmaBufFd(), false); | |
331 if (!GLImageLinuxDMABuffer::Initialize(handle, format, | |
332 pixmap->GetDmaBufPitch())) | |
333 return false; | |
334 pixmap_ = pixmap; | |
335 return true; | |
336 } | |
337 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | 444 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
338 int z_order, | 445 int z_order, |
339 gfx::OverlayTransform transform, | 446 gfx::OverlayTransform transform, |
340 const gfx::Rect& bounds_rect, | 447 const gfx::Rect& bounds_rect, |
341 const gfx::RectF& crop_rect) override { | 448 const gfx::RectF& crop_rect) override; |
342 return ui::SurfaceFactoryOzone::GetInstance()->ScheduleOverlayPlane( | |
343 widget, z_order, transform, pixmap_, bounds_rect, crop_rect); | |
344 } | |
345 | 449 |
346 private: | 450 private: |
347 ~SurfaceImage() override {} | 451 ~SurfaceImage() override; |
348 | 452 |
349 scoped_refptr<ui::NativePixmap> pixmap_; | 453 scoped_refptr<ui::NativePixmap> pixmap_; |
350 }; | 454 }; |
351 | 455 |
352 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override { | 456 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override; |
353 DCHECK(!fbo_); | 457 |
354 for (size_t i = 0; i < arraysize(textures_); i++) | 458 void BindFramebuffer(); |
355 DCHECK(!textures_[i]) << "texture " << i << " not released"; | 459 bool CreatePixmaps(); |
356 } | |
357 | |
358 void BindFramebuffer() { | |
359 ScopedFrameBufferBinder fb(fbo_); | |
360 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
361 GL_TEXTURE_2D, textures_[current_surface_], 0); | |
362 } | |
363 | |
364 bool CreatePixmaps() { | |
365 if (!fbo_) | |
366 return true; | |
367 for (size_t i = 0; i < arraysize(textures_); i++) { | |
368 scoped_refptr<ui::NativePixmap> pixmap = | |
369 ui::SurfaceFactoryOzone::GetInstance()->CreateNativePixmap( | |
370 widget_, GetSize(), ui::SurfaceFactoryOzone::RGBA_8888, | |
371 ui::SurfaceFactoryOzone::SCANOUT); | |
372 if (!pixmap) | |
373 return false; | |
374 scoped_refptr<SurfaceImage> image = new SurfaceImage(GetSize(), GL_RGBA); | |
375 if (!image->Initialize(pixmap, gfx::GpuMemoryBuffer::Format::BGRA_8888)) | |
376 return false; | |
377 images_[i] = image; | |
378 // Bind image to texture. | |
379 ScopedTextureBinder binder(GL_TEXTURE_2D, textures_[i]); | |
380 if (!images_[i]->BindTexImage(GL_TEXTURE_2D)) | |
381 return false; | |
382 } | |
383 return true; | |
384 } | |
385 | 460 |
386 GLuint fbo_; | 461 GLuint fbo_; |
387 GLuint textures_[2]; | 462 GLuint textures_[2]; |
388 scoped_refptr<GLImage> images_[2]; | 463 scoped_refptr<GLImage> images_[2]; |
389 int current_surface_; | 464 int current_surface_; |
390 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl); | 465 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl); |
391 }; | 466 }; |
392 | 467 |
| 468 GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::SurfaceImage( |
| 469 const gfx::Size& size, |
| 470 unsigned internalformat) |
| 471 : GLImageLinuxDMABuffer(size, internalformat) { |
| 472 } |
| 473 |
| 474 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::Initialize( |
| 475 scoped_refptr<ui::NativePixmap> pixmap, |
| 476 gfx::GpuMemoryBuffer::Format format) { |
| 477 base::FileDescriptor handle(pixmap->GetDmaBufFd(), false); |
| 478 if (!GLImageLinuxDMABuffer::Initialize(handle, format, |
| 479 pixmap->GetDmaBufPitch())) |
| 480 return false; |
| 481 pixmap_ = pixmap; |
| 482 return true; |
| 483 } |
| 484 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::ScheduleOverlayPlane( |
| 485 gfx::AcceleratedWidget widget, |
| 486 int z_order, |
| 487 gfx::OverlayTransform transform, |
| 488 const gfx::Rect& bounds_rect, |
| 489 const gfx::RectF& crop_rect) { |
| 490 return pixmap_->ScheduleOverlayPlane(widget, z_order, transform, bounds_rect, |
| 491 crop_rect); |
| 492 } |
| 493 |
| 494 GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::~SurfaceImage() { |
| 495 } |
| 496 |
| 497 GLSurfaceOzoneSurfacelessSurfaceImpl::GLSurfaceOzoneSurfacelessSurfaceImpl( |
| 498 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
| 499 AcceleratedWidget widget, |
| 500 const gfx::SurfaceConfiguration& requested_configuration) |
| 501 : GLSurfaceOzoneSurfaceless( |
| 502 ozone_surface.Pass(), widget, requested_configuration), |
| 503 fbo_(0), |
| 504 current_surface_(0) { |
| 505 for (auto& texture : textures_) |
| 506 texture = 0; |
| 507 } |
| 508 |
| 509 unsigned int |
| 510 GLSurfaceOzoneSurfacelessSurfaceImpl::GetBackingFrameBufferObject() { |
| 511 return fbo_; |
| 512 } |
| 513 |
| 514 bool GLSurfaceOzoneSurfacelessSurfaceImpl::OnMakeCurrent(GLContext* context) { |
| 515 if (!fbo_) { |
| 516 glGenFramebuffersEXT(1, &fbo_); |
| 517 if (!fbo_) |
| 518 return false; |
| 519 glGenTextures(arraysize(textures_), textures_); |
| 520 if (!CreatePixmaps()) |
| 521 return false; |
| 522 } |
| 523 BindFramebuffer(); |
| 524 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_); |
| 525 return SurfacelessEGL::OnMakeCurrent(context); |
| 526 } |
| 527 |
| 528 bool GLSurfaceOzoneSurfacelessSurfaceImpl::Resize(const gfx::Size& size) { |
| 529 if (size == GetSize()) |
| 530 return true; |
| 531 return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps(); |
| 532 } |
| 533 |
| 534 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SupportsPostSubBuffer() { |
| 535 return false; |
| 536 } |
| 537 |
| 538 gfx::SwapResult GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffers() { |
| 539 if (!images_[current_surface_]->ScheduleOverlayPlane( |
| 540 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, |
| 541 gfx::Rect(GetSize()), gfx::RectF(1, 1))) |
| 542 return gfx::SwapResult::SWAP_FAILED; |
| 543 gfx::SwapResult result = GLSurfaceOzoneSurfaceless::SwapBuffers(); |
| 544 if (result != gfx::SwapResult::SWAP_ACK) |
| 545 return result; |
| 546 current_surface_ ^= 1; |
| 547 BindFramebuffer(); |
| 548 return gfx::SwapResult::SWAP_ACK; |
| 549 } |
| 550 |
| 551 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffersAsync( |
| 552 const SwapCompletionCallback& callback) { |
| 553 if (!images_[current_surface_]->ScheduleOverlayPlane( |
| 554 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, |
| 555 gfx::Rect(GetSize()), gfx::RectF(1, 1))) |
| 556 return false; |
| 557 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback)) |
| 558 return false; |
| 559 current_surface_ ^= 1; |
| 560 BindFramebuffer(); |
| 561 return true; |
| 562 } |
| 563 |
| 564 void GLSurfaceOzoneSurfacelessSurfaceImpl::Destroy() { |
| 565 GLContext* current_context = GLContext::GetCurrent(); |
| 566 DCHECK(current_context && current_context->IsCurrent(this)); |
| 567 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); |
| 568 if (fbo_) { |
| 569 glDeleteTextures(arraysize(textures_), textures_); |
| 570 for (auto& texture : textures_) |
| 571 texture = 0; |
| 572 glDeleteFramebuffersEXT(1, &fbo_); |
| 573 fbo_ = 0; |
| 574 } |
| 575 for (auto image : images_) { |
| 576 if (image) |
| 577 image->Destroy(true); |
| 578 } |
| 579 } |
| 580 |
| 581 GLSurfaceOzoneSurfacelessSurfaceImpl::~GLSurfaceOzoneSurfacelessSurfaceImpl() { |
| 582 DCHECK(!fbo_); |
| 583 for (size_t i = 0; i < arraysize(textures_); i++) |
| 584 DCHECK(!textures_[i]) << "texture " << i << " not released"; |
| 585 } |
| 586 |
| 587 void GLSurfaceOzoneSurfacelessSurfaceImpl::BindFramebuffer() { |
| 588 ScopedFrameBufferBinder fb(fbo_); |
| 589 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, |
| 590 textures_[current_surface_], 0); |
| 591 } |
| 592 |
| 593 bool GLSurfaceOzoneSurfacelessSurfaceImpl::CreatePixmaps() { |
| 594 if (!fbo_) |
| 595 return true; |
| 596 for (size_t i = 0; i < arraysize(textures_); i++) { |
| 597 scoped_refptr<ui::NativePixmap> pixmap = |
| 598 ui::OzonePlatform::GetInstance() |
| 599 ->GetSurfaceFactoryOzone() |
| 600 ->CreateNativePixmap(widget_, GetSize(), |
| 601 ui::SurfaceFactoryOzone::BGRA_8888, |
| 602 ui::SurfaceFactoryOzone::SCANOUT); |
| 603 if (!pixmap) |
| 604 return false; |
| 605 scoped_refptr<SurfaceImage> image = |
| 606 new SurfaceImage(GetSize(), GL_BGRA_EXT); |
| 607 if (!image->Initialize(pixmap, gfx::GpuMemoryBuffer::Format::BGRA_8888)) |
| 608 return false; |
| 609 images_[i] = image; |
| 610 // Bind image to texture. |
| 611 ScopedTextureBinder binder(GL_TEXTURE_2D, textures_[i]); |
| 612 if (!images_[i]->BindTexImage(GL_TEXTURE_2D)) |
| 613 return false; |
| 614 } |
| 615 return true; |
| 616 } |
| 617 |
393 } // namespace | 618 } // namespace |
394 | 619 |
395 // static | 620 // static |
396 bool GLSurface::InitializeOneOffInternal() { | 621 bool GLSurface::InitializeOneOffInternal() { |
397 switch (GetGLImplementation()) { | 622 switch (GetGLImplementation()) { |
398 case kGLImplementationEGLGLES2: | 623 case kGLImplementationEGLGLES2: |
399 if (!GLSurfaceEGL::InitializeOneOff()) { | 624 if (!GLSurfaceEGL::InitializeOneOff()) { |
400 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed."; | 625 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed."; |
401 return false; | 626 return false; |
402 } | 627 } |
403 | 628 |
404 return true; | 629 return true; |
405 case kGLImplementationOSMesaGL: | 630 case kGLImplementationOSMesaGL: |
406 case kGLImplementationMockGL: | 631 case kGLImplementationMockGL: |
407 return true; | 632 return true; |
408 default: | 633 default: |
409 return false; | 634 return false; |
410 } | 635 } |
411 } | 636 } |
412 | 637 |
413 // static | 638 // static |
414 scoped_refptr<GLSurface> GLSurface::CreateSurfacelessViewGLSurface( | 639 scoped_refptr<GLSurface> GLSurface::CreateSurfacelessViewGLSurface( |
415 gfx::AcceleratedWidget window) { | 640 gfx::AcceleratedWidget window, |
| 641 const gfx::SurfaceConfiguration& requested_configuration) { |
416 if (GetGLImplementation() == kGLImplementationEGLGLES2 && | 642 if (GetGLImplementation() == kGLImplementationEGLGLES2 && |
417 window != kNullAcceleratedWidget && | 643 window != kNullAcceleratedWidget && |
418 GLSurfaceEGL::IsEGLSurfacelessContextSupported() && | 644 GLSurfaceEGL::IsEGLSurfacelessContextSupported() && |
419 ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) { | 645 ui::OzonePlatform::GetInstance() |
| 646 ->GetSurfaceFactoryOzone() |
| 647 ->CanShowPrimaryPlaneAsOverlay()) { |
420 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = | 648 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = |
421 ui::SurfaceFactoryOzone::GetInstance() | 649 ui::OzonePlatform::GetInstance() |
| 650 ->GetSurfaceFactoryOzone() |
422 ->CreateSurfacelessEGLSurfaceForWidget(window); | 651 ->CreateSurfacelessEGLSurfaceForWidget(window); |
423 if (!surface_ozone) | 652 if (!surface_ozone) |
424 return nullptr; | 653 return nullptr; |
425 scoped_refptr<GLSurface> surface; | 654 scoped_refptr<GLSurface> surface; |
426 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window); | 655 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), |
| 656 window, |
| 657 requested_configuration); |
427 if (surface->Initialize()) | 658 if (surface->Initialize()) |
428 return surface; | 659 return surface; |
429 } | 660 } |
430 | 661 |
431 return nullptr; | 662 return nullptr; |
432 } | 663 } |
433 | 664 |
434 // static | 665 // static |
435 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( | 666 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( |
436 gfx::AcceleratedWidget window) { | 667 gfx::AcceleratedWidget window, |
| 668 const gfx::SurfaceConfiguration& requested_configuration) { |
437 if (GetGLImplementation() == kGLImplementationOSMesaGL) { | 669 if (GetGLImplementation() == kGLImplementationOSMesaGL) { |
438 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless()); | 670 scoped_refptr<GLSurface> surface( |
| 671 new GLSurfaceOSMesaHeadless(requested_configuration)); |
439 if (!surface->Initialize()) | 672 if (!surface->Initialize()) |
440 return NULL; | 673 return NULL; |
441 return surface; | 674 return surface; |
442 } | 675 } |
443 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2); | 676 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2); |
444 if (window != kNullAcceleratedWidget) { | 677 if (window != kNullAcceleratedWidget) { |
445 scoped_refptr<GLSurface> surface; | 678 scoped_refptr<GLSurface> surface; |
446 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && | 679 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && |
447 ui::SurfaceFactoryOzone::GetInstance() | 680 ui::OzonePlatform::GetInstance() |
| 681 ->GetSurfaceFactoryOzone() |
448 ->CanShowPrimaryPlaneAsOverlay()) { | 682 ->CanShowPrimaryPlaneAsOverlay()) { |
449 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = | 683 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = |
450 ui::SurfaceFactoryOzone::GetInstance() | 684 ui::OzonePlatform::GetInstance() |
| 685 ->GetSurfaceFactoryOzone() |
451 ->CreateSurfacelessEGLSurfaceForWidget(window); | 686 ->CreateSurfacelessEGLSurfaceForWidget(window); |
452 if (!surface_ozone) | 687 if (!surface_ozone) |
453 return NULL; | 688 return NULL; |
454 surface = new GLSurfaceOzoneSurfacelessSurfaceImpl(surface_ozone.Pass(), | 689 surface = new GLSurfaceOzoneSurfacelessSurfaceImpl( |
455 window); | 690 surface_ozone.Pass(), window, requested_configuration); |
456 } else { | 691 } else { |
457 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = | 692 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = |
458 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget( | 693 ui::OzonePlatform::GetInstance() |
459 window); | 694 ->GetSurfaceFactoryOzone() |
| 695 ->CreateEGLSurfaceForWidget(window); |
460 if (!surface_ozone) | 696 if (!surface_ozone) |
461 return NULL; | 697 return NULL; |
462 | 698 |
463 surface = new GLSurfaceOzoneEGL(surface_ozone.Pass(), window); | 699 surface = new GLSurfaceOzoneEGL( |
| 700 surface_ozone.Pass(), window, requested_configuration); |
464 } | 701 } |
465 if (!surface->Initialize()) | 702 if (!surface->Initialize()) |
466 return NULL; | 703 return NULL; |
467 return surface; | 704 return surface; |
468 } else { | 705 } else { |
469 scoped_refptr<GLSurface> surface = new GLSurfaceStub(); | 706 scoped_refptr<GLSurface> surface = new GLSurfaceStub( |
| 707 requested_configuration); |
470 if (surface->Initialize()) | 708 if (surface->Initialize()) |
471 return surface; | 709 return surface; |
472 } | 710 } |
473 return NULL; | 711 return NULL; |
474 } | 712 } |
475 | 713 |
476 // static | 714 // static |
477 scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface( | 715 scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface( |
478 const gfx::Size& size) { | 716 const gfx::Size& size, |
| 717 const gfx::SurfaceConfiguration& requested_configuration) { |
479 switch (GetGLImplementation()) { | 718 switch (GetGLImplementation()) { |
480 case kGLImplementationOSMesaGL: { | 719 case kGLImplementationOSMesaGL: { |
481 scoped_refptr<GLSurface> surface( | 720 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesa( |
482 new GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA, size)); | 721 OSMesaSurfaceFormatBGRA, size, requested_configuration)); |
483 if (!surface->Initialize()) | 722 if (!surface->Initialize()) |
484 return NULL; | 723 return NULL; |
485 | 724 |
486 return surface; | 725 return surface; |
487 } | 726 } |
488 case kGLImplementationEGLGLES2: { | 727 case kGLImplementationEGLGLES2: { |
489 scoped_refptr<GLSurface> surface; | 728 scoped_refptr<GLSurface> surface; |
490 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && | 729 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && |
491 (size.width() == 0 && size.height() == 0)) { | 730 (size.width() == 0 && size.height() == 0)) { |
492 surface = new SurfacelessEGL(size); | 731 surface = new SurfacelessEGL(size, requested_configuration); |
493 } else | 732 } else |
494 surface = new PbufferGLSurfaceEGL(size); | 733 surface = new PbufferGLSurfaceEGL(size, requested_configuration); |
495 | 734 |
496 if (!surface->Initialize()) | 735 if (!surface->Initialize()) |
497 return NULL; | 736 return NULL; |
498 return surface; | 737 return surface; |
499 } | 738 } |
| 739 case kGLImplementationMockGL: |
| 740 return new GLSurfaceStub(requested_configuration); |
500 default: | 741 default: |
501 NOTREACHED(); | 742 NOTREACHED(); |
502 return NULL; | 743 return NULL; |
503 } | 744 } |
504 } | 745 } |
505 | 746 |
506 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { | 747 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { |
507 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); | 748 return ui::OzonePlatform::GetInstance() |
| 749 ->GetSurfaceFactoryOzone() |
| 750 ->GetNativeDisplay(); |
508 } | 751 } |
509 | 752 |
510 } // namespace gfx | 753 } // namespace gfx |
OLD | NEW |