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" |
(...skipping 26 matching lines...) Expand all Loading... |
37 | 37 |
38 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow | 38 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow |
39 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL { | 39 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL { |
40 public: | 40 public: |
41 GLSurfaceOzoneEGL(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, | 41 GLSurfaceOzoneEGL(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
42 AcceleratedWidget widget); | 42 AcceleratedWidget widget); |
43 | 43 |
44 // GLSurface: | 44 // GLSurface: |
45 bool Initialize() override; | 45 bool Initialize() override; |
46 bool Resize(const gfx::Size& size) override; | 46 bool Resize(const gfx::Size& size) override; |
47 bool SwapBuffers() override; | 47 gfx::SwapResult SwapBuffers() override; |
48 bool ScheduleOverlayPlane(int z_order, | 48 bool ScheduleOverlayPlane(int z_order, |
49 OverlayTransform transform, | 49 OverlayTransform transform, |
50 GLImage* image, | 50 GLImage* image, |
51 const Rect& bounds_rect, | 51 const Rect& bounds_rect, |
52 const RectF& crop_rect) override; | 52 const RectF& crop_rect) override; |
53 | 53 |
54 private: | 54 private: |
55 using NativeViewGLSurfaceEGL::Initialize; | 55 using NativeViewGLSurfaceEGL::Initialize; |
56 | 56 |
57 ~GLSurfaceOzoneEGL() override; | 57 ~GLSurfaceOzoneEGL() override; |
(...skipping 22 matching lines...) Expand all Loading... |
80 bool GLSurfaceOzoneEGL::Resize(const gfx::Size& size) { | 80 bool GLSurfaceOzoneEGL::Resize(const gfx::Size& size) { |
81 if (!ozone_surface_->ResizeNativeWindow(size)) { | 81 if (!ozone_surface_->ResizeNativeWindow(size)) { |
82 if (!ReinitializeNativeSurface() || | 82 if (!ReinitializeNativeSurface() || |
83 !ozone_surface_->ResizeNativeWindow(size)) | 83 !ozone_surface_->ResizeNativeWindow(size)) |
84 return false; | 84 return false; |
85 } | 85 } |
86 | 86 |
87 return NativeViewGLSurfaceEGL::Resize(size); | 87 return NativeViewGLSurfaceEGL::Resize(size); |
88 } | 88 } |
89 | 89 |
90 bool GLSurfaceOzoneEGL::SwapBuffers() { | 90 gfx::SwapResult GLSurfaceOzoneEGL::SwapBuffers() { |
91 if (!NativeViewGLSurfaceEGL::SwapBuffers()) | 91 gfx::SwapResult result = NativeViewGLSurfaceEGL::SwapBuffers(); |
92 return false; | 92 if (result != gfx::SwapResult::SWAP_ACK) |
| 93 return result; |
93 | 94 |
94 return ozone_surface_->OnSwapBuffers(); | 95 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK |
| 96 : gfx::SwapResult::SWAP_FAILED; |
95 } | 97 } |
96 | 98 |
97 bool GLSurfaceOzoneEGL::ScheduleOverlayPlane(int z_order, | 99 bool GLSurfaceOzoneEGL::ScheduleOverlayPlane(int z_order, |
98 OverlayTransform transform, | 100 OverlayTransform transform, |
99 GLImage* image, | 101 GLImage* image, |
100 const Rect& bounds_rect, | 102 const Rect& bounds_rect, |
101 const RectF& crop_rect) { | 103 const RectF& crop_rect) { |
102 return image->ScheduleOverlayPlane(widget_, z_order, transform, bounds_rect, | 104 return image->ScheduleOverlayPlane(widget_, z_order, transform, bounds_rect, |
103 crop_rect); | 105 crop_rect); |
104 } | 106 } |
(...skipping 29 matching lines...) Expand all Loading... |
134 } | 136 } |
135 | 137 |
136 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { | 138 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { |
137 public: | 139 public: |
138 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, | 140 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
139 AcceleratedWidget widget); | 141 AcceleratedWidget widget); |
140 | 142 |
141 // GLSurface: | 143 // GLSurface: |
142 bool Initialize() override; | 144 bool Initialize() override; |
143 bool Resize(const gfx::Size& size) override; | 145 bool Resize(const gfx::Size& size) override; |
144 bool SwapBuffers() override; | 146 gfx::SwapResult SwapBuffers() override; |
145 bool ScheduleOverlayPlane(int z_order, | 147 bool ScheduleOverlayPlane(int z_order, |
146 OverlayTransform transform, | 148 OverlayTransform transform, |
147 GLImage* image, | 149 GLImage* image, |
148 const Rect& bounds_rect, | 150 const Rect& bounds_rect, |
149 const RectF& crop_rect) override; | 151 const RectF& crop_rect) override; |
150 bool IsOffscreen() override; | 152 bool IsOffscreen() override; |
151 VSyncProvider* GetVSyncProvider() override; | 153 VSyncProvider* GetVSyncProvider() override; |
152 bool SupportsPostSubBuffer() override; | 154 bool SupportsPostSubBuffer() override; |
153 bool PostSubBuffer(int x, int y, int width, int height) override; | 155 gfx::SwapResult PostSubBuffer(int x, int y, int width, int height) override; |
154 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override; | 156 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override; |
155 bool PostSubBufferAsync(int x, | 157 bool PostSubBufferAsync(int x, |
156 int y, | 158 int y, |
157 int width, | 159 int width, |
158 int height, | 160 int height, |
159 const SwapCompletionCallback& callback) override; | 161 const SwapCompletionCallback& callback) override; |
160 | 162 |
161 protected: | 163 protected: |
162 struct Overlay { | 164 struct Overlay { |
163 Overlay(int z_order, | 165 Overlay(int z_order, |
(...skipping 21 matching lines...) Expand all Loading... |
185 SwapCompletionCallback callback; | 187 SwapCompletionCallback callback; |
186 }; | 188 }; |
187 | 189 |
188 ~GLSurfaceOzoneSurfaceless() override; | 190 ~GLSurfaceOzoneSurfaceless() override; |
189 | 191 |
190 void SubmitFrame(); | 192 void SubmitFrame(); |
191 | 193 |
192 EGLSyncKHR InsertFence(); | 194 EGLSyncKHR InsertFence(); |
193 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame); | 195 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame); |
194 | 196 |
195 void SwapCompleted(const SwapCompletionCallback& callback); | 197 void SwapCompleted(const SwapCompletionCallback& callback, |
| 198 gfx::SwapResult result); |
196 | 199 |
197 // The native surface. Deleting this is allowed to free the EGLNativeWindow. | 200 // The native surface. Deleting this is allowed to free the EGLNativeWindow. |
198 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; | 201 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; |
199 AcceleratedWidget widget_; | 202 AcceleratedWidget widget_; |
200 scoped_ptr<VSyncProvider> vsync_provider_; | 203 scoped_ptr<VSyncProvider> vsync_provider_; |
201 ScopedVector<PendingFrame> unsubmitted_frames_; | 204 ScopedVector<PendingFrame> unsubmitted_frames_; |
202 bool has_implicit_external_sync_; | 205 bool has_implicit_external_sync_; |
203 bool last_swap_buffers_result_; | 206 bool last_swap_buffers_result_; |
204 bool swap_buffers_pending_; | 207 bool swap_buffers_pending_; |
205 | 208 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 if (!vsync_provider_) | 261 if (!vsync_provider_) |
259 return false; | 262 return false; |
260 return true; | 263 return true; |
261 } | 264 } |
262 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size& size) { | 265 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size& size) { |
263 if (!ozone_surface_->ResizeNativeWindow(size)) | 266 if (!ozone_surface_->ResizeNativeWindow(size)) |
264 return false; | 267 return false; |
265 | 268 |
266 return SurfacelessEGL::Resize(size); | 269 return SurfacelessEGL::Resize(size); |
267 } | 270 } |
268 bool GLSurfaceOzoneSurfaceless::SwapBuffers() { | 271 gfx::SwapResult GLSurfaceOzoneSurfaceless::SwapBuffers() { |
269 glFlush(); | 272 glFlush(); |
270 // TODO: the following should be replaced by a per surface flush as it gets | 273 // TODO: the following should be replaced by a per surface flush as it gets |
271 // implemented in GL drivers. | 274 // implemented in GL drivers. |
272 if (has_implicit_external_sync_) { | 275 if (has_implicit_external_sync_) { |
273 EGLSyncKHR fence = InsertFence(); | 276 EGLSyncKHR fence = InsertFence(); |
274 if (!fence) | 277 if (!fence) |
275 return false; | 278 return SwapResult::SWAP_FAILED; |
276 | 279 |
277 EGLDisplay display = GetDisplay(); | 280 EGLDisplay display = GetDisplay(); |
278 WaitForFence(display, fence); | 281 WaitForFence(display, fence); |
279 eglDestroySyncKHR(display, fence); | 282 eglDestroySyncKHR(display, fence); |
280 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { | 283 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { |
281 glFinish(); | 284 glFinish(); |
282 } | 285 } |
283 | 286 |
284 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_); | 287 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_); |
285 unsubmitted_frames_.back()->overlays.clear(); | 288 unsubmitted_frames_.back()->overlays.clear(); |
286 | 289 |
287 return ozone_surface_->OnSwapBuffers(); | 290 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK |
| 291 : gfx::SwapResult::SWAP_FAILED; |
288 } | 292 } |
289 bool GLSurfaceOzoneSurfaceless::ScheduleOverlayPlane(int z_order, | 293 bool GLSurfaceOzoneSurfaceless::ScheduleOverlayPlane(int z_order, |
290 OverlayTransform transform, | 294 OverlayTransform transform, |
291 GLImage* image, | 295 GLImage* image, |
292 const Rect& bounds_rect, | 296 const Rect& bounds_rect, |
293 const RectF& crop_rect) { | 297 const RectF& crop_rect) { |
294 unsubmitted_frames_.back()->overlays.push_back( | 298 unsubmitted_frames_.back()->overlays.push_back( |
295 Overlay(z_order, transform, image, bounds_rect, crop_rect)); | 299 Overlay(z_order, transform, image, bounds_rect, crop_rect)); |
296 return true; | 300 return true; |
297 } | 301 } |
298 bool GLSurfaceOzoneSurfaceless::IsOffscreen() { | 302 bool GLSurfaceOzoneSurfaceless::IsOffscreen() { |
299 return false; | 303 return false; |
300 } | 304 } |
301 VSyncProvider* GLSurfaceOzoneSurfaceless::GetVSyncProvider() { | 305 VSyncProvider* GLSurfaceOzoneSurfaceless::GetVSyncProvider() { |
302 return vsync_provider_.get(); | 306 return vsync_provider_.get(); |
303 } | 307 } |
304 bool GLSurfaceOzoneSurfaceless::SupportsPostSubBuffer() { | 308 bool GLSurfaceOzoneSurfaceless::SupportsPostSubBuffer() { |
305 return true; | 309 return true; |
306 } | 310 } |
307 bool GLSurfaceOzoneSurfaceless::PostSubBuffer(int x, | 311 gfx::SwapResult GLSurfaceOzoneSurfaceless::PostSubBuffer(int x, |
308 int y, | 312 int y, |
309 int width, | 313 int width, |
310 int height) { | 314 int height) { |
311 // The actual sub buffer handling is handled at higher layers. | 315 // The actual sub buffer handling is handled at higher layers. |
312 SwapBuffers(); | 316 SwapBuffers(); |
313 return true; | 317 return gfx::SwapResult::SWAP_ACK; |
314 } | 318 } |
315 bool GLSurfaceOzoneSurfaceless::SwapBuffersAsync( | 319 bool GLSurfaceOzoneSurfaceless::SwapBuffersAsync( |
316 const SwapCompletionCallback& callback) { | 320 const SwapCompletionCallback& callback) { |
317 // If last swap failed, don't try to schedule new ones. | 321 // If last swap failed, don't try to schedule new ones. |
318 if (!last_swap_buffers_result_) | 322 if (!last_swap_buffers_result_) |
319 return false; | 323 return false; |
320 | 324 |
321 glFlush(); | 325 glFlush(); |
322 | 326 |
323 base::Closure surface_swap_callback = | 327 SwapCompletionCallback surface_swap_callback = |
324 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted, | 328 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted, |
325 weak_factory_.GetWeakPtr(), callback); | 329 weak_factory_.GetWeakPtr(), callback); |
326 | 330 |
327 PendingFrame* frame = unsubmitted_frames_.back(); | 331 PendingFrame* frame = unsubmitted_frames_.back(); |
328 frame->callback = surface_swap_callback; | 332 frame->callback = surface_swap_callback; |
329 unsubmitted_frames_.push_back(new PendingFrame()); | 333 unsubmitted_frames_.push_back(new PendingFrame()); |
330 | 334 |
331 // TODO: the following should be replaced by a per surface flush as it gets | 335 // TODO: the following should be replaced by a per surface flush as it gets |
332 // implemented in GL drivers. | 336 // implemented in GL drivers. |
333 if (has_implicit_external_sync_) { | 337 if (has_implicit_external_sync_) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 } | 392 } |
389 | 393 |
390 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence, | 394 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence, |
391 PendingFrame* frame) { | 395 PendingFrame* frame) { |
392 eglDestroySyncKHR(GetDisplay(), fence); | 396 eglDestroySyncKHR(GetDisplay(), fence); |
393 frame->ready = true; | 397 frame->ready = true; |
394 SubmitFrame(); | 398 SubmitFrame(); |
395 } | 399 } |
396 | 400 |
397 void GLSurfaceOzoneSurfaceless::SwapCompleted( | 401 void GLSurfaceOzoneSurfaceless::SwapCompleted( |
398 const SwapCompletionCallback& callback) { | 402 const SwapCompletionCallback& callback, |
399 callback.Run(); | 403 gfx::SwapResult result) { |
| 404 callback.Run(result); |
400 swap_buffers_pending_ = false; | 405 swap_buffers_pending_ = false; |
401 | 406 |
402 SubmitFrame(); | 407 SubmitFrame(); |
403 } | 408 } |
404 | 409 |
405 // This provides surface-like semantics implemented through surfaceless. | 410 // This provides surface-like semantics implemented through surfaceless. |
406 // A framebuffer is bound automatically. | 411 // A framebuffer is bound automatically. |
407 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl | 412 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl |
408 : public GLSurfaceOzoneSurfaceless { | 413 : public GLSurfaceOzoneSurfaceless { |
409 public: | 414 public: |
410 GLSurfaceOzoneSurfacelessSurfaceImpl( | 415 GLSurfaceOzoneSurfacelessSurfaceImpl( |
411 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, | 416 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
412 AcceleratedWidget widget); | 417 AcceleratedWidget widget); |
413 | 418 |
414 // GLSurface: | 419 // GLSurface: |
415 unsigned int GetBackingFrameBufferObject() override; | 420 unsigned int GetBackingFrameBufferObject() override; |
416 bool OnMakeCurrent(GLContext* context) override; | 421 bool OnMakeCurrent(GLContext* context) override; |
417 bool Resize(const gfx::Size& size) override; | 422 bool Resize(const gfx::Size& size) override; |
418 bool SupportsPostSubBuffer() override; | 423 bool SupportsPostSubBuffer() override; |
419 bool SwapBuffers() override; | 424 gfx::SwapResult SwapBuffers() override; |
420 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override; | 425 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override; |
421 void Destroy() override; | 426 void Destroy() override; |
422 | 427 |
423 private: | 428 private: |
424 class SurfaceImage : public GLImageLinuxDMABuffer { | 429 class SurfaceImage : public GLImageLinuxDMABuffer { |
425 public: | 430 public: |
426 SurfaceImage(const gfx::Size& size, unsigned internalformat); | 431 SurfaceImage(const gfx::Size& size, unsigned internalformat); |
427 | 432 |
428 bool Initialize(scoped_refptr<ui::NativePixmap> pixmap, | 433 bool Initialize(scoped_refptr<ui::NativePixmap> pixmap, |
429 gfx::GpuMemoryBuffer::Format format); | 434 gfx::GpuMemoryBuffer::Format format); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 bool GLSurfaceOzoneSurfacelessSurfaceImpl::Resize(const gfx::Size& size) { | 517 bool GLSurfaceOzoneSurfacelessSurfaceImpl::Resize(const gfx::Size& size) { |
513 if (size == GetSize()) | 518 if (size == GetSize()) |
514 return true; | 519 return true; |
515 return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps(); | 520 return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps(); |
516 } | 521 } |
517 | 522 |
518 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SupportsPostSubBuffer() { | 523 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SupportsPostSubBuffer() { |
519 return false; | 524 return false; |
520 } | 525 } |
521 | 526 |
522 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffers() { | 527 gfx::SwapResult GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffers() { |
523 if (!images_[current_surface_]->ScheduleOverlayPlane( | 528 if (!images_[current_surface_]->ScheduleOverlayPlane( |
524 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, | 529 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, |
525 gfx::Rect(GetSize()), gfx::RectF(1, 1))) | 530 gfx::Rect(GetSize()), gfx::RectF(1, 1))) |
526 return false; | 531 return gfx::SwapResult::SWAP_FAILED; |
527 if (!GLSurfaceOzoneSurfaceless::SwapBuffers()) | 532 gfx::SwapResult result = GLSurfaceOzoneSurfaceless::SwapBuffers(); |
528 return false; | 533 if (result != gfx::SwapResult::SWAP_ACK) |
| 534 return result; |
529 current_surface_ ^= 1; | 535 current_surface_ ^= 1; |
530 BindFramebuffer(); | 536 BindFramebuffer(); |
531 return true; | 537 return gfx::SwapResult::SWAP_ACK; |
532 } | 538 } |
533 | 539 |
534 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffersAsync( | 540 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffersAsync( |
535 const SwapCompletionCallback& callback) { | 541 const SwapCompletionCallback& callback) { |
536 if (!images_[current_surface_]->ScheduleOverlayPlane( | 542 if (!images_[current_surface_]->ScheduleOverlayPlane( |
537 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, | 543 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, |
538 gfx::Rect(GetSize()), gfx::RectF(1, 1))) | 544 gfx::Rect(GetSize()), gfx::RectF(1, 1))) |
539 return false; | 545 return false; |
540 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback)) | 546 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback)) |
541 return false; | 547 return false; |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 NOTREACHED(); | 715 NOTREACHED(); |
710 return NULL; | 716 return NULL; |
711 } | 717 } |
712 } | 718 } |
713 | 719 |
714 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { | 720 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { |
715 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); | 721 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); |
716 } | 722 } |
717 | 723 |
718 } // namespace gfx | 724 } // namespace gfx |
OLD | NEW |