Chromium Code Reviews| Index: ui/gl/gl_surface_glx.cc |
| diff --git a/ui/gl/gl_surface_glx.cc b/ui/gl/gl_surface_glx.cc |
| index 07c281d94d3acbe2e582bf771a86ac0ce72855d7..f60d16ea526da49e7c9c9e426ecd1f2ada9bb022 100644 |
| --- a/ui/gl/gl_surface_glx.cc |
| +++ b/ui/gl/gl_surface_glx.cc |
| @@ -57,7 +57,10 @@ class OMLSyncControlVSyncProvider |
| : public gfx::NativeViewGLSurfaceGLX::VSyncProvider { |
| public: |
| explicit OMLSyncControlVSyncProvider(gfx::AcceleratedWidget window) |
| - : window_(window) { |
| + : window_(window), |
| + last_timebase_(), |
| + last_media_stream_counter_(0), |
| + last_good_interval_(kDefaultIntervalTime) { |
| } |
| virtual ~OMLSyncControlVSyncProvider() { } |
| @@ -65,7 +68,6 @@ class OMLSyncControlVSyncProvider |
| virtual void GetVSyncParameters( |
| const GLSurface::UpdateVSyncCallback& callback) OVERRIDE { |
| base::TimeTicks timebase; |
| - base::TimeDelta interval; |
| // The actual clock used for the system time returned by glXGetSyncValuesOML |
| // is unspecified. In practice, the clock used is likely to be either |
| @@ -113,30 +115,46 @@ class OMLSyncControlVSyncProvider |
| timebase = base::TimeTicks::FromInternalValue(system_time); |
| } |
| - // On platforms where glXGetMscRateOML doesn't work, we fall back to the |
| - // assumption that we're displaying 60 frames per second. |
| - const int64 kDefaultIntervalTime = |
| - base::Time::kMicrosecondsPerSecond / 60; |
| - int64 interval_time = kDefaultIntervalTime; |
| - int32 numerator; |
| - int32 denominator; |
| if (g_glx_get_msc_rate_oml_supported) { |
| + int32 numerator, denominator; |
| if (glXGetMscRateOML(g_display, window_, &numerator, &denominator)) { |
| - interval_time = |
| + last_good_interval_ = |
| (base::Time::kMicrosecondsPerSecond * denominator) / numerator; |
| } else { |
| // Once glXGetMscRateOML has been found to fail, don't try again, |
| // since each failing call may spew an error message. |
| g_glx_get_msc_rate_oml_supported = false; |
| } |
| + } else { |
| + if (!last_timebase_.is_null()) { |
| + base::TimeDelta timebase_diff = timebase - last_timebase_; |
| + uint64 counter_diff = media_stream_counter - |
| + last_media_stream_counter_; |
| + if (counter_diff > 0 && timebase > last_timebase_) { |
| + last_good_interval_ = timebase_diff.InMicroseconds() / |
| + counter_diff; |
| + } |
| + } |
| } |
| - interval = base::TimeDelta::FromMicroseconds(interval_time); |
| + last_timebase_ = timebase; |
| + last_media_stream_counter_ = media_stream_counter; |
| + base::TimeDelta interval = |
| + base::TimeDelta::FromMicroseconds(last_good_interval_); |
| callback.Run(timebase, interval); |
| } |
| private: |
| XID window_; |
| + base::TimeTicks last_timebase_; |
| + uint64 last_media_stream_counter_; |
| + int64 last_good_interval_; |
|
ajuma
2013/01/04 15:34:43
Nit: making this a TimeDelta instead of an int64 w
jonathan.backer
2013/01/04 16:26:45
Done.
|
| + |
| + // On platforms where we can't get an accurate reading on the refresh |
| + // rate we fall back to the assumption that we're displaying 60 frames |
| + // per second. |
| + const int64 kDefaultIntervalTime = base::Time::kMicrosecondsPerSecond / 60; |
| + |
| DISALLOW_COPY_AND_ASSIGN(OMLSyncControlVSyncProvider); |
| }; |
| @@ -182,7 +200,7 @@ class SGIVideoSyncProviderThreadShim |
| vsync_lock_() { |
| // This ensures that creation of |window_| has occured when this shim |
| // is executing in the same process as the call to create |window_|. |
| - XSync(::gfx::g_display, False); |
| + XSync(g_display, False); |
| } |
| base::CancellationFlag* cancel_vsync_flag() { |
| @@ -194,11 +212,10 @@ class SGIVideoSyncProviderThreadShim |
| } |
| void Initialize() { |
| - DCHECK(SGIVideoSyncProviderThreadShim::g_display); |
| + DCHECK(display_); |
| XWindowAttributes attributes; |
| - if (!XGetWindowAttributes(SGIVideoSyncProviderThreadShim::g_display, |
| - window_, &attributes)) { |
| + if (!XGetWindowAttributes(display_, window_, &attributes)) { |
| LOG(ERROR) << "XGetWindowAttributes failed for window " << |
| window_ << "."; |
| return; |
| @@ -209,7 +226,7 @@ class SGIVideoSyncProviderThreadShim |
| int visual_info_count = 0; |
| scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info_list( |
| - XGetVisualInfo(SGIVideoSyncProviderThreadShim::g_display, VisualIDMask, |
| + XGetVisualInfo(display_, VisualIDMask, |
| &visual_info_template, &visual_info_count)); |
| DCHECK(visual_info_list.get()); |
| @@ -218,17 +235,14 @@ class SGIVideoSyncProviderThreadShim |
| return; |
| } |
| - context_ = glXCreateContext(SGIVideoSyncProviderThreadShim::g_display, |
| - visual_info_list.get(), |
| - NULL, |
| - True); |
| + context_ = glXCreateContext(display_, visual_info_list.get(), NULL, True); |
| DCHECK(NULL != context_); |
| } |
| void Destroy() { |
| if (context_) { |
| - glXDestroyContext(SGIVideoSyncProviderThreadShim::g_display, context_); |
| + glXDestroyContext(display_, context_); |
| context_ = NULL; |
| } |
| delete this; |
| @@ -243,8 +257,7 @@ class SGIVideoSyncProviderThreadShim |
| if (!context_ || cancel_vsync_flag_.IsSet()) |
| return; |
| - glXMakeCurrent(SGIVideoSyncProviderThreadShim::g_display, |
| - window_, context_); |
| + glXMakeCurrent(display_, window_, context_); |
| unsigned int retrace_count = 0; |
| if (glXWaitVideoSyncSGI(1, 0, &retrace_count) != 0) |
| @@ -253,7 +266,7 @@ class SGIVideoSyncProviderThreadShim |
| TRACE_EVENT_INSTANT0("gpu", "vblank"); |
| now = base::TimeTicks::HighResNow(); |
| - glXMakeCurrent(SGIVideoSyncProviderThreadShim::g_display, 0, 0); |
| + glXMakeCurrent(display_, 0, 0); |
| } |
| const int64 kDefaultIntervalTime = |
| @@ -265,14 +278,14 @@ class SGIVideoSyncProviderThreadShim |
| } |
| private: |
| - // For initialization of g_display in GLSurface::InitializeOneOff before |
| + // For initialization of display_ in GLSurface::InitializeOneOff before |
| // the sandbox goes up. |
| friend class gfx::GLSurfaceGLX; |
| virtual ~SGIVideoSyncProviderThreadShim() { |
| } |
| - static Display* g_display; |
| + static Display* display_; |
| XID window_; |
| GLXContext context_; |
| @@ -353,7 +366,7 @@ SGIVideoSyncThread* SGIVideoSyncThread::g_video_sync_thread = NULL; |
| // In order to take advantage of GLX_SGI_video_sync, we need a display |
| // for use on a separate thread. We must allocate this before the sandbox |
| // goes up (rather than on-demand when we start the thread). |
| -Display* SGIVideoSyncProviderThreadShim::g_display = NULL; |
| +Display* SGIVideoSyncProviderThreadShim::display_ = NULL; |
| } // namespace |
| @@ -399,7 +412,7 @@ bool GLSurfaceGLX::InitializeOneOff() { |
| HasGLXExtension("GLX_SGI_video_sync"); |
| if (!g_glx_get_msc_rate_oml_supported && g_glx_sgi_video_sync_supported) |
| - SGIVideoSyncProviderThreadShim::g_display = XOpenDisplay(NULL); |
| + SGIVideoSyncProviderThreadShim::display_ = XOpenDisplay(NULL); |
| initialized = true; |
| return true; |