tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsRefreshDriver.h (21201B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /*
      8 * Code to notify things that animate before a refresh, at an appropriate
      9 * refresh rate.  (Perhaps temporary, until replaced by compositor.)
     10 */
     11 
     12 #ifndef nsRefreshDriver_h_
     13 #define nsRefreshDriver_h_
     14 
     15 #include "GeckoProfiler.h"  // for ProfileChunkedBuffer
     16 #include "LayersTypes.h"
     17 #include "mozilla/Attributes.h"
     18 #include "mozilla/FlushType.h"
     19 #include "mozilla/Maybe.h"
     20 #include "mozilla/RenderingPhase.h"
     21 #include "mozilla/TimeStamp.h"
     22 #include "mozilla/UniquePtr.h"
     23 #include "mozilla/WeakPtr.h"
     24 #include "mozilla/layers/TransactionIdAllocator.h"
     25 #include "nsClassHashtable.h"
     26 #include "nsHashKeys.h"
     27 #include "nsRefreshObservers.h"
     28 #include "nsTArray.h"
     29 #include "nsTHashSet.h"
     30 #include "nsTObserverArray.h"
     31 #include "nsThreadUtils.h"
     32 
     33 class nsPresContext;
     34 
     35 class imgIRequest;
     36 class nsIRunnable;
     37 
     38 struct DocumentFrameCallbacks;
     39 
     40 namespace mozilla {
     41 class AnimationEventDispatcher;
     42 class PresShell;
     43 class RefreshDriverTimer;
     44 class Runnable;
     45 class Task;
     46 
     47 namespace dom {
     48 class Document;
     49 }
     50 
     51 }  // namespace mozilla
     52 
     53 class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator,
     54                              public nsARefreshObserver {
     55  using Document = mozilla::dom::Document;
     56  using TransactionId = mozilla::layers::TransactionId;
     57  using LogPresShellObserver = mozilla::LogPresShellObserver;
     58 
     59 public:
     60  explicit nsRefreshDriver(nsPresContext* aPresContext);
     61  ~nsRefreshDriver();
     62 
     63  /**
     64   * Methods for testing, exposed via nsIDOMWindowUtils.  See
     65   * nsIDOMWindowUtils.advanceTimeAndRefresh for description.
     66   */
     67  void AdvanceTimeAndRefresh(int64_t aMilliseconds);
     68  void RestoreNormalRefresh();
     69  void DoTick();
     70  bool IsTestControllingRefreshesEnabled() const {
     71    return mTestControllingRefreshes;
     72  }
     73 
     74  /**
     75   * Return the time of the most recent refresh.  This is intended to be
     76   * used by callers who want to start an animation now and want to know
     77   * what time to consider the start of the animation.  (This helps
     78   * ensure that multiple animations started during the same event off
     79   * the main event loop have the same start time.)
     80   */
     81  mozilla::TimeStamp MostRecentRefresh() const { return mMostRecentRefresh; }
     82 
     83  /**
     84   * Add / remove refresh observers.
     85   * RemoveRefreshObserver returns true if aObserver was found.
     86   *
     87   * The flush type affects:
     88   *   + the order in which the observers are notified (lowest flush
     89   *     type to highest, in order registered)
     90   *   + (in the future) which observers are suppressed when the display
     91   *     doesn't require current position data or isn't currently
     92   *     painting, and, correspondingly, which get notified when there
     93   *     is a flush during such suppression
     94   * and it must be FlushType::Style, or FlushType::Display.
     95   *
     96   * The refresh driver does NOT own a reference to these observers;
     97   * they must remove themselves before they are destroyed.
     98   *
     99   * The observer will be called even if there is no other activity.
    100   */
    101  void AddRefreshObserver(nsARefreshObserver* aObserver,
    102                          mozilla::FlushType aFlushType,
    103                          const char* aObserverDescription);
    104  bool RemoveRefreshObserver(nsARefreshObserver* aObserver,
    105                             mozilla::FlushType aFlushType);
    106 
    107  MOZ_CAN_RUN_SCRIPT void FlushLayoutOnPendingDocsAndFixUpFocus();
    108 
    109  /**
    110   * Add an observer that will be called after each refresh. The caller
    111   * must remove the observer before it is deleted. This does not trigger
    112   * refresh driver ticks.
    113   */
    114  void AddPostRefreshObserver(nsAPostRefreshObserver* aObserver);
    115  void AddPostRefreshObserver(mozilla::ManagedPostRefreshObserver*) = delete;
    116  void RemovePostRefreshObserver(nsAPostRefreshObserver* aObserver);
    117  void RemovePostRefreshObserver(mozilla::ManagedPostRefreshObserver*) = delete;
    118 
    119  /**
    120   * Add/Remove imgIRequest versions of observers.
    121   *
    122   * These are used for hooking into the refresh driver for
    123   * controlling animated images.
    124   *
    125   * @note The refresh driver owns a reference to these listeners.
    126   *
    127   * @note Technically, imgIRequest objects are not nsARefreshObservers, but
    128   * for controlling animated image repaint events, we subscribe the
    129   * imgIRequests to the nsRefreshDriver for notification of paint events.
    130   */
    131  void AddImageRequest(imgIRequest* aRequest);
    132  void RemoveImageRequest(imgIRequest* aRequest);
    133  void StartTimerForAnimatedImagesIfNeeded();
    134  void StopTimerForAnimatedImagesIfNeeded();
    135 
    136  /**
    137   * Marks that we're currently in the middle of processing user input.
    138   * Called by EventDispatcher when it's handling an input event.
    139   */
    140  void EnterUserInputProcessing() { mUserInputProcessingCount++; }
    141  void ExitUserInputProcessing() {
    142    MOZ_ASSERT(mUserInputProcessingCount > 0);
    143    mUserInputProcessingCount--;
    144  }
    145 
    146  /**
    147   * "Early Runner" runnables will be called as the first step when refresh
    148   * driver tick is triggered. Runners shouldn't keep other objects alive,
    149   * since it isn't guaranteed they will ever get called.
    150   */
    151  void AddEarlyRunner(nsIRunnable* aRunnable) {
    152    mEarlyRunners.AppendElement(aRunnable);
    153    EnsureTimerStarted();
    154  }
    155 
    156  // Remember whether our presshell's view manager needs a flush
    157  void SchedulePaint();
    158  bool IsPaintPending() const {
    159    return mRenderingPhasesNeeded.contains(mozilla::RenderingPhase::Paint);
    160  }
    161 
    162  // Returns true if a paint actually occurred.
    163  MOZ_CAN_RUN_SCRIPT bool PaintIfNeeded();
    164 
    165  /**
    166   * Schedule a frame visibility update "soon", subject to the heuristics and
    167   * throttling we apply to visibility updates.
    168   */
    169  void ScheduleFrameVisibilityUpdate() { mNeedToRecomputeVisibility = true; }
    170 
    171  /**
    172   * Tell the refresh driver that it is done driving refreshes and
    173   * should stop its timer and forget about its pres context.  This may
    174   * be called from within a refresh.
    175   */
    176  void Disconnect();
    177 
    178  bool IsFrozen() const { return mFreezeCount > 0; }
    179 
    180  bool IsThrottled() const { return mThrottled; }
    181 
    182  /**
    183   * Freeze the refresh driver.  It should stop delivering future
    184   * refreshes until thawed. Note that the number of calls to Freeze() must
    185   * match the number of calls to Thaw() in order for the refresh driver to
    186   * be un-frozen.
    187   */
    188  void Freeze();
    189 
    190  /**
    191   * Thaw the refresh driver.  If the number of calls to Freeze() matches the
    192   * number of calls to this function, the refresh driver should start
    193   * delivering refreshes again.
    194   */
    195  void Thaw();
    196 
    197  /**
    198   * Throttle or unthrottle the refresh driver.  This is done if the
    199   * corresponding presshell is hidden or shown.
    200   */
    201  void SetActivity(bool aIsActive);
    202 
    203  /**
    204   * Return the prescontext we were initialized with
    205   */
    206  nsPresContext* GetPresContext() const;
    207 
    208  void CreateVsyncRefreshTimer();
    209 
    210 #ifdef DEBUG
    211  /**
    212   * Check whether the given observer is an observer for the given flush type
    213   */
    214  bool IsRefreshObserver(nsARefreshObserver* aObserver,
    215                         mozilla::FlushType aFlushType);
    216 #endif
    217 
    218  /**
    219   * Default interval the refresh driver uses, in ms.
    220   */
    221  static int32_t DefaultInterval();
    222 
    223  /**
    224   * Returns 1.0 if a recent rate wasn't smaller than
    225   * DefaultInterval(). Otherwise return rate / DefaultInterval();
    226   * So the return value is (0-1].
    227   *
    228   */
    229  static double HighRateMultiplier();
    230 
    231  bool IsInRefresh() { return mInRefresh; }
    232 
    233  void SetIsResizeSuppressed() { mResizeSuppressed = true; }
    234  bool IsResizeSuppressed() const { return mResizeSuppressed; }
    235 
    236  // mozilla::layers::TransactionIdAllocator
    237  TransactionId GetTransactionId(bool aThrottle) override;
    238  TransactionId LastTransactionId() const override;
    239  void NotifyTransactionCompleted(TransactionId aTransactionId) override;
    240  void RevokeTransactionId(TransactionId aTransactionId) override;
    241  void ClearPendingTransactions() override;
    242  void ResetInitialTransactionId(TransactionId aTransactionId) override;
    243  mozilla::TimeStamp GetTransactionStart() override;
    244  mozilla::VsyncId GetVsyncId() override;
    245  mozilla::TimeStamp GetVsyncStart() override;
    246 
    247  bool IsWaitingForPaint(mozilla::TimeStamp aTime);
    248  void ScheduleAutoFocusFlush() {
    249    ScheduleRenderingPhase(mozilla::RenderingPhase::FlushAutoFocusCandidates);
    250  }
    251 
    252  // nsARefreshObserver
    253  NS_IMETHOD_(MozExternalRefCountType) AddRef(void) override {
    254    return TransactionIdAllocator::AddRef();
    255  }
    256  NS_IMETHOD_(MozExternalRefCountType) Release(void) override {
    257    return TransactionIdAllocator::Release();
    258  }
    259  virtual void WillRefresh(mozilla::TimeStamp aTime) override;
    260 
    261  /**
    262   * Compute the time when the currently active refresh driver timer
    263   * will start its next tick.
    264   *
    265   * Expects a non-null default value that is the upper bound of the
    266   * expected deadline. If the next expected deadline is later than
    267   * the default value, the default value is returned.
    268   *
    269   * If we're animating and we have skipped paints a time in the past
    270   * is returned.
    271   *
    272   * If aCheckType is AllVsyncListeners and we're in the parent process,
    273   * which doesn't have a RefreshDriver ticking, but some other process does
    274   * have, the return value is
    275   * (now + refreshrate - layout.idle_period.time_limit) as an approximation
    276   * when something will happen.
    277   * This can be useful check when parent process tries to avoid having too
    278   * long idle periods for example when it is sending input events to an
    279   * active child process.
    280   */
    281  enum IdleCheck { OnlyThisProcessRefreshDriver, AllVsyncListeners };
    282  static mozilla::TimeStamp GetIdleDeadlineHint(mozilla::TimeStamp aDefault,
    283                                                IdleCheck aCheckType);
    284 
    285  /**
    286   * It returns the expected timestamp of the next tick or nothing if the next
    287   * tick is missed.
    288   */
    289  static mozilla::Maybe<mozilla::TimeStamp> GetNextTickHint();
    290 
    291  static bool IsRegularRateTimerTicking();
    292 
    293  static void DispatchIdleTaskAfterTickUnlessExists(mozilla::Task* aTask);
    294  static void CancelIdleTask(mozilla::Task* aTask);
    295 
    296  void InitializeTimer() {
    297    MOZ_ASSERT(!mActiveTimer);
    298    EnsureTimerStarted();
    299  }
    300 
    301  bool HasPendingTick() const { return mActiveTimer; }
    302 
    303  void ScheduleRenderingPhases(mozilla::RenderingPhases aPhases) {
    304    mRenderingPhasesNeeded += aPhases;
    305    EnsureTimerStarted();
    306  }
    307 
    308  void ScheduleRenderingPhase(mozilla::RenderingPhase aPhase) {
    309    ScheduleRenderingPhases({aPhase});
    310  }
    311 
    312  void EnsureIntersectionObservationsUpdateHappens() {
    313    // This is enough to make sure that UpdateIntersectionObservations runs at
    314    // least once. This is presumably the intent of step 5 in [1]:
    315    //
    316    //     Schedule an iteration of the event loop in the root's browsing
    317    //     context.
    318    //
    319    // Though the wording of it is not quite clear to me...
    320    //
    321    // [1]:
    322    // https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-observe
    323    ScheduleRenderingPhase(
    324        mozilla::RenderingPhase::UpdateIntersectionObservations);
    325  }
    326 
    327  void EnsureViewTransitionOperationsHappen() {
    328    ScheduleRenderingPhase(mozilla::RenderingPhase::ViewTransitionOperations);
    329  }
    330 
    331  void EnsureAnimationUpdate() {
    332    ScheduleRenderingPhase(
    333        mozilla::RenderingPhase::UpdateAnimationsAndSendEvents);
    334  }
    335 
    336  void ScheduleMediaQueryListenerUpdate() {
    337    ScheduleRenderingPhase(
    338        mozilla::RenderingPhase::EvaluateMediaQueriesAndReportChanges);
    339  }
    340 
    341  // Register a composition payload that will be forwarded to the layer manager
    342  // if the current or upcoming refresh tick does a paint.
    343  // If no paint happens, the payload is discarded.
    344  // Should only be called on root refresh drivers.
    345  void RegisterCompositionPayload(
    346      const mozilla::layers::CompositionPayload& aPayload);
    347 
    348  enum class TickReasons : uint32_t {
    349    None = 0,
    350    HasObservers = 1 << 0,
    351    HasImageAnimations = 1 << 1,
    352    HasPendingRenderingSteps = 1 << 2,
    353    RootNeedsMoreTicksForUserInput = 1 << 3,
    354  };
    355 
    356  void AddForceNotifyContentfulPaintPresContext(nsPresContext* aPresContext);
    357  void FlushForceNotifyContentfulPaintPresContext();
    358 
    359  // Mark that we've just run a tick from vsync, used to throttle 'extra'
    360  // paints to one per vsync (see CanDoExtraTick).
    361  void FinishedVsyncTick() { mAttemptedExtraTickSinceLastVsync = false; }
    362 
    363 private:
    364  using RequestTable = nsTHashSet<RefPtr<imgIRequest>>;
    365  struct ImageStartData {
    366    ImageStartData() = default;
    367 
    368    mozilla::Maybe<mozilla::TimeStamp> mStartTime;
    369    RequestTable mEntries;
    370  };
    371  using ImageStartTable = nsClassHashtable<nsUint32HashKey, ImageStartData>;
    372 
    373  struct ObserverData {
    374    nsARefreshObserver* mObserver;
    375    const char* mDescription;
    376    mozilla::TimeStamp mRegisterTime;
    377    mozilla::MarkerInnerWindowId mInnerWindowId;
    378    mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> mCause;
    379    mozilla::FlushType mFlushType;
    380 
    381    bool operator==(nsARefreshObserver* aObserver) const {
    382      return mObserver == aObserver;
    383    }
    384    operator RefPtr<nsARefreshObserver>() { return mObserver; }
    385  };
    386  using ObserverArray = nsTObserverArray<ObserverData>;
    387  void RunFullscreenSteps();
    388 
    389  MOZ_CAN_RUN_SCRIPT
    390  void RunVideoAndFrameRequestCallbacks(mozilla::TimeStamp aNowTime);
    391  MOZ_CAN_RUN_SCRIPT
    392  void RunVideoFrameCallbacks(const nsTArray<RefPtr<Document>>&,
    393                              mozilla::TimeStamp aNowTime);
    394  MOZ_CAN_RUN_SCRIPT
    395  void RunFrameRequestCallbacks(const nsTArray<RefPtr<Document>>&,
    396                                mozilla::TimeStamp aNowTime);
    397  void UpdateRemoteFrameEffects();
    398  void UpdateRelevancyOfContentVisibilityAutoFrames();
    399  MOZ_CAN_RUN_SCRIPT void PerformPendingViewTransitionOperations();
    400  void MaybeIncreaseMeasuredTicksSinceLoading();
    401  void EvaluateMediaQueriesAndReportChanges();
    402 
    403  enum class IsExtraTick {
    404    No,
    405    Yes,
    406  };
    407 
    408  // Helper for Tick, to call WillRefresh(aNowTime) on each entry in
    409  // mObservers[aIdx] and then potentially do some additional post-notification
    410  // work that's associated with the FlushType corresponding to aIdx.
    411  //
    412  // Returns true on success, or false if one of our calls has destroyed our
    413  // pres context (in which case our callsite Tick() should immediately bail).
    414  MOZ_CAN_RUN_SCRIPT
    415  bool TickObserverArray(uint32_t aIdx, mozilla::TimeStamp aNowTime);
    416 
    417  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    418  void Tick(mozilla::VsyncId aId, mozilla::TimeStamp aNowTime,
    419            IsExtraTick aIsExtraTick = IsExtraTick::No);
    420 
    421  enum EnsureTimerStartedFlags {
    422    eNone = 0,
    423    eForceAdjustTimer = 1 << 0,
    424    eAllowTimeToGoBackwards = 1 << 1,
    425  };
    426  void EnsureTimerStarted(EnsureTimerStartedFlags aFlags = eNone);
    427  void StopTimer();
    428 
    429  void UpdateThrottledState();
    430 
    431  bool HasObservers() const;
    432  void AppendObserverDescriptionsToString(nsACString& aStr) const;
    433  // Note: This should only be called in the dtor of nsRefreshDriver.
    434  uint32_t ObserverCount() const;
    435  bool ComputeHasImageAnimations() const;
    436  bool ShouldKeepTimerRunningWhileWaitingForFirstContentfulPaint();
    437  bool ShouldKeepTimerRunningAfterPageLoad();
    438  ObserverArray& ArrayFor(mozilla::FlushType aFlushType);
    439  // Trigger a refresh immediately, if haven't been disconnected or frozen.
    440  void DoRefresh();
    441 
    442  // Starts pending image animations, and refreshes ongoing animations.
    443  void UpdateAnimatedImages(mozilla::TimeStamp aPreviousRefresh,
    444                            mozilla::TimeStamp aNowTime);
    445 
    446  bool HasReasonsToTick() const {
    447    return GetReasonsToTick() != TickReasons::None;
    448  }
    449  TickReasons GetReasonsToTick() const;
    450  void AppendTickReasonsToString(TickReasons aReasons, nsACString& aStr) const;
    451 
    452  double GetRegularTimerInterval() const;
    453  static double GetThrottledTimerInterval();
    454 
    455  static mozilla::TimeDuration GetMinRecomputeVisibilityInterval();
    456 
    457  void FinishedWaitingForTransaction();
    458 
    459  /**
    460   * Returns true if we didn't tick on the most recent vsync, but we think
    461   * we could run one now instead in order to reduce latency.
    462   */
    463  bool CanDoCatchUpTick();
    464  /**
    465   * Returns true if we think it's possible to run an repeat tick (between
    466   * vsyncs) to hopefully replace the original tick's paint on the compositor.
    467   * We allow this sometimes for tick requests coming for user input handling
    468   * to reduce latency.
    469   */
    470  bool CanDoExtraTick();
    471 
    472  bool AtPendingTransactionLimit() {
    473    return mPendingTransactions.Length() == 2;
    474  }
    475  bool TooManyPendingTransactions() {
    476    return mPendingTransactions.Length() >= 2;
    477  }
    478 
    479  mozilla::RefreshDriverTimer* ChooseTimer();
    480  mozilla::RefreshDriverTimer* mActiveTimer;
    481  RefPtr<mozilla::RefreshDriverTimer> mOwnTimer;
    482  mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> mRefreshTimerStartedCause;
    483 
    484  // nsPresContext passed in constructor and unset in Disconnect.
    485  mozilla::WeakPtr<nsPresContext> mPresContext;
    486 
    487  RefPtr<nsRefreshDriver> mRootRefresh;
    488 
    489  // The most recently allocated transaction id.
    490  TransactionId mNextTransactionId;
    491  AutoTArray<TransactionId, 3> mPendingTransactions;
    492 
    493  uint32_t mFreezeCount;
    494  uint32_t mUserInputProcessingCount = 0;
    495 
    496  // How long we wait between ticks for throttled (which generally means
    497  // non-visible) documents registered with a non-throttled refresh driver.
    498  const mozilla::TimeDuration mThrottledFrameRequestInterval;
    499 
    500  // How long we wait, at a minimum, before recomputing approximate frame
    501  // visibility information. This is a minimum because, regardless of this
    502  // interval, we only recompute visibility when we've seen a layout or style
    503  // flush since the last time we did it.
    504  const mozilla::TimeDuration mMinRecomputeVisibilityInterval;
    505 
    506  mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> mPaintCause;
    507 
    508  bool mThrottled : 1;
    509  bool mNeedToRecomputeVisibility : 1;
    510  bool mTestControllingRefreshes : 1;
    511  bool mInRefresh : 1;
    512 
    513  // True if the refresh driver is suspended waiting for transaction
    514  // id's to be returned and shouldn't do any work during Tick().
    515  bool mWaitingForTransaction : 1;
    516  // True if Tick() was skipped because of mWaitingForTransaction and
    517  // we should schedule a new Tick immediately when resumed instead
    518  // of waiting until the next interval.
    519  bool mSkippedPaints : 1;
    520 
    521  // True if view managers should delay any resize request until the
    522  // next tick by the refresh driver. This flag will be reset at the
    523  // start of every tick.
    524  bool mResizeSuppressed : 1;
    525 
    526  // True if we may need to run any frame callback.
    527  bool mNeedToRunFrameRequestCallbacks : 1;
    528 
    529  // True if we're currently within the scope of Tick() handling a normal
    530  // (timer-driven) tick.
    531  bool mInNormalTick : 1;
    532 
    533  // True if we attempted an extra tick (see CanDoExtraTick) since the last
    534  // vsync and thus shouldn't allow another.
    535  bool mAttemptedExtraTickSinceLastVsync : 1;
    536 
    537  bool mHasExceededAfterLoadTickPeriod : 1;
    538 
    539  bool mHasImageAnimations : 1;
    540 
    541  bool mHasStartedTimerAtLeastOnce : 1;
    542 
    543  mozilla::TimeStamp mMostRecentRefresh;
    544  mozilla::TimeStamp mTickStart;
    545  mozilla::VsyncId mTickVsyncId;
    546  mozilla::TimeStamp mTickVsyncTime;
    547  mozilla::TimeStamp mNextThrottledFrameRequestTick;
    548  mozilla::TimeStamp mNextRecomputeVisibilityTick;
    549  mozilla::TimeStamp mBeforeFirstContentfulPaintTimerRunningLimit;
    550 
    551  // The "Update the rendering" phases we need to run on our documents.
    552  mozilla::EnumSet<mozilla::RenderingPhase, uint16_t> mRenderingPhasesNeeded;
    553 
    554  // Runs a single update the rendering phase, at once, rather than filtering
    555  // the docs as per spec.
    556  //
    557  // TODO(emilio): This should be removed, ideally.
    558  template <typename Callback>
    559  MOZ_CAN_RUN_SCRIPT void RunRenderingPhaseLegacy(mozilla::RenderingPhase,
    560                                                  Callback&&);
    561 
    562  using DocFilter = bool (*)(const Document&);
    563 
    564  // Runs a single update the rendering phase with the callback called for each
    565  // document, as per spec.
    566  template <typename Callback>
    567  MOZ_CAN_RUN_SCRIPT void RunRenderingPhase(mozilla::RenderingPhase, Callback&&,
    568                                            DocFilter = nullptr);
    569 
    570  // separate arrays for each flush type we support
    571  ObserverArray mObservers[3];
    572  nsTArray<mozilla::layers::CompositionPayload> mCompositionPayloads;
    573  RequestTable mRequests;
    574  ImageStartTable mStartTable;
    575  AutoTArray<nsCOMPtr<nsIRunnable>, 16> mEarlyRunners;
    576  nsTObserverArray<nsAPostRefreshObserver*> mPostRefreshObservers;
    577 
    578  // nsPresContexts which `NotifyContentfulPaint` have been called,
    579  // however the corresponding paint doesn't come from a regular
    580  // rendering steps(aka tick).
    581  //
    582  // For these nsPresContexts, we invoke
    583  // `FlushForceNotifyContentfulPaintPresContext` in the next tick
    584  // to force notify contentful paint, regardless whether the tick paints
    585  // or not.
    586  nsTArray<mozilla::WeakPtr<nsPresContext>>
    587      mForceNotifyContentfulPaintPresContexts;
    588 
    589  void BeginRefreshingImages(RequestTable& aEntries,
    590                             mozilla::TimeStamp aDesired);
    591 
    592  friend class mozilla::RefreshDriverTimer;
    593 
    594  static void Shutdown();
    595 };
    596 
    597 #endif /* !defined(nsRefreshDriver_h_) */