Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Unified Diff: ui/gl/gl_surface_win.cc

Issue 615613002: Enabled detection of different refresh rates per monitor on Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gl/gl_surface_win.cc
diff --git a/ui/gl/gl_surface_win.cc b/ui/gl/gl_surface_win.cc
index 3cde3ea9c7645ffd1dd9d20cf5ae19f603ccd9be..c1e07b2911fa0997a3b9590518491362b05f01ad 100644
--- a/ui/gl/gl_surface_win.cc
+++ b/ui/gl/gl_surface_win.cc
@@ -59,43 +59,88 @@ class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa {
DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceOSMesa);
};
-class DWMVSyncProvider : public VSyncProvider {
+class WinVSyncProvider : public VSyncProvider {
public:
- explicit DWMVSyncProvider() {}
+ explicit WinVSyncProvider(gfx::AcceleratedWidget window) :
+ window_(window)
+ {
+ use_dwm_ = (base::win::GetVersion() >= base::win::VERSION_VISTA);
+ }
- virtual ~DWMVSyncProvider() {}
+ virtual ~WinVSyncProvider() {}
virtual void GetVSyncParameters(const UpdateVSyncCallback& callback) {
- TRACE_EVENT0("gpu", "DWMVSyncProvider::GetVSyncParameters");
- DWM_TIMING_INFO timing_info;
- timing_info.cbSize = sizeof(timing_info);
- HRESULT result = DwmGetCompositionTimingInfo(NULL, &timing_info);
- if (result != S_OK)
- return;
+ TRACE_EVENT0("gpu", "WinVSyncProvider::GetVSyncParameters");
base::TimeTicks timebase;
- // If FrameTime is not high resolution, we do not want to translate the
- // QPC value provided by DWM into the low-resolution timebase, which
- // would be error prone and jittery. As a fallback, we assume the timebase
- // is zero.
- if (gfx::FrameTime::TimestampsAreHighRes()) {
- timebase = gfx::FrameTime::FromQPCValue(
- static_cast<LONGLONG>(timing_info.qpcVBlank));
+ base::TimeDelta interval;
+ bool dwm_active = false;
+
+ // Query the DWM timing info first if available. This will provide the most
+ // precise values.
+ if (use_dwm_) {
+ DWM_TIMING_INFO timing_info;
+ timing_info.cbSize = sizeof(timing_info);
+ HRESULT result = DwmGetCompositionTimingInfo(NULL, &timing_info);
+ if (result == S_OK) {
+ dwm_active = true;
+ // If FrameTime is not high resolution, we do not want to translate the
+ // QPC value provided by DWM into the low-resolution timebase, which
+ // would be error prone and jittery. As a fallback, we assume the
+ // timebase is zero.
+ if (gfx::FrameTime::TimestampsAreHighRes()) {
+ timebase = gfx::FrameTime::FromQPCValue(
+ static_cast<LONGLONG>(timing_info.qpcVBlank));
+ }
+
+ // Swap the numerator/denominator to convert frequency to period.
+ if (timing_info.rateRefresh.uiDenominator > 0 &&
+ timing_info.rateRefresh.uiNumerator > 0) {
+ interval = base::TimeDelta::FromMicroseconds(
+ timing_info.rateRefresh.uiDenominator *
+ base::Time::kMicrosecondsPerSecond /
+ timing_info.rateRefresh.uiNumerator);
+ }
+ }
}
- // Swap the numerator/denominator to convert frequency to period.
- if (timing_info.rateRefresh.uiDenominator > 0 &&
- timing_info.rateRefresh.uiNumerator > 0) {
- base::TimeDelta interval = base::TimeDelta::FromMicroseconds(
- timing_info.rateRefresh.uiDenominator *
- base::Time::kMicrosecondsPerSecond /
- timing_info.rateRefresh.uiNumerator);
+ // Double check DWM values against per-display refresh rates.
+ // When DWM compositing is active all displays are normalized to the
+ // refresh rate of the primary display, and won't composite any faster.
+ // If the display refresh rate is higher than the DWM reported value we will
+ // favor the DWM value because any additional frames produced will be
+ // discarded by the OS. If the display refresh rate is lower, however, we
+ // can use that to limit the frames we produce more intelligently.
+ // If DWM compositing is not active we will always use the display refresh.
+ HMONITOR monitor = MonitorFromWindow(window_, MONITOR_DEFAULTTONEAREST);
+ MONITORINFOEX monitor_info;
+ monitor_info.cbSize = sizeof(MONITORINFOEX);
+ BOOL result = GetMonitorInfo(monitor, &monitor_info);
+ if (result != 0) {
jbauman 2014/09/29 19:37:07 if (result) {
+ DEVMODE display_info;
+ result = EnumDisplaySettings(monitor_info.szDevice, ENUM_CURRENT_SETTINGS,
+ &display_info);
+ if (result != 0 && display_info.dmDisplayFrequency > 0) {
jbauman 2014/09/29 19:37:07 if (result && display_info.dmDisplayFrequency > 1)
+ base::TimeDelta display_interval = base::TimeDelta::FromMicroseconds(
+ (1.0 / static_cast<double>(display_info.dmDisplayFrequency)) *
+ base::Time::kMicrosecondsPerSecond);
+
+ if (!dwm_active || display_interval > interval) {
+ interval = display_interval;
+ }
+ }
+ }
+
+ if (interval.ToInternalValue() != 0) {
callback.Run(timebase, interval);
}
}
private:
- DISALLOW_COPY_AND_ASSIGN(DWMVSyncProvider);
+ DISALLOW_COPY_AND_ASSIGN(WinVSyncProvider);
+
+ gfx::AcceleratedWidget window_;
+ bool use_dwm_;
};
// Helper routine that does one-off initialization like determining the
@@ -245,8 +290,7 @@ scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
scoped_refptr<NativeViewGLSurfaceEGL> surface(
new NativeViewGLSurfaceEGL(window));
scoped_ptr<VSyncProvider> sync_provider;
- if (base::win::GetVersion() >= base::win::VERSION_VISTA)
- sync_provider.reset(new DWMVSyncProvider);
+ sync_provider.reset(new WinVSyncProvider(window));
if (!surface->Initialize(sync_provider.Pass()))
return NULL;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698