| Index: ui/gl/gl_surface_ozone.cc
|
| diff --git a/ui/gl/gl_surface_ozone.cc b/ui/gl/gl_surface_ozone.cc
|
| index ba7b02b036814056100705915fcd4bd4033603a5..7dac123f0d1527cb61fdbaf8986ef12fa4f3ce48 100644
|
| --- a/ui/gl/gl_surface_ozone.cc
|
| +++ b/ui/gl/gl_surface_ozone.cc
|
| @@ -123,6 +123,7 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
|
| has_implicit_external_sync_(
|
| HasEGLExtension("EGL_ARM_implicit_external_sync")),
|
| last_swap_buffers_result_(true),
|
| + swap_buffers_pending_(false),
|
| weak_factory_(this) {
|
| unsubmitted_frames_.push_back(new PendingFrame());
|
| }
|
| @@ -180,16 +181,23 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
|
| return true;
|
| }
|
| bool SwapBuffersAsync(const SwapCompletionCallback& callback) override {
|
| + // If last swap failed, don't try to schedule new ones.
|
| + if (!last_swap_buffers_result_)
|
| + return false;
|
| +
|
| glFlush();
|
| +
|
| + base::Closure surface_swap_callback =
|
| + base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted,
|
| + weak_factory_.GetWeakPtr(), callback);
|
| +
|
| + PendingFrame* frame = unsubmitted_frames_.back();
|
| + frame->callback = surface_swap_callback;
|
| + unsubmitted_frames_.push_back(new PendingFrame());
|
| +
|
| // TODO: the following should be replaced by a per surface flush as it gets
|
| // implemented in GL drivers.
|
| if (has_implicit_external_sync_) {
|
| - // If last swap failed, don't try to schedule new ones.
|
| - if (!last_swap_buffers_result_) {
|
| - last_swap_buffers_result_ = true;
|
| - return false;
|
| - }
|
| -
|
| EGLSyncKHR fence = InsertFence();
|
| if (!fence)
|
| return false;
|
| @@ -197,22 +205,20 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
|
| base::Closure fence_wait_task =
|
| base::Bind(&WaitForFence, GetDisplay(), fence);
|
|
|
| - PendingFrame* frame = unsubmitted_frames_.back();
|
| - frame->callback = callback;
|
| base::Closure fence_retired_callback =
|
| base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired,
|
| weak_factory_.GetWeakPtr(), fence, frame);
|
|
|
| base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task,
|
| fence_retired_callback, false);
|
| - unsubmitted_frames_.push_back(new PendingFrame());
|
| return true;
|
| } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
|
| glFinish();
|
| }
|
| - unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_);
|
| - unsubmitted_frames_.back()->overlays.clear();
|
| - return ozone_surface_->OnSwapBuffersAsync(callback);
|
| +
|
| + frame->ready = true;
|
| + SubmitFrame();
|
| + return last_swap_buffers_result_;
|
| }
|
| bool PostSubBufferAsync(int x,
|
| int y,
|
| @@ -265,13 +271,17 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
|
| Destroy(); // EGL surface must be destroyed before SurfaceOzone
|
| }
|
|
|
| - void SubmitFrames() {
|
| - while (!unsubmitted_frames_.empty() && unsubmitted_frames_.front()->ready) {
|
| - PendingFrame* frame = unsubmitted_frames_.front();
|
| + void SubmitFrame() {
|
| + DCHECK(!unsubmitted_frames_.empty());
|
| +
|
| + if (unsubmitted_frames_.front()->ready && !swap_buffers_pending_) {
|
| + scoped_ptr<PendingFrame> frame(unsubmitted_frames_.front());
|
| + unsubmitted_frames_.weak_erase(unsubmitted_frames_.begin());
|
| + swap_buffers_pending_ = true;
|
| +
|
| last_swap_buffers_result_ =
|
| - last_swap_buffers_result_ && frame->ScheduleOverlayPlanes(widget_) &&
|
| + frame->ScheduleOverlayPlanes(widget_) &&
|
| ozone_surface_->OnSwapBuffersAsync(frame->callback);
|
| - unsubmitted_frames_.erase(unsubmitted_frames_.begin());
|
| }
|
| }
|
|
|
| @@ -285,7 +295,14 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
|
| void FenceRetired(EGLSyncKHR fence, PendingFrame* frame) {
|
| eglDestroySyncKHR(GetDisplay(), fence);
|
| frame->ready = true;
|
| - SubmitFrames();
|
| + SubmitFrame();
|
| + }
|
| +
|
| + void SwapCompleted(const SwapCompletionCallback& callback) {
|
| + callback.Run();
|
| + swap_buffers_pending_ = false;
|
| +
|
| + SubmitFrame();
|
| }
|
|
|
| // The native surface. Deleting this is allowed to free the EGLNativeWindow.
|
| @@ -295,6 +312,7 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
|
| ScopedVector<PendingFrame> unsubmitted_frames_;
|
| bool has_implicit_external_sync_;
|
| bool last_swap_buffers_result_;
|
| + bool swap_buffers_pending_;
|
|
|
| base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_;
|
|
|
|
|