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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 } | 49 } |
50 bool Resize(const gfx::Size& size) override { | 50 bool Resize(const gfx::Size& size) override { |
51 if (!ozone_surface_->ResizeNativeWindow(size)) { | 51 if (!ozone_surface_->ResizeNativeWindow(size)) { |
52 if (!ReinitializeNativeSurface() || | 52 if (!ReinitializeNativeSurface() || |
53 !ozone_surface_->ResizeNativeWindow(size)) | 53 !ozone_surface_->ResizeNativeWindow(size)) |
54 return false; | 54 return false; |
55 } | 55 } |
56 | 56 |
57 return NativeViewGLSurfaceEGL::Resize(size); | 57 return NativeViewGLSurfaceEGL::Resize(size); |
58 } | 58 } |
59 bool SwapBuffers() override { | 59 gfx::SwapResult SwapBuffers() override { |
60 if (!NativeViewGLSurfaceEGL::SwapBuffers()) | 60 if (NativeViewGLSurfaceEGL::SwapBuffers() == gfx::SwapResult::SWAP_FAILED) |
61 return false; | 61 return gfx::SwapResult::SWAP_FAILED; |
62 | 62 |
63 return ozone_surface_->OnSwapBuffers(); | 63 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK |
| 64 : gfx::SwapResult::SWAP_FAILED; |
64 } | 65 } |
65 bool ScheduleOverlayPlane(int z_order, | 66 bool ScheduleOverlayPlane(int z_order, |
66 OverlayTransform transform, | 67 OverlayTransform transform, |
67 GLImage* image, | 68 GLImage* image, |
68 const Rect& bounds_rect, | 69 const Rect& bounds_rect, |
69 const RectF& crop_rect) override { | 70 const RectF& crop_rect) override { |
70 return image->ScheduleOverlayPlane( | 71 return image->ScheduleOverlayPlane( |
71 widget_, z_order, transform, bounds_rect, crop_rect); | 72 widget_, z_order, transform, bounds_rect, crop_rect); |
72 } | 73 } |
73 | 74 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 if (!vsync_provider_) | 136 if (!vsync_provider_) |
136 return false; | 137 return false; |
137 return true; | 138 return true; |
138 } | 139 } |
139 bool Resize(const gfx::Size& size) override { | 140 bool Resize(const gfx::Size& size) override { |
140 if (!ozone_surface_->ResizeNativeWindow(size)) | 141 if (!ozone_surface_->ResizeNativeWindow(size)) |
141 return false; | 142 return false; |
142 | 143 |
143 return SurfacelessEGL::Resize(size); | 144 return SurfacelessEGL::Resize(size); |
144 } | 145 } |
145 bool SwapBuffers() override { | 146 gfx::SwapResult SwapBuffers() override { |
146 glFlush(); | 147 glFlush(); |
147 // TODO: the following should be replaced by a per surface flush as it gets | 148 // TODO: the following should be replaced by a per surface flush as it gets |
148 // implemented in GL drivers. | 149 // implemented in GL drivers. |
149 if (has_implicit_external_sync_) { | 150 if (has_implicit_external_sync_) { |
150 EGLSyncKHR fence = InsertFence(); | 151 EGLSyncKHR fence = InsertFence(); |
151 if (!fence) | 152 if (!fence) |
152 return false; | 153 return gfx::SwapResult::SWAP_FAILED; |
153 | 154 |
154 EGLDisplay display = GetDisplay(); | 155 EGLDisplay display = GetDisplay(); |
155 WaitForFence(display, fence); | 156 WaitForFence(display, fence); |
156 eglDestroySyncKHR(display, fence); | 157 eglDestroySyncKHR(display, fence); |
157 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { | 158 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) { |
158 glFinish(); | 159 glFinish(); |
159 } | 160 } |
160 | 161 |
161 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_); | 162 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_); |
162 unsubmitted_frames_.back()->overlays.clear(); | 163 unsubmitted_frames_.back()->overlays.clear(); |
163 | 164 |
164 return ozone_surface_->OnSwapBuffers(); | 165 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK |
| 166 : gfx::SwapResult::SWAP_FAILED; |
165 } | 167 } |
166 bool ScheduleOverlayPlane(int z_order, | 168 bool ScheduleOverlayPlane(int z_order, |
167 OverlayTransform transform, | 169 OverlayTransform transform, |
168 GLImage* image, | 170 GLImage* image, |
169 const Rect& bounds_rect, | 171 const Rect& bounds_rect, |
170 const RectF& crop_rect) override { | 172 const RectF& crop_rect) override { |
171 unsubmitted_frames_.back()->overlays.push_back(PendingFrame::Overlay( | 173 unsubmitted_frames_.back()->overlays.push_back(PendingFrame::Overlay( |
172 z_order, transform, image, bounds_rect, crop_rect)); | 174 z_order, transform, image, bounds_rect, crop_rect)); |
173 return true; | 175 return true; |
174 } | 176 } |
175 bool IsOffscreen() override { return false; } | 177 bool IsOffscreen() override { return false; } |
176 VSyncProvider* GetVSyncProvider() override { return vsync_provider_.get(); } | 178 VSyncProvider* GetVSyncProvider() override { return vsync_provider_.get(); } |
177 bool SupportsPostSubBuffer() override { return true; } | 179 bool SupportsPostSubBuffer() override { return true; } |
178 bool PostSubBuffer(int x, int y, int width, int height) override { | 180 gfx::SwapResult PostSubBuffer(int x, int y, int width, int height) override { |
179 // The actual sub buffer handling is handled at higher layers. | 181 // The actual sub buffer handling is handled at higher layers. |
180 SwapBuffers(); | 182 return SwapBuffers(); |
181 return true; | |
182 } | 183 } |
183 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { | 184 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { |
184 // If last swap failed, don't try to schedule new ones. | 185 // If last swap failed, don't try to schedule new ones. |
185 if (!last_swap_buffers_result_) | 186 if (!last_swap_buffers_result_) |
186 return false; | 187 return false; |
187 | 188 |
188 glFlush(); | 189 glFlush(); |
189 | 190 |
190 base::Closure surface_swap_callback = | 191 SwapCompletionCallback surface_swap_callback = |
191 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted, | 192 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted, |
192 weak_factory_.GetWeakPtr(), callback); | 193 weak_factory_.GetWeakPtr(), callback); |
193 | 194 |
194 PendingFrame* frame = unsubmitted_frames_.back(); | 195 PendingFrame* frame = unsubmitted_frames_.back(); |
195 frame->callback = surface_swap_callback; | 196 frame->callback = surface_swap_callback; |
196 unsubmitted_frames_.push_back(new PendingFrame()); | 197 unsubmitted_frames_.push_back(new PendingFrame()); |
197 | 198 |
198 // TODO: the following should be replaced by a per surface flush as it gets | 199 // TODO: the following should be replaced by a per surface flush as it gets |
199 // implemented in GL drivers. | 200 // implemented in GL drivers. |
200 if (has_implicit_external_sync_) { | 201 if (has_implicit_external_sync_) { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 EGL_NONE}; | 292 EGL_NONE}; |
292 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); | 293 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); |
293 } | 294 } |
294 | 295 |
295 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame) { | 296 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame) { |
296 eglDestroySyncKHR(GetDisplay(), fence); | 297 eglDestroySyncKHR(GetDisplay(), fence); |
297 frame->ready = true; | 298 frame->ready = true; |
298 SubmitFrame(); | 299 SubmitFrame(); |
299 } | 300 } |
300 | 301 |
301 void SwapCompleted(const SwapCompletionCallback& callback) { | 302 void SwapCompleted(const SwapCompletionCallback& callback, |
302 callback.Run(); | 303 gfx::SwapResult result) { |
| 304 callback.Run(result); |
303 swap_buffers_pending_ = false; | 305 swap_buffers_pending_ = false; |
304 | 306 |
305 SubmitFrame(); | 307 SubmitFrame(); |
306 } | 308 } |
307 | 309 |
308 // The native surface. Deleting this is allowed to free the EGLNativeWindow. | 310 // The native surface. Deleting this is allowed to free the EGLNativeWindow. |
309 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; | 311 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; |
310 AcceleratedWidget widget_; | 312 AcceleratedWidget widget_; |
311 scoped_ptr<VSyncProvider> vsync_provider_; | 313 scoped_ptr<VSyncProvider> vsync_provider_; |
312 ScopedVector<PendingFrame> unsubmitted_frames_; | 314 ScopedVector<PendingFrame> unsubmitted_frames_; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 } | 353 } |
352 | 354 |
353 bool Resize(const gfx::Size& size) override { | 355 bool Resize(const gfx::Size& size) override { |
354 if (size == GetSize()) | 356 if (size == GetSize()) |
355 return true; | 357 return true; |
356 return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps(); | 358 return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps(); |
357 } | 359 } |
358 | 360 |
359 bool SupportsPostSubBuffer() override { return false; } | 361 bool SupportsPostSubBuffer() override { return false; } |
360 | 362 |
361 bool SwapBuffers() override { | 363 gfx::SwapResult SwapBuffers() override { |
362 if (!images_[current_surface_]->ScheduleOverlayPlane( | 364 if (!images_[current_surface_]->ScheduleOverlayPlane( |
363 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, | 365 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, |
364 gfx::Rect(GetSize()), gfx::RectF(1, 1))) | 366 gfx::Rect(GetSize()), gfx::RectF(1, 1))) |
365 return false; | 367 return gfx::SwapResult::SWAP_FAILED; |
366 if (!GLSurfaceOzoneSurfaceless::SwapBuffers()) | 368 if (GLSurfaceOzoneSurfaceless::SwapBuffers() == |
367 return false; | 369 gfx::SwapResult::SWAP_FAILED) |
| 370 return gfx::SwapResult::SWAP_FAILED; |
368 current_surface_ ^= 1; | 371 current_surface_ ^= 1; |
369 BindFramebuffer(); | 372 BindFramebuffer(); |
370 return true; | 373 return gfx::SwapResult::SWAP_ACK; |
371 } | 374 } |
372 | 375 |
373 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { | 376 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { |
374 if (!images_[current_surface_]->ScheduleOverlayPlane( | 377 if (!images_[current_surface_]->ScheduleOverlayPlane( |
375 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, | 378 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE, |
376 gfx::Rect(GetSize()), gfx::RectF(1, 1))) | 379 gfx::Rect(GetSize()), gfx::RectF(1, 1))) |
377 return false; | 380 return false; |
378 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback)) | 381 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback)) |
379 return false; | 382 return false; |
380 current_surface_ ^= 1; | 383 current_surface_ ^= 1; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 NOTREACHED(); | 584 NOTREACHED(); |
582 return NULL; | 585 return NULL; |
583 } | 586 } |
584 } | 587 } |
585 | 588 |
586 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { | 589 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { |
587 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); | 590 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); |
588 } | 591 } |
589 | 592 |
590 } // namespace gfx | 593 } // namespace gfx |
OLD | NEW |