Bug 1869043 allow a device to be specified with MediaTrackGraph::NotifyWhenDeviceStar...
[gecko.git] / layout / base / nsRefreshDriver.h
blobcd050f74313a7b89b2202b109b48bf80236f012b
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/. */
7 /*
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"
21 #include "nsTArray.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
35 class nsPresContext;
37 class imgIRequest;
38 class nsIRunnable;
40 namespace mozilla {
41 class AnimationEventDispatcher;
42 class PendingFullscreenEvent;
43 class PresShell;
44 class RefreshDriverTimer;
45 class Runnable;
46 class Task;
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;
59 public:
60 explicit nsRefreshDriver(nsPresContext* aPresContext);
61 ~nsRefreshDriver();
63 /**
64 * Methods for testing, exposed via nsIDOMWindowUtils. See
65 * nsIDOMWindowUtils.advanceTimeAndRefresh for description.
67 void AdvanceTimeAndRefresh(int64_t aMilliseconds);
68 void RestoreNormalRefresh();
69 void DoTick();
70 bool IsTestControllingRefreshesEnabled() const {
71 return mTestControllingRefreshes;
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.)
81 mozilla::TimeStamp MostRecentRefresh(bool aEnsureTimerStarted = true) const;
83 /**
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");
166 if (aDelayed) {
167 mDelayedResizeEventFlushObservers.AppendElement(aPresShell);
168 } else {
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
239 * the style flush
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.
278 void Disconnect();
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
288 * be un-frozen.
290 void Freeze();
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.
297 void Thaw();
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();
312 #ifdef DEBUG
314 * Check whether the given observer is an observer for the given flush type
316 bool IsRefreshObserver(nsARefreshObserver* aObserver,
317 mozilla::FlushType aFlushType);
318 #endif
321 * Default interval the refresh driver uses, in ms.
323 static int32_t DefaultInterval();
326 * Returns 1.0 if a recent rate wasn't smaller than
327 * DefaultInterval(). Otherwise return rate / DefaultInterval();
328 * So the return value is (0-1].
331 static double HighRateMultiplier();
333 bool IsInRefresh() { return mInRefresh; }
335 void SetIsResizeSuppressed() { mResizeSuppressed = true; }
336 bool IsResizeSuppressed() const { return mResizeSuppressed; }
338 // mozilla::layers::TransactionIdAllocator
339 TransactionId GetTransactionId(bool aThrottle) override;
340 TransactionId LastTransactionId() const override;
341 void NotifyTransactionCompleted(TransactionId aTransactionId) override;
342 void RevokeTransactionId(TransactionId aTransactionId) override;
343 void ClearPendingTransactions() override;
344 void ResetInitialTransactionId(TransactionId aTransactionId) override;
345 mozilla::TimeStamp GetTransactionStart() override;
346 mozilla::VsyncId GetVsyncId() override;
347 mozilla::TimeStamp GetVsyncStart() override;
349 bool IsWaitingForPaint(mozilla::TimeStamp aTime);
351 void ScheduleAutoFocusFlush(Document* aDocument);
353 // nsARefreshObserver
354 NS_IMETHOD_(MozExternalRefCountType) AddRef(void) override {
355 return TransactionIdAllocator::AddRef();
357 NS_IMETHOD_(MozExternalRefCountType) Release(void) override {
358 return TransactionIdAllocator::Release();
360 virtual void WillRefresh(mozilla::TimeStamp aTime) override;
363 * Compute the time when the currently active refresh driver timer
364 * will start its next tick.
366 * Expects a non-null default value that is the upper bound of the
367 * expected deadline. If the next expected deadline is later than
368 * the default value, the default value is returned.
370 * If we're animating and we have skipped paints a time in the past
371 * is returned.
373 * If aCheckType is AllVsyncListeners and we're in the parent process,
374 * which doesn't have a RefreshDriver ticking, but some other process does
375 * have, the return value is
376 * (now + refreshrate - layout.idle_period.time_limit) as an approximation
377 * when something will happen.
378 * This can be useful check when parent process tries to avoid having too
379 * long idle periods for example when it is sending input events to an
380 * active child process.
382 enum IdleCheck { OnlyThisProcessRefreshDriver, AllVsyncListeners };
383 static mozilla::TimeStamp GetIdleDeadlineHint(mozilla::TimeStamp aDefault,
384 IdleCheck aCheckType);
387 * It returns the expected timestamp of the next tick or nothing if the next
388 * tick is missed.
390 static mozilla::Maybe<mozilla::TimeStamp> GetNextTickHint();
392 static bool IsRegularRateTimerTicking();
394 static void DispatchIdleTaskAfterTickUnlessExists(mozilla::Task* aTask);
395 static void CancelIdleTask(mozilla::Task* aTask);
397 void NotifyDOMContentLoaded();
399 // Schedule a refresh so that any delayed events will run soon.
400 void RunDelayedEventsSoon();
402 void InitializeTimer() {
403 MOZ_ASSERT(!mActiveTimer);
404 EnsureTimerStarted();
407 bool HasPendingTick() const { return mActiveTimer; }
409 void EnsureIntersectionObservationsUpdateHappens() {
410 // This is enough to make sure that UpdateIntersectionObservations runs at
411 // least once. This is presumably the intent of step 5 in [1]:
413 // Schedule an iteration of the event loop in the root's browsing
414 // context.
416 // Though the wording of it is not quite clear to me...
418 // [1]:
419 // https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-observe
420 EnsureTimerStarted();
421 mNeedToUpdateIntersectionObservations = true;
424 void EnsureResizeObserverUpdateHappens() {
425 EnsureTimerStarted();
426 mNeedToUpdateResizeObservers = true;
429 void ScheduleMediaQueryListenerUpdate() {
430 EnsureTimerStarted();
431 mMightNeedMediaQueryListenerUpdate = true;
434 void EnsureContentRelevancyUpdateHappens() {
435 EnsureTimerStarted();
436 mNeedToUpdateContentRelevancy = true;
439 // Register a composition payload that will be forwarded to the layer manager
440 // if the current or upcoming refresh tick does a paint.
441 // If no paint happens, the payload is discarded.
442 // Should only be called on root refresh drivers.
443 void RegisterCompositionPayload(
444 const mozilla::layers::CompositionPayload& aPayload);
446 enum class TickReasons : uint32_t {
447 eNone = 0,
448 eHasObservers = 1 << 0,
449 eHasImageRequests = 1 << 1,
450 eNeedsToUpdateIntersectionObservations = 1 << 2,
451 eNeedsToUpdateContentRelevancy = 1 << 3,
452 eHasVisualViewportResizeEvents = 1 << 4,
453 eHasScrollEvents = 1 << 5,
454 eHasVisualViewportScrollEvents = 1 << 6,
455 eHasPendingMediaQueryListeners = 1 << 7,
456 eNeedsToNotifyResizeObservers = 1 << 8,
457 eRootNeedsMoreTicksForUserInput = 1 << 9,
460 void AddForceNotifyContentfulPaintPresContext(nsPresContext* aPresContext);
461 void FlushForceNotifyContentfulPaintPresContext();
463 // Mark that we've just run a tick from vsync, used to throttle 'extra'
464 // paints to one per vsync (see CanDoExtraTick).
465 void FinishedVsyncTick() { mAttemptedExtraTickSinceLastVsync = false; }
467 void CancelFlushAutoFocus(Document* aDocument);
469 private:
470 typedef nsTArray<RefPtr<VVPResizeEvent>> VisualViewportResizeEventArray;
471 typedef nsTArray<RefPtr<mozilla::Runnable>> ScrollEventArray;
472 typedef nsTArray<RefPtr<VVPScrollEvent>> VisualViewportScrollEventArray;
473 using RequestTable = nsTHashSet<RefPtr<imgIRequest>>;
474 struct ImageStartData {
475 ImageStartData() = default;
477 mozilla::Maybe<mozilla::TimeStamp> mStartTime;
478 RequestTable mEntries;
480 typedef nsClassHashtable<nsUint32HashKey, ImageStartData> ImageStartTable;
482 struct ObserverData {
483 nsARefreshObserver* mObserver;
484 const char* mDescription;
485 mozilla::TimeStamp mRegisterTime;
486 mozilla::MarkerInnerWindowId mInnerWindowId;
487 mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> mCause;
488 mozilla::FlushType mFlushType;
490 bool operator==(nsARefreshObserver* aObserver) const {
491 return mObserver == aObserver;
493 operator RefPtr<nsARefreshObserver>() { return mObserver; }
495 using ObserverArray = nsTObserverArray<ObserverData>;
496 MOZ_CAN_RUN_SCRIPT
497 void FlushAutoFocusDocuments();
498 void RunFullscreenSteps();
499 void DispatchAnimationEvents();
500 MOZ_CAN_RUN_SCRIPT
501 void RunFrameRequestCallbacks(mozilla::TimeStamp aNowTime);
502 void UpdateIntersectionObservations(mozilla::TimeStamp aNowTime);
503 void UpdateRelevancyOfContentVisibilityAutoFrames();
504 MOZ_CAN_RUN_SCRIPT void
505 DetermineProximityToViewportAndNotifyResizeObservers();
506 void MaybeIncreaseMeasuredTicksSinceLoading();
507 void EvaluateMediaQueriesAndReportChanges();
509 enum class IsExtraTick {
511 Yes,
514 // Helper for Tick, to call WillRefresh(aNowTime) on each entry in
515 // mObservers[aIdx] and then potentially do some additional post-notification
516 // work that's associated with the FlushType corresponding to aIdx.
518 // Returns true on success, or false if one of our calls has destroyed our
519 // pres context (in which case our callsite Tick() should immediately bail).
520 MOZ_CAN_RUN_SCRIPT
521 bool TickObserverArray(uint32_t aIdx, mozilla::TimeStamp aNowTime);
523 MOZ_CAN_RUN_SCRIPT_BOUNDARY
524 void Tick(mozilla::VsyncId aId, mozilla::TimeStamp aNowTime,
525 IsExtraTick aIsExtraTick = IsExtraTick::No);
527 enum EnsureTimerStartedFlags {
528 eNone = 0,
529 eForceAdjustTimer = 1 << 0,
530 eAllowTimeToGoBackwards = 1 << 1,
531 eNeverAdjustTimer = 1 << 2,
533 void EnsureTimerStarted(EnsureTimerStartedFlags aFlags = eNone);
534 void StopTimer();
536 void UpdateThrottledState();
538 bool HasObservers() const;
539 void AppendObserverDescriptionsToString(nsACString& aStr) const;
540 // Note: This should only be called in the dtor of nsRefreshDriver.
541 uint32_t ObserverCount() const;
542 bool HasImageRequests() const;
543 bool ShouldKeepTimerRunningWhileWaitingForFirstContentfulPaint();
544 bool ShouldKeepTimerRunningAfterPageLoad();
545 ObserverArray& ArrayFor(mozilla::FlushType aFlushType);
546 // Trigger a refresh immediately, if haven't been disconnected or frozen.
547 void DoRefresh();
549 // Starts pending image animations, and refreshes ongoing animations.
550 void UpdateAnimatedImages(mozilla::TimeStamp aPreviousRefresh,
551 mozilla::TimeStamp aNowTime);
553 TickReasons GetReasonsToTick() const;
554 void AppendTickReasonsToString(TickReasons aReasons, nsACString& aStr) const;
556 double GetRegularTimerInterval() const;
557 static double GetThrottledTimerInterval();
559 static mozilla::TimeDuration GetMinRecomputeVisibilityInterval();
561 bool HaveFrameRequestCallbacks() const {
562 return mFrameRequestCallbackDocs.Length() != 0;
565 void FinishedWaitingForTransaction();
568 * Returns true if we didn't tick on the most recent vsync, but we think
569 * we could run one now instead in order to reduce latency.
571 bool CanDoCatchUpTick();
573 * Returns true if we think it's possible to run an repeat tick (between
574 * vsyncs) to hopefully replace the original tick's paint on the compositor.
575 * We allow this sometimes for tick requests coming for user input handling
576 * to reduce latency.
578 bool CanDoExtraTick();
580 bool AtPendingTransactionLimit() {
581 return mPendingTransactions.Length() == 2;
583 bool TooManyPendingTransactions() {
584 return mPendingTransactions.Length() >= 2;
587 mozilla::RefreshDriverTimer* ChooseTimer();
588 mozilla::RefreshDriverTimer* mActiveTimer;
589 RefPtr<mozilla::RefreshDriverTimer> mOwnTimer;
590 mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> mRefreshTimerStartedCause;
592 // nsPresContext passed in constructor and unset in Disconnect.
593 mozilla::WeakPtr<nsPresContext> mPresContext;
595 RefPtr<nsRefreshDriver> mRootRefresh;
597 // The most recently allocated transaction id.
598 TransactionId mNextTransactionId;
599 AutoTArray<TransactionId, 3> mPendingTransactions;
601 uint32_t mFreezeCount;
602 uint32_t mUserInputProcessingCount = 0;
604 // How long we wait between ticks for throttled (which generally means
605 // non-visible) documents registered with a non-throttled refresh driver.
606 const mozilla::TimeDuration mThrottledFrameRequestInterval;
608 // How long we wait, at a minimum, before recomputing approximate frame
609 // visibility information. This is a minimum because, regardless of this
610 // interval, we only recompute visibility when we've seen a layout or style
611 // flush since the last time we did it.
612 const mozilla::TimeDuration mMinRecomputeVisibilityInterval;
614 mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> mViewManagerFlushCause;
616 bool mThrottled : 1;
617 bool mNeedToRecomputeVisibility : 1;
618 bool mTestControllingRefreshes : 1;
620 // These two fields are almost the same, the only difference is that
621 // mViewManagerFlushIsPending gets cleared right before calling
622 // ProcessPendingUpdates, and mHasScheduleFlush gets cleared right after
623 // calling ProcessPendingUpdates. It is important that mHasScheduleFlush
624 // only gets cleared after, but it's not clear if mViewManagerFlushIsPending
625 // needs to be cleared before.
626 bool mViewManagerFlushIsPending : 1;
627 bool mHasScheduleFlush : 1;
629 bool mInRefresh : 1;
631 // True if the refresh driver is suspended waiting for transaction
632 // id's to be returned and shouldn't do any work during Tick().
633 bool mWaitingForTransaction : 1;
634 // True if Tick() was skipped because of mWaitingForTransaction and
635 // we should schedule a new Tick immediately when resumed instead
636 // of waiting until the next interval.
637 bool mSkippedPaints : 1;
639 // True if view managers should delay any resize request until the
640 // next tick by the refresh driver. This flag will be reset at the
641 // start of every tick.
642 bool mResizeSuppressed : 1;
644 // True if the next tick should notify DOMContentFlushed.
645 bool mNotifyDOMContentFlushed : 1;
647 // True if we need to flush in order to update intersection observations in
648 // all our documents.
649 bool mNeedToUpdateIntersectionObservations : 1;
651 // True if we need to flush in order to update intersection observations in
652 // all our documents.
653 bool mNeedToUpdateResizeObservers : 1;
655 // True if we might need to report media query changes in any of our
656 // documents.
657 bool mMightNeedMediaQueryListenerUpdate : 1;
659 // True if we need to update the relevancy of `content-visibility: auto`
660 // elements in our documents.
661 bool mNeedToUpdateContentRelevancy : 1;
663 // True if we're currently within the scope of Tick() handling a normal
664 // (timer-driven) tick.
665 bool mInNormalTick : 1;
667 // True if we attempted an extra tick (see CanDoExtraTick) since the last
668 // vsync and thus shouldn't allow another.
669 bool mAttemptedExtraTickSinceLastVsync : 1;
671 bool mHasExceededAfterLoadTickPeriod : 1;
673 bool mHasStartedTimerAtLeastOnce : 1;
675 mozilla::TimeStamp mMostRecentRefresh;
676 mozilla::TimeStamp mTickStart;
677 mozilla::VsyncId mTickVsyncId;
678 mozilla::TimeStamp mTickVsyncTime;
679 mozilla::TimeStamp mNextThrottledFrameRequestTick;
680 mozilla::TimeStamp mNextRecomputeVisibilityTick;
681 mozilla::TimeStamp mBeforeFirstContentfulPaintTimerRunningLimit;
683 // separate arrays for each flush type we support
684 ObserverArray mObservers[4];
685 // These observers should NOT be included in HasObservers() since that method
686 // is used to determine whether or not to stop the timer, or restore it when
687 // thawing the refresh driver. On the other hand these observers are intended
688 // to be called when the timer is re-started and should not influence its
689 // starting or stopping.
690 nsTObserverArray<nsATimerAdjustmentObserver*> mTimerAdjustmentObservers;
691 nsTArray<mozilla::layers::CompositionPayload> mCompositionPayloads;
692 RequestTable mRequests;
693 ImageStartTable mStartTable;
694 AutoTArray<nsCOMPtr<nsIRunnable>, 16> mEarlyRunners;
695 VisualViewportResizeEventArray mVisualViewportResizeEvents;
696 ScrollEventArray mScrollEvents;
697 VisualViewportScrollEventArray mVisualViewportScrollEvents;
699 // Scroll events on documents that might have events suppressed.
700 ScrollEventArray mDelayedScrollEvents;
702 AutoTArray<mozilla::PresShell*, 16> mResizeEventFlushObservers;
703 AutoTArray<mozilla::PresShell*, 16> mDelayedResizeEventFlushObservers;
704 AutoTArray<mozilla::PresShell*, 16> mStyleFlushObservers;
705 AutoTArray<mozilla::PresShell*, 16> mLayoutFlushObservers;
706 // nsTArray on purpose, because we want to be able to swap.
707 nsTArray<Document*> mFrameRequestCallbackDocs;
708 nsTArray<Document*> mThrottledFrameRequestCallbackDocs;
709 nsTArray<RefPtr<Document>> mAutoFocusFlushDocuments;
710 nsTObserverArray<nsAPostRefreshObserver*> mPostRefreshObservers;
711 nsTArray<mozilla::UniquePtr<mozilla::PendingFullscreenEvent>>
712 mPendingFullscreenEvents;
713 AutoTArray<mozilla::AnimationEventDispatcher*, 16>
714 mAnimationEventFlushObservers;
716 // nsPresContexts which `NotifyContentfulPaint` have been called,
717 // however the corresponding paint doesn't come from a regular
718 // rendering steps(aka tick).
720 // For these nsPresContexts, we invoke
721 // `FlushForceNotifyContentfulPaintPresContext` in the next tick
722 // to force notify contentful paint, regardless whether the tick paints
723 // or not.
724 nsTArray<mozilla::WeakPtr<nsPresContext>>
725 mForceNotifyContentfulPaintPresContexts;
727 void BeginRefreshingImages(RequestTable& aEntries,
728 mozilla::TimeStamp aDesired);
730 friend class mozilla::RefreshDriverTimer;
732 static void Shutdown();
735 #endif /* !defined(nsRefreshDriver_h_) */