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/. */
8 * Code to notify things that animate before a refresh, at an appropriate
9 * refresh rate. (Perhaps temporary, until replaced by compositor.)
12 #ifndef nsRefreshDriver_h_
13 #define nsRefreshDriver_h_
15 #include "mozilla/FlushType.h"
16 #include "mozilla/TimeStamp.h"
17 #include "mozilla/UniquePtr.h"
18 #include "mozilla/Vector.h"
19 #include "mozilla/WeakPtr.h"
20 #include "nsTObserverArray.h"
22 #include "nsTHashSet.h"
23 #include "nsClassHashtable.h"
24 #include "nsHashKeys.h"
25 #include "nsRefreshObservers.h"
26 #include "nsThreadUtils.h"
27 #include "mozilla/Attributes.h"
28 #include "mozilla/Maybe.h"
29 #include "mozilla/dom/VisualViewport.h"
30 #include "mozilla/layers/TransactionIdAllocator.h"
31 #include "LayersTypes.h"
33 #include "GeckoProfiler.h" // for ProfileChunkedBuffer
41 class AnimationEventDispatcher
;
42 class PendingFullscreenEvent
;
44 class RefreshDriverTimer
;
47 } // namespace mozilla
49 class nsRefreshDriver final
: public mozilla::layers::TransactionIdAllocator
,
50 public nsARefreshObserver
{
51 using Document
= mozilla::dom::Document
;
52 using TransactionId
= mozilla::layers::TransactionId
;
53 using VVPResizeEvent
=
54 mozilla::dom::VisualViewport::VisualViewportResizeEvent
;
55 using VVPScrollEvent
=
56 mozilla::dom::VisualViewport::VisualViewportScrollEvent
;
57 using LogPresShellObserver
= mozilla::LogPresShellObserver
;
60 explicit nsRefreshDriver(nsPresContext
* aPresContext
);
64 * Methods for testing, exposed via nsIDOMWindowUtils. See
65 * nsIDOMWindowUtils.advanceTimeAndRefresh for description.
67 void AdvanceTimeAndRefresh(int64_t aMilliseconds
);
68 void RestoreNormalRefresh();
70 bool IsTestControllingRefreshesEnabled() const {
71 return mTestControllingRefreshes
;
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.)
81 mozilla::TimeStamp
MostRecentRefresh(bool aEnsureTimerStarted
= true) const;
84 * Add / remove refresh observers.
85 * RemoveRefreshObserver returns true if aObserver was found.
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, FlushType::Layout, or FlushType::Display.
96 * The refresh driver does NOT own a reference to these observers;
97 * they must remove themselves before they are destroyed.
99 * The observer will be called even if there is no other activity.
101 void AddRefreshObserver(nsARefreshObserver
* aObserver
,
102 mozilla::FlushType aFlushType
,
103 const char* aObserverDescription
);
104 bool RemoveRefreshObserver(nsARefreshObserver
* aObserver
,
105 mozilla::FlushType aFlushType
);
107 * Add / remove an observer wants to know the time when the refresh driver
108 * updated the most recent refresh time due to its active timer changes.
110 void AddTimerAdjustmentObserver(nsATimerAdjustmentObserver
* aObserver
);
111 void RemoveTimerAdjustmentObserver(nsATimerAdjustmentObserver
* aObserver
);
113 void PostVisualViewportResizeEvent(VVPResizeEvent
* aResizeEvent
);
114 void DispatchVisualViewportResizeEvents();
116 void PostScrollEvent(mozilla::Runnable
* aScrollEvent
, bool aDelayed
= false);
117 void DispatchScrollEvents();
119 void PostVisualViewportScrollEvent(VVPScrollEvent
* aScrollEvent
);
120 void DispatchVisualViewportScrollEvents();
123 * Add an observer that will be called after each refresh. The caller
124 * must remove the observer before it is deleted. This does not trigger
125 * refresh driver ticks.
127 void AddPostRefreshObserver(nsAPostRefreshObserver
* aObserver
);
128 void AddPostRefreshObserver(mozilla::ManagedPostRefreshObserver
*) = delete;
129 void RemovePostRefreshObserver(nsAPostRefreshObserver
* aObserver
);
130 void RemovePostRefreshObserver(mozilla::ManagedPostRefreshObserver
*) = delete;
133 * Add/Remove imgIRequest versions of observers.
135 * These are used for hooking into the refresh driver for
136 * controlling animated images.
138 * @note The refresh driver owns a reference to these listeners.
140 * @note Technically, imgIRequest objects are not nsARefreshObservers, but
141 * for controlling animated image repaint events, we subscribe the
142 * imgIRequests to the nsRefreshDriver for notification of paint events.
144 void AddImageRequest(imgIRequest
* aRequest
);
145 void RemoveImageRequest(imgIRequest
* aRequest
);
148 * Marks that we're currently in the middle of processing user input.
149 * Called by EventDispatcher when it's handling an input event.
151 void EnterUserInputProcessing() { mUserInputProcessingCount
++; }
152 void ExitUserInputProcessing() {
153 MOZ_ASSERT(mUserInputProcessingCount
> 0);
154 mUserInputProcessingCount
--;
158 * Add / remove presshells which have pending resize event.
160 void AddResizeEventFlushObserver(mozilla::PresShell
* aPresShell
,
161 bool aDelayed
= false) {
162 MOZ_DIAGNOSTIC_ASSERT(
163 !mResizeEventFlushObservers
.Contains(aPresShell
) &&
164 !mDelayedResizeEventFlushObservers
.Contains(aPresShell
),
165 "Double-adding resize event flush observer");
167 mDelayedResizeEventFlushObservers
.AppendElement(aPresShell
);
169 mResizeEventFlushObservers
.AppendElement(aPresShell
);
170 EnsureTimerStarted();
174 void RemoveResizeEventFlushObserver(mozilla::PresShell
* aPresShell
) {
175 mResizeEventFlushObservers
.RemoveElement(aPresShell
);
176 mDelayedResizeEventFlushObservers
.RemoveElement(aPresShell
);
180 * Add / remove presshells that we should flush style and layout on
182 void AddStyleFlushObserver(mozilla::PresShell
* aPresShell
) {
183 MOZ_DIAGNOSTIC_ASSERT(!mStyleFlushObservers
.Contains(aPresShell
),
184 "Double-adding style flush observer");
185 LogPresShellObserver::LogDispatch(aPresShell
, this);
186 mStyleFlushObservers
.AppendElement(aPresShell
);
187 EnsureTimerStarted();
190 void RemoveStyleFlushObserver(mozilla::PresShell
* aPresShell
) {
191 mStyleFlushObservers
.RemoveElement(aPresShell
);
193 void AddLayoutFlushObserver(mozilla::PresShell
* aPresShell
) {
194 MOZ_DIAGNOSTIC_ASSERT(!IsLayoutFlushObserver(aPresShell
),
195 "Double-adding layout flush observer");
196 LogPresShellObserver::LogDispatch(aPresShell
, this);
197 mLayoutFlushObservers
.AppendElement(aPresShell
);
198 EnsureTimerStarted();
200 void RemoveLayoutFlushObserver(mozilla::PresShell
* aPresShell
) {
201 mLayoutFlushObservers
.RemoveElement(aPresShell
);
204 bool IsLayoutFlushObserver(mozilla::PresShell
* aPresShell
) {
205 return mLayoutFlushObservers
.Contains(aPresShell
);
209 * "Early Runner" runnables will be called as the first step when refresh
210 * driver tick is triggered. Runners shouldn't keep other objects alive,
211 * since it isn't guaranteed they will ever get called.
213 void AddEarlyRunner(nsIRunnable
* aRunnable
) {
214 mEarlyRunners
.AppendElement(aRunnable
);
215 EnsureTimerStarted();
219 * Remember whether our presshell's view manager needs a flush
221 void ScheduleViewManagerFlush();
222 void RevokeViewManagerFlush() { mViewManagerFlushIsPending
= false; }
223 bool ViewManagerFlushIsPending() { return mViewManagerFlushIsPending
; }
224 bool HasScheduleFlush() { return mHasScheduleFlush
; }
225 void ClearHasScheduleFlush() { mHasScheduleFlush
= false; }
228 * Add a document for which we have FrameRequestCallbacks
230 void ScheduleFrameRequestCallbacks(Document
* aDocument
);
233 * Remove a document for which we have FrameRequestCallbacks
235 void RevokeFrameRequestCallbacks(Document
* aDocument
);
238 * Queue a new fullscreen event to be dispatched in next tick before
241 void ScheduleFullscreenEvent(
242 mozilla::UniquePtr
<mozilla::PendingFullscreenEvent
> aEvent
);
245 * Cancel all pending fullscreen events scheduled by ScheduleFullscreenEvent
246 * which targets any node in aDocument.
248 void CancelPendingFullscreenEvents(Document
* aDocument
);
251 * Queue new animation events to dispatch in next tick.
253 void ScheduleAnimationEventDispatch(
254 mozilla::AnimationEventDispatcher
* aDispatcher
) {
255 NS_ASSERTION(!mAnimationEventFlushObservers
.Contains(aDispatcher
),
256 "Double-adding animation event flush observer");
257 mAnimationEventFlushObservers
.AppendElement(aDispatcher
);
258 EnsureTimerStarted();
262 * Cancel all pending animation events associated with |aDispatcher|.
264 void CancelPendingAnimationEvents(
265 mozilla::AnimationEventDispatcher
* aDispatcher
);
268 * Schedule a frame visibility update "soon", subject to the heuristics and
269 * throttling we apply to visibility updates.
271 void ScheduleFrameVisibilityUpdate() { mNeedToRecomputeVisibility
= true; }
274 * Tell the refresh driver that it is done driving refreshes and
275 * should stop its timer and forget about its pres context. This may
276 * be called from within a refresh.
280 bool IsFrozen() const { return mFreezeCount
> 0; }
282 bool IsThrottled() const { return mThrottled
; }
285 * Freeze the refresh driver. It should stop delivering future
286 * refreshes until thawed. Note that the number of calls to Freeze() must
287 * match the number of calls to Thaw() in order for the refresh driver to
293 * Thaw the refresh driver. If the number of calls to Freeze() matches the
294 * number of calls to this function, the refresh driver should start
295 * delivering refreshes again.
300 * Throttle or unthrottle the refresh driver. This is done if the
301 * corresponding presshell is hidden or shown.
303 void SetActivity(bool aIsActive
);
306 * Return the prescontext we were initialized with
308 nsPresContext
* GetPresContext() const;
310 void CreateVsyncRefreshTimer();
314 * Check whether the given observer is an observer for the given flush type
316 bool IsRefreshObserver(nsARefreshObserver
* aObserver
,
317 mozilla::FlushType aFlushType
);
321 * Default interval the refresh driver uses, in ms.
323 static int32_t DefaultInterval();
326 * Returns true if a recent vsync interval has been less than a half of
329 static bool IsInHighRateMode();
331 bool IsInRefresh() { return mInRefresh
; }
333 void SetIsResizeSuppressed() { mResizeSuppressed
= true; }
334 bool IsResizeSuppressed() const { return mResizeSuppressed
; }
336 // mozilla::layers::TransactionIdAllocator
337 TransactionId
GetTransactionId(bool aThrottle
) override
;
338 TransactionId
LastTransactionId() const override
;
339 void NotifyTransactionCompleted(TransactionId aTransactionId
) override
;
340 void RevokeTransactionId(TransactionId aTransactionId
) override
;
341 void ClearPendingTransactions() override
;
342 void ResetInitialTransactionId(TransactionId aTransactionId
) override
;
343 mozilla::TimeStamp
GetTransactionStart() override
;
344 mozilla::VsyncId
GetVsyncId() override
;
345 mozilla::TimeStamp
GetVsyncStart() override
;
347 bool IsWaitingForPaint(mozilla::TimeStamp aTime
);
349 void ScheduleAutoFocusFlush(Document
* aDocument
);
351 // nsARefreshObserver
352 NS_IMETHOD_(MozExternalRefCountType
) AddRef(void) override
{
353 return TransactionIdAllocator::AddRef();
355 NS_IMETHOD_(MozExternalRefCountType
) Release(void) override
{
356 return TransactionIdAllocator::Release();
358 virtual void WillRefresh(mozilla::TimeStamp aTime
) override
;
361 * Compute the time when the currently active refresh driver timer
362 * will start its next tick.
364 * Expects a non-null default value that is the upper bound of the
365 * expected deadline. If the next expected deadline is later than
366 * the default value, the default value is returned.
368 * If we're animating and we have skipped paints a time in the past
371 * If aCheckType is AllVsyncListeners and we're in the parent process,
372 * which doesn't have a RefreshDriver ticking, but some other process does
373 * have, the return value is
374 * (now + refreshrate - layout.idle_period.time_limit) as an approximation
375 * when something will happen.
376 * This can be useful check when parent process tries to avoid having too
377 * long idle periods for example when it is sending input events to an
378 * active child process.
380 enum IdleCheck
{ OnlyThisProcessRefreshDriver
, AllVsyncListeners
};
381 static mozilla::TimeStamp
GetIdleDeadlineHint(mozilla::TimeStamp aDefault
,
382 IdleCheck aCheckType
);
385 * It returns the expected timestamp of the next tick or nothing if the next
388 static mozilla::Maybe
<mozilla::TimeStamp
> GetNextTickHint();
390 static bool IsRegularRateTimerTicking();
392 static void DispatchIdleTaskAfterTickUnlessExists(mozilla::Task
* aTask
);
393 static void CancelIdleTask(mozilla::Task
* aTask
);
395 void NotifyDOMContentLoaded();
397 // Schedule a refresh so that any delayed events will run soon.
398 void RunDelayedEventsSoon();
400 void InitializeTimer() {
401 MOZ_ASSERT(!mActiveTimer
);
402 EnsureTimerStarted();
405 bool HasPendingTick() const { return mActiveTimer
; }
407 void EnsureIntersectionObservationsUpdateHappens() {
408 // This is enough to make sure that UpdateIntersectionObservations runs at
409 // least once. This is presumably the intent of step 5 in [1]:
411 // Schedule an iteration of the event loop in the root's browsing
414 // Though the wording of it is not quite clear to me...
417 // https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-observe
418 EnsureTimerStarted();
419 mNeedToUpdateIntersectionObservations
= true;
422 void EnsureResizeObserverUpdateHappens() {
423 EnsureTimerStarted();
424 mNeedToUpdateResizeObservers
= true;
427 void ScheduleMediaQueryListenerUpdate() {
428 EnsureTimerStarted();
429 mMightNeedMediaQueryListenerUpdate
= true;
432 void EnsureContentRelevancyUpdateHappens() {
433 EnsureTimerStarted();
434 mNeedToUpdateContentRelevancy
= true;
437 // Register a composition payload that will be forwarded to the layer manager
438 // if the current or upcoming refresh tick does a paint.
439 // If no paint happens, the payload is discarded.
440 // Should only be called on root refresh drivers.
441 void RegisterCompositionPayload(
442 const mozilla::layers::CompositionPayload
& aPayload
);
444 enum class TickReasons
: uint32_t {
446 eHasObservers
= 1 << 0,
447 eHasImageRequests
= 1 << 1,
448 eNeedsToUpdateIntersectionObservations
= 1 << 2,
449 eNeedsToUpdateContentRelevancy
= 1 << 3,
450 eHasVisualViewportResizeEvents
= 1 << 4,
451 eHasScrollEvents
= 1 << 5,
452 eHasVisualViewportScrollEvents
= 1 << 6,
453 eHasPendingMediaQueryListeners
= 1 << 7,
454 eNeedsToNotifyResizeObservers
= 1 << 8,
455 eRootNeedsMoreTicksForUserInput
= 1 << 9,
458 void AddForceNotifyContentfulPaintPresContext(nsPresContext
* aPresContext
);
459 void FlushForceNotifyContentfulPaintPresContext();
461 // Mark that we've just run a tick from vsync, used to throttle 'extra'
462 // paints to one per vsync (see CanDoExtraTick).
463 void FinishedVsyncTick() { mAttemptedExtraTickSinceLastVsync
= false; }
465 void CancelFlushAutoFocus(Document
* aDocument
);
468 typedef nsTArray
<RefPtr
<VVPResizeEvent
>> VisualViewportResizeEventArray
;
469 typedef nsTArray
<RefPtr
<mozilla::Runnable
>> ScrollEventArray
;
470 typedef nsTArray
<RefPtr
<VVPScrollEvent
>> VisualViewportScrollEventArray
;
471 using RequestTable
= nsTHashSet
<RefPtr
<imgIRequest
>>;
472 struct ImageStartData
{
473 ImageStartData() = default;
475 mozilla::Maybe
<mozilla::TimeStamp
> mStartTime
;
476 RequestTable mEntries
;
478 typedef nsClassHashtable
<nsUint32HashKey
, ImageStartData
> ImageStartTable
;
480 struct ObserverData
{
481 nsARefreshObserver
* mObserver
;
482 const char* mDescription
;
483 mozilla::TimeStamp mRegisterTime
;
484 mozilla::MarkerInnerWindowId mInnerWindowId
;
485 mozilla::UniquePtr
<mozilla::ProfileChunkedBuffer
> mCause
;
486 mozilla::FlushType mFlushType
;
488 bool operator==(nsARefreshObserver
* aObserver
) const {
489 return mObserver
== aObserver
;
491 operator RefPtr
<nsARefreshObserver
>() { return mObserver
; }
493 using ObserverArray
= nsTObserverArray
<ObserverData
>;
495 void FlushAutoFocusDocuments();
496 void RunFullscreenSteps();
497 void DispatchAnimationEvents();
499 void RunFrameRequestCallbacks(mozilla::TimeStamp aNowTime
);
500 void UpdateIntersectionObservations(mozilla::TimeStamp aNowTime
);
501 void UpdateRelevancyOfContentVisibilityAutoFrames();
502 MOZ_CAN_RUN_SCRIPT
void NotifyResizeObservers();
503 void MaybeIncreaseMeasuredTicksSinceLoading();
504 void EvaluateMediaQueriesAndReportChanges();
506 enum class IsExtraTick
{
511 // Helper for Tick, to call WillRefresh(aNowTime) on each entry in
512 // mObservers[aIdx] and then potentially do some additional post-notification
513 // work that's associated with the FlushType corresponding to aIdx.
515 // Returns true on success, or false if one of our calls has destroyed our
516 // pres context (in which case our callsite Tick() should immediately bail).
518 bool TickObserverArray(uint32_t aIdx
, mozilla::TimeStamp aNowTime
);
520 MOZ_CAN_RUN_SCRIPT_BOUNDARY
521 void Tick(mozilla::VsyncId aId
, mozilla::TimeStamp aNowTime
,
522 IsExtraTick aIsExtraTick
= IsExtraTick::No
);
524 enum EnsureTimerStartedFlags
{
526 eForceAdjustTimer
= 1 << 0,
527 eAllowTimeToGoBackwards
= 1 << 1,
528 eNeverAdjustTimer
= 1 << 2,
530 void EnsureTimerStarted(EnsureTimerStartedFlags aFlags
= eNone
);
533 void UpdateThrottledState();
535 bool HasObservers() const;
536 void AppendObserverDescriptionsToString(nsACString
& aStr
) const;
537 // Note: This should only be called in the dtor of nsRefreshDriver.
538 uint32_t ObserverCount() const;
539 bool HasImageRequests() const;
540 bool ShouldKeepTimerRunningWhileWaitingForFirstContentfulPaint();
541 bool ShouldKeepTimerRunningAfterPageLoad();
542 ObserverArray
& ArrayFor(mozilla::FlushType aFlushType
);
543 // Trigger a refresh immediately, if haven't been disconnected or frozen.
546 // Starts pending image animations, and refreshes ongoing animations.
547 void UpdateAnimatedImages(mozilla::TimeStamp aPreviousRefresh
,
548 mozilla::TimeStamp aNowTime
);
550 TickReasons
GetReasonsToTick() const;
551 void AppendTickReasonsToString(TickReasons aReasons
, nsACString
& aStr
) const;
553 double GetRegularTimerInterval() const;
554 static double GetThrottledTimerInterval();
556 static mozilla::TimeDuration
GetMinRecomputeVisibilityInterval();
558 bool HaveFrameRequestCallbacks() const {
559 return mFrameRequestCallbackDocs
.Length() != 0;
562 void FinishedWaitingForTransaction();
565 * Returns true if we didn't tick on the most recent vsync, but we think
566 * we could run one now instead in order to reduce latency.
568 bool CanDoCatchUpTick();
570 * Returns true if we think it's possible to run an repeat tick (between
571 * vsyncs) to hopefully replace the original tick's paint on the compositor.
572 * We allow this sometimes for tick requests coming for user input handling
575 bool CanDoExtraTick();
577 bool AtPendingTransactionLimit() {
578 return mPendingTransactions
.Length() == 2;
580 bool TooManyPendingTransactions() {
581 return mPendingTransactions
.Length() >= 2;
584 mozilla::RefreshDriverTimer
* ChooseTimer();
585 mozilla::RefreshDriverTimer
* mActiveTimer
;
586 RefPtr
<mozilla::RefreshDriverTimer
> mOwnTimer
;
587 mozilla::UniquePtr
<mozilla::ProfileChunkedBuffer
> mRefreshTimerStartedCause
;
589 // nsPresContext passed in constructor and unset in Disconnect.
590 mozilla::WeakPtr
<nsPresContext
> mPresContext
;
592 RefPtr
<nsRefreshDriver
> mRootRefresh
;
594 // The most recently allocated transaction id.
595 TransactionId mNextTransactionId
;
596 AutoTArray
<TransactionId
, 3> mPendingTransactions
;
598 uint32_t mFreezeCount
;
599 uint32_t mUserInputProcessingCount
= 0;
601 // How long we wait between ticks for throttled (which generally means
602 // non-visible) documents registered with a non-throttled refresh driver.
603 const mozilla::TimeDuration mThrottledFrameRequestInterval
;
605 // How long we wait, at a minimum, before recomputing approximate frame
606 // visibility information. This is a minimum because, regardless of this
607 // interval, we only recompute visibility when we've seen a layout or style
608 // flush since the last time we did it.
609 const mozilla::TimeDuration mMinRecomputeVisibilityInterval
;
611 mozilla::UniquePtr
<mozilla::ProfileChunkedBuffer
> mViewManagerFlushCause
;
614 bool mNeedToRecomputeVisibility
: 1;
615 bool mTestControllingRefreshes
: 1;
617 // These two fields are almost the same, the only difference is that
618 // mViewManagerFlushIsPending gets cleared right before calling
619 // ProcessPendingUpdates, and mHasScheduleFlush gets cleared right after
620 // calling ProcessPendingUpdates. It is important that mHasScheduleFlush
621 // only gets cleared after, but it's not clear if mViewManagerFlushIsPending
622 // needs to be cleared before.
623 bool mViewManagerFlushIsPending
: 1;
624 bool mHasScheduleFlush
: 1;
628 // True if the refresh driver is suspended waiting for transaction
629 // id's to be returned and shouldn't do any work during Tick().
630 bool mWaitingForTransaction
: 1;
631 // True if Tick() was skipped because of mWaitingForTransaction and
632 // we should schedule a new Tick immediately when resumed instead
633 // of waiting until the next interval.
634 bool mSkippedPaints
: 1;
636 // True if view managers should delay any resize request until the
637 // next tick by the refresh driver. This flag will be reset at the
638 // start of every tick.
639 bool mResizeSuppressed
: 1;
641 // True if the next tick should notify DOMContentFlushed.
642 bool mNotifyDOMContentFlushed
: 1;
644 // True if we need to flush in order to update intersection observations in
645 // all our documents.
646 bool mNeedToUpdateIntersectionObservations
: 1;
648 // True if we need to flush in order to update intersection observations in
649 // all our documents.
650 bool mNeedToUpdateResizeObservers
: 1;
652 // True if we might need to report media query changes in any of our
654 bool mMightNeedMediaQueryListenerUpdate
: 1;
656 // True if we need to update the relevancy of `content-visibility: auto`
657 // elements in our documents.
658 bool mNeedToUpdateContentRelevancy
: 1;
660 // True if we're currently within the scope of Tick() handling a normal
661 // (timer-driven) tick.
662 bool mInNormalTick
: 1;
664 // True if we attempted an extra tick (see CanDoExtraTick) since the last
665 // vsync and thus shouldn't allow another.
666 bool mAttemptedExtraTickSinceLastVsync
: 1;
668 bool mHasExceededAfterLoadTickPeriod
: 1;
670 bool mHasStartedTimerAtLeastOnce
: 1;
672 mozilla::TimeStamp mMostRecentRefresh
;
673 mozilla::TimeStamp mTickStart
;
674 mozilla::VsyncId mTickVsyncId
;
675 mozilla::TimeStamp mTickVsyncTime
;
676 mozilla::TimeStamp mNextThrottledFrameRequestTick
;
677 mozilla::TimeStamp mNextRecomputeVisibilityTick
;
678 mozilla::TimeStamp mBeforeFirstContentfulPaintTimerRunningLimit
;
680 // separate arrays for each flush type we support
681 ObserverArray mObservers
[4];
682 // These observers should NOT be included in HasObservers() since that method
683 // is used to determine whether or not to stop the timer, or restore it when
684 // thawing the refresh driver. On the other hand these observers are intended
685 // to be called when the timer is re-started and should not influence its
686 // starting or stopping.
687 nsTObserverArray
<nsATimerAdjustmentObserver
*> mTimerAdjustmentObservers
;
688 nsTArray
<mozilla::layers::CompositionPayload
> mCompositionPayloads
;
689 RequestTable mRequests
;
690 ImageStartTable mStartTable
;
691 AutoTArray
<nsCOMPtr
<nsIRunnable
>, 16> mEarlyRunners
;
692 VisualViewportResizeEventArray mVisualViewportResizeEvents
;
693 ScrollEventArray mScrollEvents
;
694 VisualViewportScrollEventArray mVisualViewportScrollEvents
;
696 // Scroll events on documents that might have events suppressed.
697 ScrollEventArray mDelayedScrollEvents
;
699 AutoTArray
<mozilla::PresShell
*, 16> mResizeEventFlushObservers
;
700 AutoTArray
<mozilla::PresShell
*, 16> mDelayedResizeEventFlushObservers
;
701 AutoTArray
<mozilla::PresShell
*, 16> mStyleFlushObservers
;
702 AutoTArray
<mozilla::PresShell
*, 16> mLayoutFlushObservers
;
703 // nsTArray on purpose, because we want to be able to swap.
704 nsTArray
<Document
*> mFrameRequestCallbackDocs
;
705 nsTArray
<Document
*> mThrottledFrameRequestCallbackDocs
;
706 nsTArray
<RefPtr
<Document
>> mAutoFocusFlushDocuments
;
707 nsTObserverArray
<nsAPostRefreshObserver
*> mPostRefreshObservers
;
708 nsTArray
<mozilla::UniquePtr
<mozilla::PendingFullscreenEvent
>>
709 mPendingFullscreenEvents
;
710 AutoTArray
<mozilla::AnimationEventDispatcher
*, 16>
711 mAnimationEventFlushObservers
;
713 // nsPresContexts which `NotifyContentfulPaint` have been called,
714 // however the corresponding paint doesn't come from a regular
715 // rendering steps(aka tick).
717 // For these nsPresContexts, we invoke
718 // `FlushForceNotifyContentfulPaintPresContext` in the next tick
719 // to force notify contentful paint, regardless whether the tick paints
721 nsTArray
<mozilla::WeakPtr
<nsPresContext
>>
722 mForceNotifyContentfulPaintPresContexts
;
724 void BeginRefreshingImages(RequestTable
& aEntries
,
725 mozilla::TimeStamp aDesired
);
727 friend class mozilla::RefreshDriverTimer
;
729 static void Shutdown();
732 #endif /* !defined(nsRefreshDriver_h_) */