/work/obj-fuzz/dist/include/nsRefreshDriver.h
Line | Count | Source (jump to first uncovered line) |
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 "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 "nsTHashtable.h" |
23 | | #include "nsTObserverArray.h" |
24 | | #include "nsClassHashtable.h" |
25 | | #include "nsHashKeys.h" |
26 | | #include "mozilla/Attributes.h" |
27 | | #include "mozilla/Maybe.h" |
28 | | #include "mozilla/layers/TransactionIdAllocator.h" |
29 | | |
30 | | class nsPresContext; |
31 | | class nsIPresShell; |
32 | | class nsIDocument; |
33 | | class imgIRequest; |
34 | | class nsINode; |
35 | | class nsIRunnable; |
36 | | |
37 | | namespace mozilla { |
38 | | class AnimationEventDispatcher; |
39 | | class PendingFullscreenEvent; |
40 | | class RefreshDriverTimer; |
41 | | class Runnable; |
42 | | |
43 | | namespace layout { |
44 | | class VsyncChild; |
45 | | } // namespace layout |
46 | | |
47 | | namespace dom { |
48 | | class Event; |
49 | | } // namespace dom |
50 | | |
51 | | } // namespace mozilla |
52 | | |
53 | | /** |
54 | | * An abstract base class to be implemented by callers wanting to be |
55 | | * notified at refresh times. When nothing needs to be painted, callers |
56 | | * may not be notified. |
57 | | */ |
58 | | class nsARefreshObserver { |
59 | | public: |
60 | | // AddRef and Release signatures that match nsISupports. Implementors |
61 | | // must implement reference counting, and those that do implement |
62 | | // nsISupports will already have methods with the correct signature. |
63 | | // |
64 | | // The refresh driver does NOT hold references to refresh observers |
65 | | // except while it is notifying them. |
66 | | NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING |
67 | | |
68 | | virtual void WillRefresh(mozilla::TimeStamp aTime) = 0; |
69 | | }; |
70 | | |
71 | | /** |
72 | | * An abstract base class to be implemented by callers wanting to be notified |
73 | | * when the observing refresh driver updated mMostRecentRefresh due to active |
74 | | * timer changes. Callers must ensure an observer is removed before it is |
75 | | * destroyed. |
76 | | */ |
77 | | class nsATimerAdjustmentObserver { |
78 | | public: |
79 | | virtual void NotifyTimerAdjusted(mozilla::TimeStamp aTime) = 0; |
80 | | }; |
81 | | |
82 | | /** |
83 | | * An abstract base class to be implemented by callers wanting to be notified |
84 | | * that a refresh has occurred. Callers must ensure an observer is removed |
85 | | * before it is destroyed. |
86 | | */ |
87 | | class nsAPostRefreshObserver { |
88 | | public: |
89 | | virtual void DidRefresh() = 0; |
90 | | }; |
91 | | |
92 | | class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator, |
93 | | public nsARefreshObserver |
94 | | { |
95 | | using TransactionId = mozilla::layers::TransactionId; |
96 | | |
97 | | public: |
98 | | explicit nsRefreshDriver(nsPresContext *aPresContext); |
99 | | ~nsRefreshDriver(); |
100 | | |
101 | | /** |
102 | | * Methods for testing, exposed via nsIDOMWindowUtils. See |
103 | | * nsIDOMWindowUtils.advanceTimeAndRefresh for description. |
104 | | */ |
105 | | void AdvanceTimeAndRefresh(int64_t aMilliseconds); |
106 | | void RestoreNormalRefresh(); |
107 | | void DoTick(); |
108 | | bool IsTestControllingRefreshesEnabled() const |
109 | | { |
110 | | return mTestControllingRefreshes; |
111 | | } |
112 | | |
113 | | /** |
114 | | * Return the time of the most recent refresh. This is intended to be |
115 | | * used by callers who want to start an animation now and want to know |
116 | | * what time to consider the start of the animation. (This helps |
117 | | * ensure that multiple animations started during the same event off |
118 | | * the main event loop have the same start time.) |
119 | | */ |
120 | | mozilla::TimeStamp MostRecentRefresh() const; |
121 | | |
122 | | /** |
123 | | * Add / remove refresh observers. Returns whether the operation |
124 | | * succeeded. |
125 | | * |
126 | | * The flush type affects: |
127 | | * + the order in which the observers are notified (lowest flush |
128 | | * type to highest, in order registered) |
129 | | * + (in the future) which observers are suppressed when the display |
130 | | * doesn't require current position data or isn't currently |
131 | | * painting, and, correspondingly, which get notified when there |
132 | | * is a flush during such suppression |
133 | | * and it must be FlushType::Style, FlushType::Layout, or FlushType::Display. |
134 | | * |
135 | | * The refresh driver does NOT own a reference to these observers; |
136 | | * they must remove themselves before they are destroyed. |
137 | | * |
138 | | * The observer will be called even if there is no other activity. |
139 | | */ |
140 | | bool AddRefreshObserver(nsARefreshObserver *aObserver, |
141 | | mozilla::FlushType aFlushType); |
142 | | bool RemoveRefreshObserver(nsARefreshObserver *aObserver, |
143 | | mozilla::FlushType aFlushType); |
144 | | /** |
145 | | * Add / remove an observer wants to know the time when the refresh driver |
146 | | * updated the most recent refresh time due to its active timer changes. |
147 | | */ |
148 | | bool AddTimerAdjustmentObserver(nsATimerAdjustmentObserver *aObserver); |
149 | | bool RemoveTimerAdjustmentObserver(nsATimerAdjustmentObserver *aObserver); |
150 | | |
151 | | void PostScrollEvent(mozilla::Runnable* aScrollEvent); |
152 | | void DispatchScrollEvents(); |
153 | | |
154 | | /** |
155 | | * Add an observer that will be called after each refresh. The caller |
156 | | * must remove the observer before it is deleted. This does not trigger |
157 | | * refresh driver ticks. |
158 | | */ |
159 | | void AddPostRefreshObserver(nsAPostRefreshObserver *aObserver); |
160 | | void RemovePostRefreshObserver(nsAPostRefreshObserver *aObserver); |
161 | | |
162 | | /** |
163 | | * Add/Remove imgIRequest versions of observers. |
164 | | * |
165 | | * These are used for hooking into the refresh driver for |
166 | | * controlling animated images. |
167 | | * |
168 | | * @note The refresh driver owns a reference to these listeners. |
169 | | * |
170 | | * @note Technically, imgIRequest objects are not nsARefreshObservers, but |
171 | | * for controlling animated image repaint events, we subscribe the |
172 | | * imgIRequests to the nsRefreshDriver for notification of paint events. |
173 | | * |
174 | | * @returns whether the operation succeeded, or void in the case of removal. |
175 | | */ |
176 | | bool AddImageRequest(imgIRequest* aRequest); |
177 | | void RemoveImageRequest(imgIRequest* aRequest); |
178 | | |
179 | | /** |
180 | | * Add / remove presshells which have pending resize event. |
181 | | */ |
182 | | void AddResizeEventFlushObserver(nsIPresShell* aShell) |
183 | 0 | { |
184 | 0 | MOZ_DIAGNOSTIC_ASSERT(!mResizeEventFlushObservers.Contains(aShell), |
185 | 0 | "Double-adding resize event flush observer"); |
186 | 0 | mResizeEventFlushObservers.AppendElement(aShell); |
187 | 0 | EnsureTimerStarted(); |
188 | 0 | } |
189 | | |
190 | | void RemoveResizeEventFlushObserver(nsIPresShell* aShell) |
191 | 0 | { |
192 | 0 | mResizeEventFlushObservers.RemoveElement(aShell); |
193 | 0 | } |
194 | | |
195 | | /** |
196 | | * Add / remove presshells that we should flush style and layout on |
197 | | */ |
198 | | void AddStyleFlushObserver(nsIPresShell* aShell) |
199 | 0 | { |
200 | 0 | MOZ_DIAGNOSTIC_ASSERT(!mStyleFlushObservers.Contains(aShell), |
201 | 0 | "Double-adding style flush observer"); |
202 | 0 | mStyleFlushObservers.AppendElement(aShell); |
203 | 0 | EnsureTimerStarted(); |
204 | 0 | } |
205 | | |
206 | | void RemoveStyleFlushObserver(nsIPresShell* aShell) |
207 | 0 | { |
208 | 0 | mStyleFlushObservers.RemoveElement(aShell); |
209 | 0 | } |
210 | | void AddLayoutFlushObserver(nsIPresShell* aShell) |
211 | 0 | { |
212 | 0 | MOZ_DIAGNOSTIC_ASSERT(!IsLayoutFlushObserver(aShell), |
213 | 0 | "Double-adding layout flush observer"); |
214 | 0 | mLayoutFlushObservers.AppendElement(aShell); |
215 | 0 | EnsureTimerStarted(); |
216 | 0 | } |
217 | | void RemoveLayoutFlushObserver(nsIPresShell* aShell) |
218 | 0 | { |
219 | 0 | mLayoutFlushObservers.RemoveElement(aShell); |
220 | 0 | } |
221 | | |
222 | | bool IsLayoutFlushObserver(nsIPresShell* aShell) |
223 | 0 | { |
224 | 0 | return mLayoutFlushObservers.Contains(aShell); |
225 | 0 | } |
226 | | |
227 | | /** |
228 | | * "Early Runner" runnables will be called as the first step when refresh |
229 | | * driver tick is triggered. Runners shouldn't keep other objects alive, |
230 | | * since it isn't guaranteed they will ever get called. |
231 | | */ |
232 | | void AddEarlyRunner(nsIRunnable* aRunnable) |
233 | | { |
234 | | mEarlyRunners.AppendElement(aRunnable); |
235 | | EnsureTimerStarted(); |
236 | | } |
237 | | |
238 | | /** |
239 | | * Remember whether our presshell's view manager needs a flush |
240 | | */ |
241 | | void ScheduleViewManagerFlush(); |
242 | 0 | void RevokeViewManagerFlush() { |
243 | 0 | mViewManagerFlushIsPending = false; |
244 | 0 | } |
245 | 0 | bool ViewManagerFlushIsPending() { |
246 | 0 | return mViewManagerFlushIsPending; |
247 | 0 | } |
248 | | bool HasScheduleFlush() { |
249 | | return mHasScheduleFlush; |
250 | | } |
251 | | |
252 | | /** |
253 | | * Add a document for which we have FrameRequestCallbacks |
254 | | */ |
255 | | void ScheduleFrameRequestCallbacks(nsIDocument* aDocument); |
256 | | |
257 | | /** |
258 | | * Remove a document for which we have FrameRequestCallbacks |
259 | | */ |
260 | | void RevokeFrameRequestCallbacks(nsIDocument* aDocument); |
261 | | |
262 | | /** |
263 | | * Queue a new fullscreen event to be dispatched in next tick before |
264 | | * the style flush |
265 | | */ |
266 | | void ScheduleFullscreenEvent( |
267 | | mozilla::UniquePtr<mozilla::PendingFullscreenEvent> aEvent); |
268 | | |
269 | | /** |
270 | | * Cancel all pending fullscreen events scheduled by ScheduleFullscreenEvent |
271 | | * which targets any node in aDocument. |
272 | | */ |
273 | | void CancelPendingFullscreenEvents(nsIDocument* aDocument); |
274 | | |
275 | | /** |
276 | | * Queue new animation events to dispatch in next tick. |
277 | | */ |
278 | | void ScheduleAnimationEventDispatch( |
279 | | mozilla::AnimationEventDispatcher* aDispatcher) |
280 | | { |
281 | | NS_ASSERTION(!mAnimationEventFlushObservers.Contains(aDispatcher), |
282 | | "Double-adding animation event flush observer"); |
283 | | mAnimationEventFlushObservers.AppendElement(aDispatcher); |
284 | | EnsureTimerStarted(); |
285 | | } |
286 | | |
287 | | /** |
288 | | * Cancel all pending animation events associated with |aDispatcher|. |
289 | | */ |
290 | | void CancelPendingAnimationEvents( |
291 | | mozilla::AnimationEventDispatcher* aDispatcher); |
292 | | |
293 | | /** |
294 | | * Schedule a frame visibility update "soon", subject to the heuristics and |
295 | | * throttling we apply to visibility updates. |
296 | | */ |
297 | 0 | void ScheduleFrameVisibilityUpdate() { mNeedToRecomputeVisibility = true; } |
298 | | |
299 | | /** |
300 | | * Tell the refresh driver that it is done driving refreshes and |
301 | | * should stop its timer and forget about its pres context. This may |
302 | | * be called from within a refresh. |
303 | | */ |
304 | | void Disconnect(); |
305 | | |
306 | | bool IsFrozen() { return mFreezeCount > 0; } |
307 | | |
308 | | /** |
309 | | * Freeze the refresh driver. It should stop delivering future |
310 | | * refreshes until thawed. Note that the number of calls to Freeze() must |
311 | | * match the number of calls to Thaw() in order for the refresh driver to |
312 | | * be un-frozen. |
313 | | */ |
314 | | void Freeze(); |
315 | | |
316 | | /** |
317 | | * Thaw the refresh driver. If the number of calls to Freeze() matches the |
318 | | * number of calls to this function, the refresh driver should start |
319 | | * delivering refreshes again. |
320 | | */ |
321 | | void Thaw(); |
322 | | |
323 | | /** |
324 | | * Throttle or unthrottle the refresh driver. This is done if the |
325 | | * corresponding presshell is hidden or shown. |
326 | | */ |
327 | | void SetThrottled(bool aThrottled); |
328 | | |
329 | | /** |
330 | | * Return the prescontext we were initialized with |
331 | | */ |
332 | | nsPresContext* GetPresContext() const { return mPresContext; } |
333 | | |
334 | | /** |
335 | | * PBackgroundChild actor is created asynchronously in content process. |
336 | | * We can't create vsync-based timers during PBackground startup. This |
337 | | * function will be called when PBackgroundChild actor is created. Then we can |
338 | | * do the pending vsync-based timer creation. |
339 | | */ |
340 | | static void PVsyncActorCreated(mozilla::layout::VsyncChild* aVsyncChild); |
341 | | |
342 | | #ifdef DEBUG |
343 | | /** |
344 | | * Check whether the given observer is an observer for the given flush type |
345 | | */ |
346 | | bool IsRefreshObserver(nsARefreshObserver *aObserver, |
347 | | mozilla::FlushType aFlushType); |
348 | | #endif |
349 | | |
350 | | /** |
351 | | * Default interval the refresh driver uses, in ms. |
352 | | */ |
353 | | static int32_t DefaultInterval(); |
354 | | |
355 | | bool IsInRefresh() { return mInRefresh; } |
356 | | |
357 | | void SetIsResizeSuppressed() { mResizeSuppressed = true; } |
358 | 0 | bool IsResizeSuppressed() const { return mResizeSuppressed; } |
359 | | |
360 | | /** |
361 | | * The latest value of process-wide jank levels. |
362 | | * |
363 | | * For each i, sJankLevels[i] counts the number of times delivery of |
364 | | * vsync to the main thread has been delayed by at least 2^i |
365 | | * ms. This data structure has been designed to make it easy to |
366 | | * determine how much jank has taken place between two instants in |
367 | | * time. |
368 | | * |
369 | | * Return `false` if `aJank` needs to be grown to accomodate the |
370 | | * data but we didn't have enough memory. |
371 | | */ |
372 | | static bool GetJankLevels(mozilla::Vector<uint64_t>& aJank); |
373 | | |
374 | | // mozilla::layers::TransactionIdAllocator |
375 | | TransactionId GetTransactionId(bool aThrottle) override; |
376 | | TransactionId LastTransactionId() const override; |
377 | | void NotifyTransactionCompleted(TransactionId aTransactionId) override; |
378 | | void RevokeTransactionId(TransactionId aTransactionId) override; |
379 | | void ClearPendingTransactions() override; |
380 | | void ResetInitialTransactionId(TransactionId aTransactionId) override; |
381 | | mozilla::TimeStamp GetTransactionStart() override; |
382 | | |
383 | | bool IsWaitingForPaint(mozilla::TimeStamp aTime); |
384 | | |
385 | | // nsARefreshObserver |
386 | 0 | NS_IMETHOD_(MozExternalRefCountType) AddRef(void) override { return TransactionIdAllocator::AddRef(); } |
387 | 0 | NS_IMETHOD_(MozExternalRefCountType) Release(void) override { return TransactionIdAllocator::Release(); } |
388 | | virtual void WillRefresh(mozilla::TimeStamp aTime) override; |
389 | | |
390 | | /** |
391 | | * Compute the time when the currently active refresh driver timer |
392 | | * will start its next tick. |
393 | | * |
394 | | * Expects a non-null default value that is the upper bound of the |
395 | | * expected deadline. If the next expected deadline is later than |
396 | | * the default value, the default value is returned. |
397 | | * |
398 | | * If we're animating and we have skipped paints a time in the past |
399 | | * is returned. |
400 | | */ |
401 | | static mozilla::TimeStamp GetIdleDeadlineHint(mozilla::TimeStamp aDefault); |
402 | | |
403 | | /** |
404 | | * It returns the expected timestamp of the next tick or nothing if the next |
405 | | * tick is missed. |
406 | | */ |
407 | | static mozilla::Maybe<mozilla::TimeStamp> GetNextTickHint(); |
408 | | |
409 | | static void DispatchIdleRunnableAfterTick(nsIRunnable* aRunnable, |
410 | | uint32_t aDelay); |
411 | | static void CancelIdleRunnable(nsIRunnable* aRunnable); |
412 | | |
413 | | void NotifyDOMContentLoaded(); |
414 | | |
415 | | private: |
416 | | typedef nsTObserverArray<nsARefreshObserver*> ObserverArray; |
417 | | typedef nsTArray<RefPtr<mozilla::Runnable>> ScrollEventArray; |
418 | | typedef nsTHashtable<nsISupportsHashKey> RequestTable; |
419 | | struct ImageStartData { |
420 | | ImageStartData() |
421 | | { |
422 | | } |
423 | | |
424 | | mozilla::Maybe<mozilla::TimeStamp> mStartTime; |
425 | | RequestTable mEntries; |
426 | | }; |
427 | | typedef nsClassHashtable<nsUint32HashKey, ImageStartData> ImageStartTable; |
428 | | |
429 | | void RunFullscreenSteps(); |
430 | | void DispatchAnimationEvents(); |
431 | | void RunFrameRequestCallbacks(mozilla::TimeStamp aNowTime); |
432 | | void UpdateIntersectionObservations(); |
433 | | void Tick(mozilla::TimeStamp aNowTime); |
434 | | |
435 | | enum EnsureTimerStartedFlags { |
436 | | eNone = 0, |
437 | | eForceAdjustTimer = 1 << 0, |
438 | | eAllowTimeToGoBackwards = 1 << 1, |
439 | | eNeverAdjustTimer = 1 << 2, |
440 | | }; |
441 | | void EnsureTimerStarted(EnsureTimerStartedFlags aFlags = eNone); |
442 | | void StopTimer(); |
443 | | |
444 | | bool HasObservers() const; |
445 | | // Note: This should only be called in the dtor of nsRefreshDriver. |
446 | | uint32_t ObserverCount() const; |
447 | | bool HasImageRequests() const; |
448 | | ObserverArray& ArrayFor(mozilla::FlushType aFlushType); |
449 | | // Trigger a refresh immediately, if haven't been disconnected or frozen. |
450 | | void DoRefresh(); |
451 | | |
452 | | double GetRegularTimerInterval() const; |
453 | | static double GetThrottledTimerInterval(); |
454 | | |
455 | | static mozilla::TimeDuration GetMinRecomputeVisibilityInterval(); |
456 | | |
457 | 0 | bool HaveFrameRequestCallbacks() const { |
458 | 0 | return mFrameRequestCallbackDocs.Length() != 0; |
459 | 0 | } |
460 | | |
461 | | void FinishedWaitingForTransaction(); |
462 | | |
463 | | mozilla::RefreshDriverTimer* ChooseTimer() const; |
464 | | mozilla::RefreshDriverTimer* mActiveTimer; |
465 | | |
466 | | // nsPresContext passed in constructor and unset in Disconnect. |
467 | | mozilla::WeakPtr<nsPresContext> mPresContext; |
468 | | |
469 | | RefPtr<nsRefreshDriver> mRootRefresh; |
470 | | |
471 | | // The most recently allocated transaction id. |
472 | | TransactionId mNextTransactionId; |
473 | | // This number is mCompletedTransaction + (pending transaction count). |
474 | | // When we revoke a transaction id, we revert this number (since it's |
475 | | // no longer outstanding), but not mNextTransactionId (since we don't |
476 | | // want to reuse the number). |
477 | | TransactionId mOutstandingTransactionId; |
478 | | // The most recently completed transaction id. |
479 | | TransactionId mCompletedTransaction; |
480 | | |
481 | | uint32_t mFreezeCount; |
482 | | |
483 | | // How long we wait between ticks for throttled (which generally means |
484 | | // non-visible) documents registered with a non-throttled refresh driver. |
485 | | const mozilla::TimeDuration mThrottledFrameRequestInterval; |
486 | | |
487 | | // How long we wait, at a minimum, before recomputing approximate frame |
488 | | // visibility information. This is a minimum because, regardless of this |
489 | | // interval, we only recompute visibility when we've seen a layout or style |
490 | | // flush since the last time we did it. |
491 | | const mozilla::TimeDuration mMinRecomputeVisibilityInterval; |
492 | | |
493 | | bool mThrottled; |
494 | | bool mNeedToRecomputeVisibility; |
495 | | bool mTestControllingRefreshes; |
496 | | bool mViewManagerFlushIsPending; |
497 | | |
498 | | // True if the view manager needs a flush. Layers-free mode uses this value |
499 | | // to know when to notify invalidation. |
500 | | bool mHasScheduleFlush; |
501 | | |
502 | | bool mInRefresh; |
503 | | |
504 | | // True if the refresh driver is suspended waiting for transaction |
505 | | // id's to be returned and shouldn't do any work during Tick(). |
506 | | bool mWaitingForTransaction; |
507 | | // True if Tick() was skipped because of mWaitingForTransaction and |
508 | | // we should schedule a new Tick immediately when resumed instead |
509 | | // of waiting until the next interval. |
510 | | bool mSkippedPaints; |
511 | | |
512 | | // True if view managers should delay any resize request until the |
513 | | // next tick by the refresh driver. This flag will be reset at the |
514 | | // start of every tick. |
515 | | bool mResizeSuppressed; |
516 | | |
517 | | // True if the next tick should notify DOMContentFlushed. |
518 | | bool mNotifyDOMContentFlushed; |
519 | | |
520 | | // Number of seconds that the refresh driver is blocked waiting for a compositor |
521 | | // transaction to be completed before we append a note to the gfx critical log. |
522 | | // The number is doubled every time the threshold is hit. |
523 | | uint64_t mWarningThreshold; |
524 | | mozilla::TimeStamp mMostRecentRefresh; |
525 | | mozilla::TimeStamp mTickStart; |
526 | | mozilla::TimeStamp mNextThrottledFrameRequestTick; |
527 | | mozilla::TimeStamp mNextRecomputeVisibilityTick; |
528 | | |
529 | | // separate arrays for each flush type we support |
530 | | ObserverArray mObservers[4]; |
531 | | // These observers should NOT be included in HasObservers() since that method |
532 | | // is used to determine whether or not to stop the timer, or restore it when |
533 | | // thawing the refresh driver. On the other hand these observers are intended |
534 | | // to be called when the timer is re-started and should not influence its |
535 | | // starting or stopping. |
536 | | nsTObserverArray<nsATimerAdjustmentObserver*> mTimerAdjustmentObservers; |
537 | | RequestTable mRequests; |
538 | | ImageStartTable mStartTable; |
539 | | AutoTArray<nsCOMPtr<nsIRunnable>, 16> mEarlyRunners; |
540 | | ScrollEventArray mScrollEvents; |
541 | | |
542 | | AutoTArray<nsIPresShell*, 16> mResizeEventFlushObservers; |
543 | | AutoTArray<nsIPresShell*, 16> mStyleFlushObservers; |
544 | | AutoTArray<nsIPresShell*, 16> mLayoutFlushObservers; |
545 | | // nsTArray on purpose, because we want to be able to swap. |
546 | | nsTArray<nsIDocument*> mFrameRequestCallbackDocs; |
547 | | nsTArray<nsIDocument*> mThrottledFrameRequestCallbackDocs; |
548 | | nsTObserverArray<nsAPostRefreshObserver*> mPostRefreshObservers; |
549 | | nsTArray<mozilla::UniquePtr<mozilla::PendingFullscreenEvent>> |
550 | | mPendingFullscreenEvents; |
551 | | AutoTArray<mozilla::AnimationEventDispatcher*, 16> |
552 | | mAnimationEventFlushObservers; |
553 | | |
554 | | void BeginRefreshingImages(RequestTable& aEntries, |
555 | | mozilla::TimeStamp aDesired); |
556 | | |
557 | | friend class mozilla::RefreshDriverTimer; |
558 | | |
559 | | static void Shutdown(); |
560 | | |
561 | | // `true` if we are currently in jank-critical mode. |
562 | | // |
563 | | // In jank-critical mode, any iteration of the event loop that takes |
564 | | // more than 16ms to compute will cause an ongoing animation to miss |
565 | | // frames. |
566 | | // |
567 | | // For simplicity, the current implementation assumes that we are |
568 | | // in jank-critical mode if and only if the vsync driver has at least |
569 | | // one observer. |
570 | | static bool IsJankCritical(); |
571 | | }; |
572 | | |
573 | | #endif /* !defined(nsRefreshDriver_h_) */ |