Bug 1474721 - Drop epoch times in nsRefreshDriver. r?bz draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Wed, 11 Jul 2018 06:15:00 +0900
changeset 816240 b0c637d0f99d77c474ce1c4d190e27d4be473526
parent 816164 9302fd8c95c05e5a5cd295dde3bbdac2d58d6256
push id115788
push userhikezoe@mozilla.com
push dateTue, 10 Jul 2018 21:16:36 +0000
reviewersbz
bugs1474721, 569520, 909154
milestone63.0a1
Bug 1474721 - Drop epoch times in nsRefreshDriver. r?bz These epoch times were introduced for beforepaint event in bug 569520, and haven't used since we dropped mozRequestAnimationFrame in bug 909154. MozReview-Commit-ID: CGOGeH0rrdi
layout/base/nsRefreshDriver.cpp
layout/base/nsRefreshDriver.h
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -139,17 +139,16 @@ namespace mozilla {
  * StopTimer(), and ScheduleNextTick() -- the first two just
  * start/stop whatever timer mechanism is in use, and ScheduleNextTick
  * is called at the start of the Tick() implementation to set a time
  * for the next tick.
  */
 class RefreshDriverTimer {
 public:
   RefreshDriverTimer()
-    : mLastFireEpoch(0)
   {
   }
 
   NS_INLINE_DECL_REFCOUNTING(RefreshDriverTimer)
 
   virtual void AddRefreshDriver(nsRefreshDriver* aDriver)
   {
     LOG("[%p] AddRefreshDriver %p", this, aDriver);
@@ -197,17 +196,16 @@ public:
 
     bool stopTimer = mContentRefreshDrivers.IsEmpty() && mRootRefreshDrivers.IsEmpty();
     if (stopTimer) {
       StopTimer();
     }
   }
 
   TimeStamp MostRecentRefresh() const { return mLastFireTime; }
-  int64_t MostRecentRefreshEpochTime() const { return mLastFireEpoch; }
 
   void SwapRefreshDrivers(RefreshDriverTimer* aNewTimer)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     for (nsRefreshDriver* driver : mContentRefreshDrivers) {
       aNewTimer->AddRefreshDriver(driver);
       driver->mActiveTimer = aNewTimer;
@@ -215,17 +213,16 @@ public:
     mContentRefreshDrivers.Clear();
 
     for (nsRefreshDriver* driver : mRootRefreshDrivers) {
       aNewTimer->AddRefreshDriver(driver);
       driver->mActiveTimer = aNewTimer;
     }
     mRootRefreshDrivers.Clear();
 
-    aNewTimer->mLastFireEpoch = mLastFireEpoch;
     aNewTimer->mLastFireTime = mLastFireTime;
 
     StopTimer();
   }
 
   virtual TimeDuration GetTimerRate() = 0;
 
   TimeStamp GetIdleDeadlineHint(TimeStamp aDefault)
@@ -273,69 +270,65 @@ protected:
       return false;
     }
 
     return aDriver == rootContext->RefreshDriver();
   }
 
   /*
    * Actually runs a tick, poking all the attached RefreshDrivers.
-   * Grabs the "now" time via JS_Now and TimeStamp::Now().
+   * Grabs the "now" time via TimeStamp::Now().
    */
   void Tick()
   {
-    int64_t jsnow = JS_Now();
     TimeStamp now = TimeStamp::Now();
-    Tick(jsnow, now);
+    Tick(now);
   }
 
-  void TickRefreshDrivers(int64_t aJsNow, TimeStamp aNow, nsTArray<RefPtr<nsRefreshDriver>>& aDrivers)
+  void TickRefreshDrivers(TimeStamp aNow, nsTArray<RefPtr<nsRefreshDriver>>& aDrivers)
   {
     if (aDrivers.IsEmpty()) {
       return;
     }
 
     nsTArray<RefPtr<nsRefreshDriver>> drivers(aDrivers);
     for (nsRefreshDriver* driver : drivers) {
       // don't poke this driver if it's in test mode
       if (driver->IsTestControllingRefreshesEnabled()) {
         continue;
       }
 
-      TickDriver(driver, aJsNow, aNow);
+      TickDriver(driver, aNow);
     }
   }
 
   /*
    * Tick the refresh drivers based on the given timestamp.
    */
-  void Tick(int64_t jsnow, TimeStamp now)
+  void Tick(TimeStamp now)
   {
     ScheduleNextTick(now);
 
-    mLastFireEpoch = jsnow;
     mLastFireTime = now;
 
     LOG("[%p] ticking drivers...", this);
     // RD is short for RefreshDriver
     AUTO_PROFILER_TRACING("Paint", "RefreshDriverTick");
 
-    TickRefreshDrivers(jsnow, now, mContentRefreshDrivers);
-    TickRefreshDrivers(jsnow, now, mRootRefreshDrivers);
+    TickRefreshDrivers(now, mContentRefreshDrivers);
+    TickRefreshDrivers(now, mRootRefreshDrivers);
 
     LOG("[%p] done.", this);
   }
 
-  static void TickDriver(nsRefreshDriver* driver, int64_t jsnow, TimeStamp now)
+  static void TickDriver(nsRefreshDriver* driver, TimeStamp now)
   {
-    LOG(">> TickDriver: %p (jsnow: %" PRId64 ")", driver, jsnow);
-    driver->Tick(jsnow, now);
+    driver->Tick(now);
   }
 
-  int64_t mLastFireEpoch;
   TimeStamp mLastFireTime;
   TimeStamp mTargetTime;
 
   nsTArray<RefPtr<nsRefreshDriver>> mContentRefreshDrivers;
   nsTArray<RefPtr<nsRefreshDriver>> mRootRefreshDrivers;
 
   // useful callback for nsITimer-based derived classes, here
   // because of c++ protected shenanigans
@@ -389,17 +382,16 @@ public:
     return mRateDuration;
   }
 
 protected:
 
   void StartTimer() override
   {
     // pretend we just fired, and we schedule the next tick normally
-    mLastFireEpoch = JS_Now();
     mLastFireTime = TimeStamp::Now();
 
     mTargetTime = mLastFireTime + mRateDuration;
 
     uint32_t delay = static_cast<uint32_t>(mRateMilliseconds);
     mTimer->InitWithNamedFuncCallback(
       TimerTick,
       this,
@@ -720,17 +712,16 @@ private:
     mVsyncObserver = nullptr;
   }
 
   void StartTimer() override
   {
     // Protect updates to `sActiveVsyncTimers`.
     MOZ_ASSERT(NS_IsMainThread());
 
-    mLastFireEpoch = JS_Now();
     mLastFireTime = TimeStamp::Now();
 
     if (XRE_IsParentProcess()) {
       mVsyncDispatcher->SetParentRefreshTimer(mVsyncObserver);
     } else {
       Unused << mVsyncChild->SendObserve();
       mVsyncObserver->OnTimerStart();
     }
@@ -756,20 +747,17 @@ private:
   void ScheduleNextTick(TimeStamp aNowTime) override
   {
     // Do nothing since we just wait for the next vsync from
     // RefreshDriverVsyncObserver.
   }
 
   void RunRefreshDrivers(TimeStamp aTimeStamp)
   {
-    int64_t jsnow = JS_Now();
-    TimeDuration diff = TimeStamp::Now() - aTimeStamp;
-    int64_t vsyncJsNow = jsnow - diff.ToMicroseconds();
-    Tick(vsyncJsNow, aTimeStamp);
+    Tick(aTimeStamp);
   }
 
   RefPtr<RefreshDriverVsyncObserver> mVsyncObserver;
   // Used for parent process.
   RefPtr<RefreshTimerVsyncDispatcher> mVsyncDispatcher;
   // Used for child process.
   // The mVsyncChild will be always available before VsncChild::ActorDestroy().
   // After ActorDestroy(), StartTimer() and StopTimer() calls will be non-op.
@@ -880,17 +868,16 @@ public:
 protected:
   uint32_t GetRefreshDriverCount()
   {
     return mContentRefreshDrivers.Length() + mRootRefreshDrivers.Length();
   }
 
   void StartTimer() override
   {
-    mLastFireEpoch = JS_Now();
     mLastFireTime = TimeStamp::Now();
 
     mTargetTime = mLastFireTime + mRateDuration;
 
     uint32_t delay = static_cast<uint32_t>(mRateMilliseconds);
     mTimer->InitWithNamedFuncCallback(TimerTickOne,
                                       this,
                                       delay,
@@ -931,32 +918,30 @@ protected:
 
     LOG("[%p] inactive timer next tick in %f ms [index %d/%d]", this, mNextTickDuration,
         mNextDriverIndex, GetRefreshDriverCount());
   }
 
   /* Runs just one driver's tick. */
   void TickOne()
   {
-    int64_t jsnow = JS_Now();
     TimeStamp now = TimeStamp::Now();
 
     ScheduleNextTick(now);
 
-    mLastFireEpoch = jsnow;
     mLastFireTime = now;
 
     nsTArray<RefPtr<nsRefreshDriver>> drivers(mContentRefreshDrivers);
     drivers.AppendElements(mRootRefreshDrivers);
     size_t index = mNextDriverIndex;
 
     if (index < drivers.Length() &&
         !drivers[index]->IsTestControllingRefreshesEnabled())
     {
-      TickDriver(drivers[index], jsnow, now);
+      TickDriver(drivers[index], now);
     }
 
     mNextDriverIndex++;
   }
 
   static void TimerTickOne(nsITimer* aTimer, void* aClosure)
   {
     RefPtr<InactiveRefreshDriverTimer> timer =
@@ -1142,17 +1127,16 @@ nsRefreshDriver::nsRefreshDriver(nsPresC
     mResizeSuppressed(false),
     mNotifyDOMContentFlushed(false),
     mWarningThreshold(REFRESH_WAIT_WARNING)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mPresContext,
              "Need a pres context to tell us to call Disconnect() later "
              "and decrement sRefreshDriverCount.");
-  mMostRecentRefreshEpochTime = JS_Now();
   mMostRecentRefresh = TimeStamp::Now();
   mMostRecentTick = mMostRecentRefresh;
   mNextThrottledFrameRequestTick = mMostRecentTick;
   mNextRecomputeVisibilityTick = mMostRecentTick;
 
   ++sRefreshDriverCount;
 }
 
@@ -1177,29 +1161,27 @@ nsRefreshDriver::~nsRefreshDriver()
 // for description.
 void
 nsRefreshDriver::AdvanceTimeAndRefresh(int64_t aMilliseconds)
 {
   // ensure that we're removed from our driver
   StopTimer();
 
   if (!mTestControllingRefreshes) {
-    mMostRecentRefreshEpochTime = JS_Now();
     mMostRecentRefresh = TimeStamp::Now();
 
     mTestControllingRefreshes = true;
     if (mWaitingForTransaction) {
       // Disable any refresh driver throttling when entering test mode
       mWaitingForTransaction = false;
       mSkippedPaints = false;
       mWarningThreshold = REFRESH_WAIT_WARNING;
     }
   }
 
-  mMostRecentRefreshEpochTime += aMilliseconds * 1000;
   mMostRecentRefresh += TimeDuration::FromMilliseconds((double) aMilliseconds);
 
   mozilla::dom::AutoNoJSAPI nojsapi;
   DoTick();
 }
 
 void
 nsRefreshDriver::RestoreNormalRefresh()
@@ -1216,24 +1198,16 @@ nsRefreshDriver::MostRecentRefresh() con
   // RestyleManager::ProcessPendingRestyles().
   if (!ServoStyleSet::IsInServoTraversal()) {
     const_cast<nsRefreshDriver*>(this)->EnsureTimerStarted();
   }
 
   return mMostRecentRefresh;
 }
 
-int64_t
-nsRefreshDriver::MostRecentRefreshEpochTime() const
-{
-  const_cast<nsRefreshDriver*>(this)->EnsureTimerStarted();
-
-  return mMostRecentRefreshEpochTime;
-}
-
 bool
 nsRefreshDriver::AddRefreshObserver(nsARefreshObserver* aObserver,
                                     FlushType aFlushType)
 {
   ObserverArray& array = ArrayFor(aFlushType);
   bool success = array.AppendElement(aObserver) != nullptr;
   EnsureTimerStarted();
   return success;
@@ -1403,21 +1377,16 @@ nsRefreshDriver::EnsureTimerStarted(Ensu
   //
   // The one exception to this is when we are restoring the refresh driver
   // from test control in which case the time is expected to go backwards
   // (see bug 1043078).
   TimeStamp newMostRecentRefresh =
     aFlags & eAllowTimeToGoBackwards
     ? mActiveTimer->MostRecentRefresh()
     : std::max(mActiveTimer->MostRecentRefresh(), mMostRecentRefresh);
-  mMostRecentRefreshEpochTime =
-    aFlags & eAllowTimeToGoBackwards
-    ? mActiveTimer->MostRecentRefreshEpochTime()
-    : std::max(mActiveTimer->MostRecentRefreshEpochTime(),
-               mMostRecentRefreshEpochTime);
 
   if (mMostRecentRefresh != newMostRecentRefresh) {
     mMostRecentRefresh = newMostRecentRefresh;
 
     nsTObserverArray<nsATimerAdjustmentObserver*>::EndLimitedIterator
       iter(mTimerAdjustmentObservers);
     while (iter.HasMore()) {
       nsATimerAdjustmentObserver* obs = iter.GetNext();
@@ -1521,19 +1490,19 @@ void
 nsRefreshDriver::DoTick()
 {
   MOZ_ASSERT(!IsFrozen(), "Why are we notified while frozen?");
   MOZ_ASSERT(mPresContext, "Why are we notified after disconnection?");
   MOZ_ASSERT(!nsContentUtils::GetCurrentJSContext(),
              "Shouldn't have a JSContext on the stack");
 
   if (mTestControllingRefreshes) {
-    Tick(mMostRecentRefreshEpochTime, mMostRecentRefresh);
+    Tick(mMostRecentRefresh);
   } else {
-    Tick(JS_Now(), TimeStamp::Now());
+    Tick(TimeStamp::Now());
   }
 }
 
 struct DocumentFrameCallbacks {
   explicit DocumentFrameCallbacks(nsIDocument* aDocument) :
     mDocument(aDocument)
   {}
 
@@ -1784,17 +1753,17 @@ nsRefreshDriver::CancelIdleRunnable(nsIR
 
   if (sPendingIdleRunnables->IsEmpty()) {
     delete sPendingIdleRunnables;
     sPendingIdleRunnables = nullptr;
   }
 }
 
 void
-nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
+nsRefreshDriver::Tick(TimeStamp aNowTime)
 {
   MOZ_ASSERT(!nsContentUtils::GetCurrentJSContext(),
              "Shouldn't have a JSContext on the stack");
 
   if (nsNPAPIPluginInstance::InPluginCallUnsafeForReentry()) {
     NS_ERROR("Refresh driver should not run during plugin call!");
     // Try to survive this by just ignoring the refresh tick.
     return;
@@ -1817,17 +1786,16 @@ nsRefreshDriver::Tick(int64_t aNowEpoch,
   // wait until the next tick.
   if ((aNowTime <= mMostRecentRefresh) && !mTestControllingRefreshes) {
     return;
   }
 
   TimeStamp previousRefresh = mMostRecentRefresh;
 
   mMostRecentRefresh = aNowTime;
-  mMostRecentRefreshEpochTime = aNowEpoch;
 
   if (IsWaitingForPaint(aNowTime)) {
     // We're currently suspended waiting for earlier Tick's to
     // be completed (on the Compositor). Mark that we missed the paint
     // and keep waiting.
     return;
   }
   mMostRecentTick = aNowTime;
--- a/layout/base/nsRefreshDriver.h
+++ b/layout/base/nsRefreshDriver.h
@@ -111,20 +111,16 @@ public:
   /**
    * Return the time of the most recent refresh.  This is intended to be
    * used by callers who want to start an animation now and want to know
    * what time to consider the start of the animation.  (This helps
    * ensure that multiple animations started during the same event off
    * the main event loop have the same start time.)
    */
   mozilla::TimeStamp MostRecentRefresh() const;
-  /**
-   * Same thing, but in microseconds since the epoch.
-   */
-  int64_t MostRecentRefreshEpochTime() const;
 
   /**
    * Add / remove refresh observers.  Returns whether the operation
    * succeeded.
    *
    * The flush type affects:
    *   + the order in which the observers are notified (lowest flush
    *     type to highest, in order registered)
@@ -425,17 +421,17 @@ private:
     RequestTable mEntries;
   };
   typedef nsClassHashtable<nsUint32HashKey, ImageStartData> ImageStartTable;
 
   void DispatchPendingEvents();
   void DispatchAnimationEvents();
   void RunFrameRequestCallbacks(mozilla::TimeStamp aNowTime);
   void UpdateIntersectionObservations();
-  void Tick(int64_t aNowEpoch, mozilla::TimeStamp aNowTime);
+  void Tick(mozilla::TimeStamp aNowTime);
 
   enum EnsureTimerStartedFlags {
     eNone = 0,
     eForceAdjustTimer = 1 << 0,
     eAllowTimeToGoBackwards = 1 << 1,
     eNeverAdjustTimer = 1 << 2,
   };
   void EnsureTimerStarted(EnsureTimerStartedFlags aFlags = eNone);
@@ -507,17 +503,16 @@ private:
   // True if view managers should delay any resize request until the
   // next tick by the refresh driver. This flag will be reset at the
   // start of every tick.
   bool mResizeSuppressed;
 
   // True if the next tick should notify DOMContentFlushed.
   bool mNotifyDOMContentFlushed;
 
-  int64_t mMostRecentRefreshEpochTime;
   // Number of seconds that the refresh driver is blocked waiting for a compositor
   // transaction to be completed before we append a note to the gfx critical log.
   // The number is doubled every time the threshold is hit.
   uint64_t mWarningThreshold;
   mozilla::TimeStamp mMostRecentRefresh;
   mozilla::TimeStamp mMostRecentTick;
   mozilla::TimeStamp mTickStart;
   mozilla::TimeStamp mNextThrottledFrameRequestTick;