Bug 1144946 - Delete PreciseRefreshDriverTimerWindowsDwmVsync refresh driver timer. r=roc
authorMason Chang <mchang@mozilla.com>
Thu, 13 Aug 2015 08:22:28 -0700
changeset 257590 bbc8646e83432bd74a37b6a6950a53c9e5a4644d
parent 257589 a5c25038d81e9de97b939f9380c20773b10ace46
child 257591 be020690f03288bbbcf8e061a2f0bc80de498195
push id29223
push userkwierso@gmail.com
push dateThu, 13 Aug 2015 22:18:08 +0000
treeherdermozilla-central@4b35236fc76e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1144946
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1144946 - Delete PreciseRefreshDriverTimerWindowsDwmVsync refresh driver timer. r=roc
layout/base/nsRefreshDriver.cpp
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -516,134 +516,16 @@ protected:
     // then schedule the timer
     LOG("[%p] scheduling callback for %d ms (2)", this, delay);
     mTimer->InitWithFuncCallback(TimerTick, this, delay, nsITimer::TYPE_ONE_SHOT);
 
     mTargetTime = newTarget;
   }
 };
 
-#ifdef XP_WIN
-/*
- * Uses vsync timing on windows with DWM. Falls back dynamically to fixed rate if required.
- */
-class PreciseRefreshDriverTimerWindowsDwmVsync :
-  public PreciseRefreshDriverTimer
-{
-public:
-  // Checks if the vsync API is accessible.
-  static bool IsSupported()
-  {
-    return WinUtils::dwmGetCompositionTimingInfoPtr != nullptr;
-  }
-
-  PreciseRefreshDriverTimerWindowsDwmVsync(double aRate, bool aPreferHwTiming = false)
-    : PreciseRefreshDriverTimer(aRate)
-    , mPreferHwTiming(aPreferHwTiming)
-  {
-  }
-
-protected:
-  // Indicates we should try to adjust to the HW's timing (get rate from the OS or use vsync)
-  // This is typically true if the default refresh-rate value was not modified by the user.
-  bool mPreferHwTiming;
-
-  nsresult GetVBlankInfo(mozilla::TimeStamp &aLastVBlank, mozilla::TimeDuration &aInterval)
-  {
-    MOZ_ASSERT(WinUtils::dwmGetCompositionTimingInfoPtr,
-               "DwmGetCompositionTimingInfoPtr is unavailable (windows vsync)");
-
-    DWM_TIMING_INFO timingInfo;
-    timingInfo.cbSize = sizeof(DWM_TIMING_INFO);
-    HRESULT hr = WinUtils::dwmGetCompositionTimingInfoPtr(0, &timingInfo); // For the desktop window instead of a specific one.
-
-    if (FAILED(hr)) {
-      // This happens first time this is called.
-      return NS_ERROR_NOT_INITIALIZED;
-    }
-
-    LARGE_INTEGER time, freq;
-    ::QueryPerformanceCounter(&time);
-    ::QueryPerformanceFrequency(&freq);
-    aLastVBlank = TimeStamp::Now();
-    double secondsPassed = double(time.QuadPart - timingInfo.qpcVBlank) / double(freq.QuadPart);
-
-    aLastVBlank -= TimeDuration::FromSeconds(secondsPassed);
-    aInterval = TimeDuration::FromSeconds(double(timingInfo.qpcRefreshPeriod) / double(freq.QuadPart));
-
-    return NS_OK;
-  }
-
-  virtual void ScheduleNextTick(TimeStamp aNowTime)
-  {
-    static const TimeDuration kMinSaneInterval = TimeDuration::FromMilliseconds(3); // 330Hz
-    static const TimeDuration kMaxSaneInterval = TimeDuration::FromMilliseconds(44); // 23Hz
-    static const TimeDuration kNegativeMaxSaneInterval = TimeDuration::FromMilliseconds(-44); // Saves conversions for abs interval
-    TimeStamp lastVblank;
-    TimeDuration vblankInterval;
-
-    if (!mPreferHwTiming ||
-        NS_OK != GetVBlankInfo(lastVblank, vblankInterval) ||
-        vblankInterval > kMaxSaneInterval ||
-        vblankInterval < kMinSaneInterval ||
-        (aNowTime - lastVblank) > kMaxSaneInterval ||
-        (aNowTime - lastVblank) < kNegativeMaxSaneInterval) {
-      // Use the default timing without vsync
-      PreciseRefreshDriverTimer::ScheduleNextTick(aNowTime);
-      return;
-    }
-
-    TimeStamp newTarget = lastVblank + vblankInterval; // Base target
-
-    // However, timer callback might return early (or late, but that wouldn't bother us), and vblankInterval
-    // appears to be slightly (~1%) different on each call (probably the OS measuring recent actual interval[s])
-    // and since we don't want to re-target the same vsync, we keep advancing in vblank intervals until we find the
-    // next safe target (next vsync, but not within 10% interval of previous target).
-    // This is typically 0 or 1 iteration:
-    // If we're too early, next vsync would be the one we've already targeted (1 iteration).
-    // If the timer returned late, no iteration will be required.
-
-    const double kSameVsyncThreshold = 0.1;
-    while (newTarget <= mTargetTime + vblankInterval.MultDouble(kSameVsyncThreshold)) {
-      newTarget += vblankInterval;
-    }
-
-    // To make sure we always hit the same "side" of the signal:
-    // round the delay up (by adding 1, since we later floor) and add a little (10% by default).
-    // Note that newTarget doesn't change (and is the next vblank) as a reference when we're back.
-    static const double kDefaultPhaseShiftPercent = 10;
-    static const double phaseShiftFactor = 0.01 *
-      (Preferences::GetInt("layout.frame_rate.vsync.phasePercentage", kDefaultPhaseShiftPercent) % 100);
-
-    double phaseDelay = 1.0 + vblankInterval.ToMilliseconds() * phaseShiftFactor;
-
-    // ms until the next time we should tick
-    double delayMs = (newTarget - aNowTime).ToMilliseconds() + phaseDelay;
-
-    // Make sure the delay is never negative.
-    uint32_t delay = static_cast<uint32_t>(delayMs < 0 ? 0 : delayMs);
-
-    // log info & lateness
-    LOG("[%p] precise dwm-vsync timer last tick late by %f ms, next tick in %d ms",
-        this,
-        (aNowTime - mTargetTime).ToMilliseconds(),
-        delay);
-#ifndef ANDROID  /* bug 1142079 */
-    Telemetry::Accumulate(Telemetry::FX_REFRESH_DRIVER_FRAME_DELAY_MS, (aNowTime - mTargetTime).ToMilliseconds());
-#endif
-
-    // then schedule the timer
-    LOG("[%p] scheduling callback for %d ms (2)", this, delay);
-    mTimer->InitWithFuncCallback(TimerTick, this, delay, nsITimer::TYPE_ONE_SHOT);
-
-    mTargetTime = newTarget;
-  }
-};
-#endif
-
 /*
  * A RefreshDriverTimer for inactive documents.  When a new refresh driver is
  * added, the rate is reset to the base (normally 1s/1fps).  Every time
  * it ticks, a single refresh driver is poked.  Once they have all been poked,
  * the duration between ticks doubles, up to mDisableAfterMilliseconds.  At that point,
  * the timer is quiet and doesn't tick (until something is added to it again).
  *
  * When a timer is removed, there is a possibility of another timer
@@ -1002,21 +884,16 @@ nsRefreshDriver::ChooseTimer() const
 
   if (!sRegularRateTimer) {
     bool isDefault = true;
     double rate = GetRegularTimerInterval(&isDefault);
 
     // Try to use vsync-base refresh timer first for sRegularRateTimer.
     CreateVsyncRefreshTimer();
 
-#ifdef XP_WIN
-    if (!sRegularRateTimer && PreciseRefreshDriverTimerWindowsDwmVsync::IsSupported()) {
-      sRegularRateTimer = new PreciseRefreshDriverTimerWindowsDwmVsync(rate, isDefault);
-    }
-#endif
     if (!sRegularRateTimer) {
       sRegularRateTimer = new PreciseRefreshDriverTimer(rate);
     }
   }
   return sRegularRateTimer;
 }
 
 nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext)