Chromium Code Reviews| Index: ui/gl/gl_surface_egl.cc |
| diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc |
| index 3b81daf83285a476768cb724f7facde9bbca8950..d8783f40efc83a7eaaf392170a7d8d6c9b2550f7 100644 |
| --- a/ui/gl/gl_surface_egl.cc |
| +++ b/ui/gl/gl_surface_egl.cc |
| @@ -8,6 +8,7 @@ |
| #include <android/native_window_jni.h> |
| #endif |
| +#include "base/debug/trace_event.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/message_loop.h" |
| @@ -221,7 +222,8 @@ NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(bool software, |
| : window_(window), |
| surface_(NULL), |
| supports_post_sub_buffer_(false), |
| - config_(NULL) { |
| + config_(NULL), |
| + max_frame_latency_(0) { |
| software_ = software; |
| #if defined(OS_ANDROID) |
| if (window) |
| @@ -368,12 +370,33 @@ bool NativeViewGLSurfaceEGL::IsOffscreen() { |
| } |
| bool NativeViewGLSurfaceEGL::SwapBuffers() { |
| + // Create a fence for this frame. |
| + if (max_frame_latency_ > 0) { |
| + DCHECK_LE(frame_fences_.size(), max_frame_latency_ - 1); |
| + EGLSyncKHR fence = eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, NULL); |
|
Sami
2013/04/24 10:44:18
I remember one driver where sync object creation w
epennerAtGoogle
2013/04/24 19:33:38
Will do.
|
| + frame_fences_.push_back(fence); |
| + } |
| + |
| if (!eglSwapBuffers(GetDisplay(), surface_)) { |
| DVLOG(1) << "eglSwapBuffers failed with error " |
| << GetLastEGLErrorString(); |
| return false; |
| } |
| + // SwapBuffers above will block above according to the driver's |
| + // maximum latency. We now block again according to our own. |
| + DCHECK_LE(frame_fences_.size(), max_frame_latency_); |
| + if (frame_fences_.size() == max_frame_latency_) { |
| + TRACE_EVENT0("cc", "NativeViewGLSurfaceEGL eglClientWaitSyncKHR"); |
| + // We shouldn't need the flush flag, as SwapBuffers |
| + // always triggers a flush. |
| + EGLint flags = 0; //EGL_SYNC_FLUSH_COMMANDS_BIT_KHR; |
| + EGLTimeKHR time = EGL_FOREVER_KHR; |
| + EGLSyncKHR fence = frame_fences_.front(); |
| + eglClientWaitSyncKHR(GetDisplay(), fence, flags, time); |
|
Sami
2013/04/24 10:44:18
Call eglDestroySyncKHR after waiting here to avoid
epennerAtGoogle
2013/04/24 19:33:38
Oops! Thanks!
|
| + frame_fences_.pop_front(); |
| + } |
| + |
| return true; |
| } |
| @@ -439,7 +462,18 @@ VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() { |
| return vsync_provider_.get(); |
| } |
| +void NativeViewGLSurfaceEGL::SetMaximumFrameLatency(unsigned int frames) { |
| + while (frame_fences_.size() > frames) { |
| + eglDestroySyncKHR(GetDisplay(), frame_fences_.front()); |
| + frame_fences_.pop_front(); |
| + } |
| + max_frame_latency_ = frames; |
| +} |
| + |
| NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { |
| + SetMaximumFrameLatency(0); |
| + DCHECK(!frame_fences_.size()); |
| + |
| Destroy(); |
| #if defined(OS_ANDROID) |
| if (window_) |