Index: ui/gl/gl_surface_ozone.cc |
diff --git a/ui/gl/gl_surface_ozone.cc b/ui/gl/gl_surface_ozone.cc |
index eecd06413876bdbceb9b0d7a50c26c5f40eb6559..cba706bda4e030b6daa599525846ebebbc847640 100644 |
--- a/ui/gl/gl_surface_ozone.cc |
+++ b/ui/gl/gl_surface_ozone.cc |
@@ -105,7 +105,9 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { |
AcceleratedWidget widget) |
: SurfacelessEGL(gfx::Size()), |
ozone_surface_(ozone_surface.Pass()), |
- widget_(widget) {} |
+ widget_(widget), |
+ has_implicit_external_sync_( |
+ HasEGLExtension("EGL_ARM_implicit_external_sync")) {} |
bool Initialize() override { |
if (!SurfacelessEGL::Initialize()) |
@@ -122,8 +124,8 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { |
return SurfacelessEGL::Resize(size); |
} |
bool SwapBuffers() override { |
- // TODO: this should be replaced by a fence when supported by the driver. |
- glFlush(); |
+ if (!Flush()) |
+ return false; |
return ozone_surface_->OnSwapBuffers(); |
} |
bool ScheduleOverlayPlane(int z_order, |
@@ -143,8 +145,8 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { |
return true; |
} |
bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { |
- // TODO: this should be replaced by a fence when supported by the driver. |
- glFlush(); |
+ if (!Flush()) |
+ return false; |
return ozone_surface_->OnSwapBuffersAsync(callback); |
} |
bool PostSubBufferAsync(int x, |
@@ -160,11 +162,35 @@ class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { |
Destroy(); // EGL surface must be destroyed before SurfaceOzone |
} |
+ bool Flush() { |
+ glFlush(); |
+ // TODO: the following should be replaced by a per surface flush as it gets |
+ // implemented in GL drivers. |
+ if (has_implicit_external_sync_) { |
+ const EGLint attrib_list[] = { |
+ EGL_SYNC_CONDITION_KHR, |
+ EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, |
+ EGL_NONE}; |
+ EGLSyncKHR fence = |
+ eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); |
+ if (fence) { |
+ // TODO(dbehr): piman@ suggests we could improve here by moving |
+ // following wait to right before drmModePageFlip crbug.com/456417. |
+ eglClientWaitSyncKHR(GetDisplay(), fence, |
+ EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR); |
+ eglDestroySyncKHR(GetDisplay(), fence); |
+ } else { |
+ return false; |
+ } |
+ } |
+ return true; |
+ } |
+ |
// The native surface. Deleting this is allowed to free the EGLNativeWindow. |
scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; |
AcceleratedWidget widget_; |
scoped_ptr<VSyncProvider> vsync_provider_; |
- |
+ bool has_implicit_external_sync_; |
DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); |
}; |