Index: ui/gl/gl_surface_win.cc |
diff --git a/ui/gl/gl_surface_win.cc b/ui/gl/gl_surface_win.cc |
index 02407a580c79f97d6384d400bd41f87c189a7344..9962468fcd9e9586db2bbd6254143cffb41953ca 100644 |
--- a/ui/gl/gl_surface_win.cc |
+++ b/ui/gl/gl_surface_win.cc |
@@ -76,6 +76,19 @@ class WinVSyncProvider : public VSyncProvider { |
HRESULT result = DwmGetCompositionTimingInfo(NULL, &timing_info); |
if (result == S_OK) { |
dwm_active = true; |
+ |
+ // Calculate a backup interval value using the rateRefresh numerator and |
+ // denominator. |
+ base::TimeDelta interval2; |
jbauman
2015/05/14 22:42:39
Nit, maybe call this "backup_interval".
brucedawson
2015/05/14 22:51:57
How about 'rate_interval'. That gives more of a re
sunnyps
2015/05/14 23:05:14
I don't care much about the name but I like low_re
|
+ if (timing_info.rateRefresh.uiDenominator > 0 && |
+ timing_info.rateRefresh.uiNumerator > 0) { |
+ // Swap the numerator/denominator to convert frequency to period. |
+ interval2 = base::TimeDelta::FromMicroseconds( |
+ timing_info.rateRefresh.uiDenominator * |
+ base::Time::kMicrosecondsPerSecond / |
+ timing_info.rateRefresh.uiNumerator); |
+ } |
+ |
if (gfx::FrameTime::TimestampsAreHighRes()) { |
// qpcRefreshPeriod is very accurate but noisy, and must be used with |
// a high resolution timebase to avoid frequently missing Vsync. |
@@ -83,8 +96,18 @@ class WinVSyncProvider : public VSyncProvider { |
static_cast<LONGLONG>(timing_info.qpcVBlank)); |
interval = base::TimeDelta::FromQPCValue( |
static_cast<LONGLONG>(timing_info.qpcRefreshPeriod)); |
- } else if (timing_info.rateRefresh.uiDenominator > 0 && |
- timing_info.rateRefresh.uiNumerator > 0) { |
+ // Check for interval values that are impossibly low. A 29 microsecond |
+ // interval was seen (from a qpcRefreshPeriod of 60). |
+ if (interval < base::TimeDelta::FromMilliseconds(1)) { |
+ interval = interval2; |
+ } |
+ // Check for the qpcRefreshPeriod interval being improbably small |
+ // compared to the rateRefresh calculated interval, as another |
+ // attempt at detecting driver bugs. |
+ if (!interval2.is_zero() && interval < interval2 / 2) { |
+ interval = interval2; |
+ } |
+ } else { |
// 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 |
@@ -92,12 +115,7 @@ class WinVSyncProvider : public VSyncProvider { |
// isn't noisy like qpcRefreshPeriod, instead. The fact that we don't |
// have a timebase here may lead to brief periods of jank when our |
// scheduling becomes offset from the hardware vsync. |
- |
- // Swap the numerator/denominator to convert frequency to period. |
- interval = base::TimeDelta::FromMicroseconds( |
- timing_info.rateRefresh.uiDenominator * |
- base::Time::kMicrosecondsPerSecond / |
- timing_info.rateRefresh.uiNumerator); |
+ interval = interval2; |
} |
} |
} |