Chromium Code Reviews| 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; |
| } |
| } |
| } |