summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-04 23:37:57 +0000
committerbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-04 23:37:57 +0000
commite9d46f8b56c8fdb4bf2ffab8900d53fe20a68890 (patch)
tree5e1bc0f70f8c6c77fc838fef9a942ab8c7ada5ab
parent8c43efaf1ed7bfeb03903aaae059873edd57b246 (diff)
downloadchromium_src-e9d46f8b56c8fdb4bf2ffab8900d53fe20a68890.zip
chromium_src-e9d46f8b56c8fdb4bf2ffab8900d53fe20a68890.tar.gz
chromium_src-e9d46f8b56c8fdb4bf2ffab8900d53fe20a68890.tar.bz2
Calculate the refresh period from GLX_OML_sync_control.
glXGetSyncValuesOML gives us a count of the number of refreshes that have occurred (media stream counter). We can use this and the time between successive UST counters to measure the period of the screen refresh. BUG=none TEST=by hand on stumpy and alex using xrandr to force different refresh rates Review URL: https://chromiumcodereview.appspot.com/11752002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@175234 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/gl/gl_surface_glx.cc75
1 files changed, 40 insertions, 35 deletions
diff --git a/ui/gl/gl_surface_glx.cc b/ui/gl/gl_surface_glx.cc
index 07c281d..fde3df5d 100644
--- a/ui/gl/gl_surface_glx.cc
+++ b/ui/gl/gl_surface_glx.cc
@@ -57,7 +57,12 @@ class OMLSyncControlVSyncProvider
: public gfx::NativeViewGLSurfaceGLX::VSyncProvider {
public:
explicit OMLSyncControlVSyncProvider(gfx::AcceleratedWidget window)
- : window_(window) {
+ : window_(window),
+ last_media_stream_counter_(0) {
+ // 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.
+ last_good_interval_ = base::TimeDelta::FromSeconds(1) / 60;
}
virtual ~OMLSyncControlVSyncProvider() { }
@@ -65,7 +70,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 +117,37 @@ 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 =
- (base::Time::kMicrosecondsPerSecond * denominator) / numerator;
+ last_good_interval_ =
+ base::TimeDelta::FromSeconds(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 / counter_diff;
+ }
}
- interval = base::TimeDelta::FromMicroseconds(interval_time);
- callback.Run(timebase, interval);
+ last_timebase_ = timebase;
+ last_media_stream_counter_ = media_stream_counter;
+ callback.Run(timebase, last_good_interval_);
}
private:
XID window_;
+ base::TimeTicks last_timebase_;
+ uint64 last_media_stream_counter_;
+ base::TimeDelta last_good_interval_;
+
DISALLOW_COPY_AND_ASSIGN(OMLSyncControlVSyncProvider);
};
@@ -182,7 +193,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 +205,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 +219,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 +228,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 +250,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,26 +259,25 @@ class SGIVideoSyncProviderThreadShim
TRACE_EVENT_INSTANT0("gpu", "vblank");
now = base::TimeTicks::HighResNow();
- glXMakeCurrent(SGIVideoSyncProviderThreadShim::g_display, 0, 0);
+ glXMakeCurrent(display_, 0, 0);
}
- const int64 kDefaultIntervalTime =
- base::Time::kMicrosecondsPerSecond / 60;
- base::TimeDelta interval =
- base::TimeDelta::FromMicroseconds(kDefaultIntervalTime);
+ const base::TimeDelta kDefaultInterval =
+ base::TimeDelta::FromSeconds(1) / 60;
- message_loop_->PostTask(FROM_HERE, base::Bind(callback, now, interval));
+ message_loop_->PostTask(
+ FROM_HERE, base::Bind(callback, now, kDefaultInterval));
}
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 +358,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 +404,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;