2017-10-27 20:33:53 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2009-10-08 07:22:42 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Code to notify things that animate before a refresh, at an appropriate
|
|
|
|
* refresh rate. (Perhaps temporary, until replaced by compositor.)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef nsRefreshDriver_h_
|
|
|
|
#define nsRefreshDriver_h_
|
|
|
|
|
2017-01-05 09:54:02 +03:00
|
|
|
#include "mozilla/FlushType.h"
|
2009-10-08 07:22:42 +04:00
|
|
|
#include "mozilla/TimeStamp.h"
|
2016-01-14 17:07:18 +03:00
|
|
|
#include "mozilla/Vector.h"
|
2016-10-12 14:27:38 +03:00
|
|
|
#include "mozilla/WeakPtr.h"
|
2009-10-08 07:22:42 +04:00
|
|
|
#include "nsTObserverArray.h"
|
2010-08-12 01:05:27 +04:00
|
|
|
#include "nsTArray.h"
|
2011-11-10 01:39:16 +04:00
|
|
|
#include "nsTHashtable.h"
|
2015-06-26 23:20:10 +03:00
|
|
|
#include "nsTObserverArray.h"
|
2013-05-18 00:57:26 +04:00
|
|
|
#include "nsClassHashtable.h"
|
2011-11-10 01:39:16 +04:00
|
|
|
#include "nsHashKeys.h"
|
2012-06-19 07:26:34 +04:00
|
|
|
#include "mozilla/Attributes.h"
|
2013-08-28 02:10:28 +04:00
|
|
|
#include "mozilla/Maybe.h"
|
2014-05-29 01:42:17 +04:00
|
|
|
#include "mozilla/layers/TransactionIdAllocator.h"
|
2009-10-08 07:22:42 +04:00
|
|
|
|
2009-12-22 00:46:24 +03:00
|
|
|
class nsPresContext;
|
2010-08-12 01:05:27 +04:00
|
|
|
class nsIPresShell;
|
2010-08-12 01:05:28 +04:00
|
|
|
class nsIDocument;
|
2011-11-10 01:39:16 +04:00
|
|
|
class imgIRequest;
|
2015-07-02 12:12:31 +03:00
|
|
|
class nsINode;
|
2017-06-10 02:38:50 +03:00
|
|
|
class nsIRunnable;
|
2013-08-19 17:08:44 +04:00
|
|
|
|
|
|
|
namespace mozilla {
|
2018-04-26 08:00:50 +03:00
|
|
|
class AnimationEventDispatcher;
|
2013-08-19 17:08:44 +04:00
|
|
|
class RefreshDriverTimer;
|
2017-08-10 04:08:38 +03:00
|
|
|
class Runnable;
|
2018-04-05 20:42:41 +03:00
|
|
|
|
2015-01-14 02:38:00 +03:00
|
|
|
namespace layout {
|
|
|
|
class VsyncChild;
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace layout
|
2018-04-05 20:42:41 +03:00
|
|
|
|
|
|
|
namespace dom {
|
|
|
|
class Event;
|
|
|
|
} // namespace dom
|
|
|
|
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace mozilla
|
2009-12-22 00:46:24 +03:00
|
|
|
|
2009-10-08 07:22:42 +04:00
|
|
|
/**
|
|
|
|
* An abstract base class to be implemented by callers wanting to be
|
|
|
|
* notified at refresh times. When nothing needs to be painted, callers
|
|
|
|
* may not be notified.
|
|
|
|
*/
|
|
|
|
class nsARefreshObserver {
|
|
|
|
public:
|
2009-12-22 00:46:25 +03:00
|
|
|
// AddRef and Release signatures that match nsISupports. Implementors
|
|
|
|
// must implement reference counting, and those that do implement
|
|
|
|
// nsISupports will already have methods with the correct signature.
|
|
|
|
//
|
|
|
|
// The refresh driver does NOT hold references to refresh observers
|
2010-06-27 06:43:13 +04:00
|
|
|
// except while it is notifying them.
|
2017-01-25 22:51:34 +03:00
|
|
|
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
2009-12-22 00:46:25 +03:00
|
|
|
|
2009-10-08 07:22:42 +04:00
|
|
|
virtual void WillRefresh(mozilla::TimeStamp aTime) = 0;
|
|
|
|
};
|
|
|
|
|
2018-07-03 04:57:12 +03:00
|
|
|
/**
|
|
|
|
* An abstract base class to be implemented by callers wanting to be notified
|
|
|
|
* when the observing refresh driver updated mMostRecentRefresh due to active
|
|
|
|
* timer changes. Callers must ensure an observer is removed before it is
|
|
|
|
* destroyed.
|
|
|
|
*/
|
|
|
|
class nsATimerAdjustmentObserver {
|
|
|
|
public:
|
|
|
|
virtual void NotifyTimerAdjusted(mozilla::TimeStamp aTime) = 0;
|
|
|
|
};
|
|
|
|
|
2013-08-19 17:08:44 +04:00
|
|
|
/**
|
|
|
|
* An abstract base class to be implemented by callers wanting to be notified
|
|
|
|
* that a refresh has occurred. Callers must ensure an observer is removed
|
|
|
|
* before it is destroyed.
|
|
|
|
*/
|
|
|
|
class nsAPostRefreshObserver {
|
|
|
|
public:
|
|
|
|
virtual void DidRefresh() = 0;
|
|
|
|
};
|
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator,
|
2015-03-27 21:52:19 +03:00
|
|
|
public nsARefreshObserver
|
|
|
|
{
|
2018-04-20 22:13:06 +03:00
|
|
|
using TransactionId = mozilla::layers::TransactionId;
|
|
|
|
|
2009-10-08 07:22:42 +04:00
|
|
|
public:
|
2014-08-08 03:48:38 +04:00
|
|
|
explicit nsRefreshDriver(nsPresContext *aPresContext);
|
2009-10-08 07:22:42 +04:00
|
|
|
~nsRefreshDriver();
|
|
|
|
|
2011-04-12 10:18:43 +04:00
|
|
|
/**
|
|
|
|
* Methods for testing, exposed via nsIDOMWindowUtils. See
|
|
|
|
* nsIDOMWindowUtils.advanceTimeAndRefresh for description.
|
|
|
|
*/
|
2012-08-22 19:56:38 +04:00
|
|
|
void AdvanceTimeAndRefresh(int64_t aMilliseconds);
|
2011-04-12 10:18:43 +04:00
|
|
|
void RestoreNormalRefresh();
|
2012-12-12 02:15:32 +04:00
|
|
|
void DoTick();
|
|
|
|
bool IsTestControllingRefreshesEnabled() const
|
|
|
|
{
|
|
|
|
return mTestControllingRefreshes;
|
|
|
|
}
|
2011-04-12 10:18:43 +04:00
|
|
|
|
2009-10-08 07:22:42 +04:00
|
|
|
/**
|
|
|
|
* Return the time of the most recent refresh. This is intended to be
|
|
|
|
* used by callers who want to start an animation now and want to know
|
|
|
|
* what time to consider the start of the animation. (This helps
|
|
|
|
* ensure that multiple animations started during the same event off
|
|
|
|
* the main event loop have the same start time.)
|
|
|
|
*/
|
|
|
|
mozilla::TimeStamp MostRecentRefresh() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add / remove refresh observers. Returns whether the operation
|
|
|
|
* succeeded.
|
|
|
|
*
|
|
|
|
* The flush type affects:
|
|
|
|
* + the order in which the observers are notified (lowest flush
|
|
|
|
* type to highest, in order registered)
|
|
|
|
* + (in the future) which observers are suppressed when the display
|
|
|
|
* doesn't require current position data or isn't currently
|
|
|
|
* painting, and, correspondingly, which get notified when there
|
|
|
|
* is a flush during such suppression
|
2017-01-05 10:31:56 +03:00
|
|
|
* and it must be FlushType::Style, FlushType::Layout, or FlushType::Display.
|
2009-12-22 00:46:25 +03:00
|
|
|
*
|
|
|
|
* The refresh driver does NOT own a reference to these observers;
|
|
|
|
* they must remove themselves before they are destroyed.
|
2013-08-19 17:08:44 +04:00
|
|
|
*
|
|
|
|
* The observer will be called even if there is no other activity.
|
2009-10-08 07:22:42 +04:00
|
|
|
*/
|
2011-09-29 10:19:26 +04:00
|
|
|
bool AddRefreshObserver(nsARefreshObserver *aObserver,
|
2017-01-05 10:31:56 +03:00
|
|
|
mozilla::FlushType aFlushType);
|
2011-09-29 10:19:26 +04:00
|
|
|
bool RemoveRefreshObserver(nsARefreshObserver *aObserver,
|
2017-01-05 10:31:56 +03:00
|
|
|
mozilla::FlushType aFlushType);
|
2018-07-03 04:57:12 +03:00
|
|
|
/**
|
|
|
|
* Add / remove an observer wants to know the time when the refresh driver
|
|
|
|
* updated the most recent refresh time due to its active timer changes.
|
|
|
|
*/
|
|
|
|
bool AddTimerAdjustmentObserver(nsATimerAdjustmentObserver *aObserver);
|
|
|
|
bool RemoveTimerAdjustmentObserver(nsATimerAdjustmentObserver *aObserver);
|
2013-08-19 17:08:44 +04:00
|
|
|
|
2017-08-10 04:08:38 +03:00
|
|
|
void PostScrollEvent(mozilla::Runnable* aScrollEvent);
|
|
|
|
void DispatchScrollEvents();
|
|
|
|
|
2013-08-19 17:08:44 +04:00
|
|
|
/**
|
|
|
|
* Add an observer that will be called after each refresh. The caller
|
|
|
|
* must remove the observer before it is deleted. This does not trigger
|
|
|
|
* refresh driver ticks.
|
|
|
|
*/
|
|
|
|
void AddPostRefreshObserver(nsAPostRefreshObserver *aObserver);
|
|
|
|
void RemovePostRefreshObserver(nsAPostRefreshObserver *aObserver);
|
2009-10-08 07:22:42 +04:00
|
|
|
|
2011-11-10 01:39:16 +04:00
|
|
|
/**
|
|
|
|
* Add/Remove imgIRequest versions of observers.
|
|
|
|
*
|
|
|
|
* These are used for hooking into the refresh driver for
|
|
|
|
* controlling animated images.
|
|
|
|
*
|
|
|
|
* @note The refresh driver owns a reference to these listeners.
|
|
|
|
*
|
|
|
|
* @note Technically, imgIRequest objects are not nsARefreshObservers, but
|
|
|
|
* for controlling animated image repaint events, we subscribe the
|
|
|
|
* imgIRequests to the nsRefreshDriver for notification of paint events.
|
|
|
|
*
|
|
|
|
* @returns whether the operation succeeded, or void in the case of removal.
|
|
|
|
*/
|
|
|
|
bool AddImageRequest(imgIRequest* aRequest);
|
|
|
|
void RemoveImageRequest(imgIRequest* aRequest);
|
|
|
|
|
2015-05-05 17:56:01 +03:00
|
|
|
/**
|
|
|
|
* Add / remove presshells which have pending resize event.
|
|
|
|
*/
|
|
|
|
void AddResizeEventFlushObserver(nsIPresShell* aShell)
|
|
|
|
{
|
2018-03-08 13:01:32 +03:00
|
|
|
MOZ_DIAGNOSTIC_ASSERT(!mResizeEventFlushObservers.Contains(aShell),
|
|
|
|
"Double-adding resize event flush observer");
|
2015-05-05 17:56:01 +03:00
|
|
|
mResizeEventFlushObservers.AppendElement(aShell);
|
|
|
|
EnsureTimerStarted();
|
|
|
|
}
|
|
|
|
|
|
|
|
void RemoveResizeEventFlushObserver(nsIPresShell* aShell)
|
|
|
|
{
|
|
|
|
mResizeEventFlushObservers.RemoveElement(aShell);
|
|
|
|
}
|
|
|
|
|
2010-08-12 01:05:27 +04:00
|
|
|
/**
|
|
|
|
* Add / remove presshells that we should flush style and layout on
|
|
|
|
*/
|
2018-03-08 13:01:32 +03:00
|
|
|
void AddStyleFlushObserver(nsIPresShell* aShell)
|
|
|
|
{
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(!mStyleFlushObservers.Contains(aShell),
|
|
|
|
"Double-adding style flush observer");
|
|
|
|
mStyleFlushObservers.AppendElement(aShell);
|
2015-01-06 04:56:02 +03:00
|
|
|
EnsureTimerStarted();
|
2010-08-12 01:05:27 +04:00
|
|
|
}
|
2018-03-08 13:01:32 +03:00
|
|
|
|
|
|
|
void RemoveStyleFlushObserver(nsIPresShell* aShell)
|
|
|
|
{
|
2010-08-12 01:05:27 +04:00
|
|
|
mStyleFlushObservers.RemoveElement(aShell);
|
|
|
|
}
|
2018-03-08 13:01:32 +03:00
|
|
|
void AddLayoutFlushObserver(nsIPresShell* aShell)
|
|
|
|
{
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(!IsLayoutFlushObserver(aShell),
|
|
|
|
"Double-adding layout flush observer");
|
|
|
|
mLayoutFlushObservers.AppendElement(aShell);
|
2015-01-06 04:56:02 +03:00
|
|
|
EnsureTimerStarted();
|
2010-08-12 01:05:27 +04:00
|
|
|
}
|
2018-03-08 13:01:32 +03:00
|
|
|
void RemoveLayoutFlushObserver(nsIPresShell* aShell)
|
|
|
|
{
|
2010-08-12 01:05:27 +04:00
|
|
|
mLayoutFlushObservers.RemoveElement(aShell);
|
|
|
|
}
|
2018-03-08 13:01:32 +03:00
|
|
|
|
|
|
|
bool IsLayoutFlushObserver(nsIPresShell* aShell)
|
|
|
|
{
|
2010-08-12 01:05:27 +04:00
|
|
|
return mLayoutFlushObservers.Contains(aShell);
|
|
|
|
}
|
|
|
|
|
2017-06-29 14:46:11 +03:00
|
|
|
/**
|
|
|
|
* "Early Runner" runnables will be called as the first step when refresh
|
|
|
|
* driver tick is triggered. Runners shouldn't keep other objects alive,
|
|
|
|
* since it isn't guaranteed they will ever get called.
|
|
|
|
*/
|
|
|
|
void AddEarlyRunner(nsIRunnable* aRunnable)
|
2017-06-25 00:38:42 +03:00
|
|
|
{
|
2017-06-29 14:46:11 +03:00
|
|
|
mEarlyRunners.AppendElement(aRunnable);
|
2017-06-25 00:38:42 +03:00
|
|
|
EnsureTimerStarted();
|
|
|
|
}
|
|
|
|
|
2011-12-24 07:52:22 +04:00
|
|
|
/**
|
|
|
|
* Remember whether our presshell's view manager needs a flush
|
|
|
|
*/
|
2012-09-17 09:06:12 +04:00
|
|
|
void ScheduleViewManagerFlush();
|
2011-12-24 07:52:22 +04:00
|
|
|
void RevokeViewManagerFlush() {
|
|
|
|
mViewManagerFlushIsPending = false;
|
|
|
|
}
|
2012-08-29 09:47:18 +04:00
|
|
|
bool ViewManagerFlushIsPending() {
|
|
|
|
return mViewManagerFlushIsPending;
|
|
|
|
}
|
2017-10-03 11:00:38 +03:00
|
|
|
bool HasScheduleFlush() {
|
|
|
|
return mHasScheduleFlush;
|
|
|
|
}
|
2011-12-24 07:52:22 +04:00
|
|
|
|
2010-09-09 09:38:04 +04:00
|
|
|
/**
|
2015-07-20 17:14:24 +03:00
|
|
|
* Add a document for which we have FrameRequestCallbacks
|
2010-09-09 09:38:04 +04:00
|
|
|
*/
|
2011-11-28 16:48:30 +04:00
|
|
|
void ScheduleFrameRequestCallbacks(nsIDocument* aDocument);
|
2010-09-09 09:38:04 +04:00
|
|
|
|
|
|
|
/**
|
2015-07-20 17:14:24 +03:00
|
|
|
* Remove a document for which we have FrameRequestCallbacks
|
2010-09-09 09:38:04 +04:00
|
|
|
*/
|
2011-11-28 16:48:30 +04:00
|
|
|
void RevokeFrameRequestCallbacks(nsIDocument* aDocument);
|
2010-09-09 09:38:04 +04:00
|
|
|
|
2015-07-02 12:12:31 +03:00
|
|
|
/**
|
|
|
|
* Queue a new event to dispatch in next tick before the style flush
|
|
|
|
*/
|
2018-04-05 20:42:41 +03:00
|
|
|
void ScheduleEventDispatch(nsINode* aTarget, mozilla::dom::Event* aEvent);
|
2015-07-02 12:12:31 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Cancel all pending events scheduled by ScheduleEventDispatch which
|
|
|
|
* targets any node in aDocument.
|
|
|
|
*/
|
|
|
|
void CancelPendingEvents(nsIDocument* aDocument);
|
|
|
|
|
2018-01-27 15:17:27 +03:00
|
|
|
/**
|
|
|
|
* Queue new animation events to dispatch in next tick.
|
|
|
|
*/
|
|
|
|
void ScheduleAnimationEventDispatch(
|
|
|
|
mozilla::AnimationEventDispatcher* aDispatcher)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(!mAnimationEventFlushObservers.Contains(aDispatcher),
|
|
|
|
"Double-adding animation event flush observer");
|
|
|
|
mAnimationEventFlushObservers.AppendElement(aDispatcher);
|
|
|
|
EnsureTimerStarted();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Cancel all pending animation events associated with |aDispatcher|.
|
|
|
|
*/
|
|
|
|
void CancelPendingAnimationEvents(
|
|
|
|
mozilla::AnimationEventDispatcher* aDispatcher);
|
|
|
|
|
2016-03-26 00:49:43 +03:00
|
|
|
/**
|
|
|
|
* Schedule a frame visibility update "soon", subject to the heuristics and
|
|
|
|
* throttling we apply to visibility updates.
|
|
|
|
*/
|
|
|
|
void ScheduleFrameVisibilityUpdate() { mNeedToRecomputeVisibility = true; }
|
|
|
|
|
2009-12-22 00:46:24 +03:00
|
|
|
/**
|
|
|
|
* Tell the refresh driver that it is done driving refreshes and
|
|
|
|
* should stop its timer and forget about its pres context. This may
|
|
|
|
* be called from within a refresh.
|
|
|
|
*/
|
2016-06-06 16:51:15 +03:00
|
|
|
void Disconnect();
|
2009-10-08 07:22:42 +04:00
|
|
|
|
2013-12-20 01:38:35 +04:00
|
|
|
bool IsFrozen() { return mFreezeCount > 0; }
|
|
|
|
|
2010-02-04 00:17:55 +03:00
|
|
|
/**
|
|
|
|
* Freeze the refresh driver. It should stop delivering future
|
2013-12-20 01:38:35 +04:00
|
|
|
* refreshes until thawed. Note that the number of calls to Freeze() must
|
|
|
|
* match the number of calls to Thaw() in order for the refresh driver to
|
|
|
|
* be un-frozen.
|
2010-02-04 00:17:55 +03:00
|
|
|
*/
|
|
|
|
void Freeze();
|
|
|
|
|
|
|
|
/**
|
2013-12-20 01:38:35 +04:00
|
|
|
* Thaw the refresh driver. If the number of calls to Freeze() matches the
|
|
|
|
* number of calls to this function, the refresh driver should start
|
|
|
|
* delivering refreshes again.
|
2010-02-04 00:17:55 +03:00
|
|
|
*/
|
|
|
|
void Thaw();
|
|
|
|
|
2010-08-27 08:26:23 +04:00
|
|
|
/**
|
|
|
|
* Throttle or unthrottle the refresh driver. This is done if the
|
|
|
|
* corresponding presshell is hidden or shown.
|
|
|
|
*/
|
|
|
|
void SetThrottled(bool aThrottled);
|
|
|
|
|
2010-08-12 01:05:27 +04:00
|
|
|
/**
|
|
|
|
* Return the prescontext we were initialized with
|
|
|
|
*/
|
2016-10-12 14:27:38 +03:00
|
|
|
nsPresContext* GetPresContext() const { return mPresContext; }
|
2010-08-12 01:05:27 +04:00
|
|
|
|
2015-01-14 02:38:00 +03:00
|
|
|
/**
|
|
|
|
* PBackgroundChild actor is created asynchronously in content process.
|
|
|
|
* We can't create vsync-based timers during PBackground startup. This
|
|
|
|
* function will be called when PBackgroundChild actor is created. Then we can
|
|
|
|
* do the pending vsync-based timer creation.
|
|
|
|
*/
|
|
|
|
static void PVsyncActorCreated(mozilla::layout::VsyncChild* aVsyncChild);
|
|
|
|
|
2010-02-19 20:11:40 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
/**
|
|
|
|
* Check whether the given observer is an observer for the given flush type
|
|
|
|
*/
|
2011-09-29 10:19:26 +04:00
|
|
|
bool IsRefreshObserver(nsARefreshObserver *aObserver,
|
2017-01-05 10:31:56 +03:00
|
|
|
mozilla::FlushType aFlushType);
|
2010-02-19 20:11:40 +03:00
|
|
|
#endif
|
|
|
|
|
2011-12-24 07:52:26 +04:00
|
|
|
/**
|
|
|
|
* Default interval the refresh driver uses, in ms.
|
|
|
|
*/
|
2012-08-22 19:56:38 +04:00
|
|
|
static int32_t DefaultInterval();
|
2011-12-24 07:52:26 +04:00
|
|
|
|
2013-09-04 15:47:21 +04:00
|
|
|
bool IsInRefresh() { return mInRefresh; }
|
|
|
|
|
2016-05-03 10:58:57 +03:00
|
|
|
void SetIsResizeSuppressed() { mResizeSuppressed = true; }
|
|
|
|
bool IsResizeSuppressed() const { return mResizeSuppressed; }
|
|
|
|
|
2016-01-14 17:07:18 +03:00
|
|
|
/**
|
|
|
|
* The latest value of process-wide jank levels.
|
|
|
|
*
|
|
|
|
* For each i, sJankLevels[i] counts the number of times delivery of
|
|
|
|
* vsync to the main thread has been delayed by at least 2^i
|
|
|
|
* ms. This data structure has been designed to make it easy to
|
|
|
|
* determine how much jank has taken place between two instants in
|
|
|
|
* time.
|
|
|
|
*
|
|
|
|
* Return `false` if `aJank` needs to be grown to accomodate the
|
|
|
|
* data but we didn't have enough memory.
|
|
|
|
*/
|
|
|
|
static bool GetJankLevels(mozilla::Vector<uint64_t>& aJank);
|
|
|
|
|
2014-05-29 01:42:17 +04:00
|
|
|
// mozilla::layers::TransactionIdAllocator
|
2018-04-20 22:13:06 +03:00
|
|
|
TransactionId GetTransactionId(bool aThrottle) override;
|
|
|
|
TransactionId LastTransactionId() const override;
|
|
|
|
void NotifyTransactionCompleted(TransactionId aTransactionId) override;
|
|
|
|
void RevokeTransactionId(TransactionId aTransactionId) override;
|
2017-03-09 13:35:50 +03:00
|
|
|
void ClearPendingTransactions() override;
|
2018-04-20 22:13:06 +03:00
|
|
|
void ResetInitialTransactionId(TransactionId aTransactionId) override;
|
2015-03-21 19:28:04 +03:00
|
|
|
mozilla::TimeStamp GetTransactionStart() override;
|
2014-05-29 01:42:17 +04:00
|
|
|
|
2014-08-15 06:24:50 +04:00
|
|
|
bool IsWaitingForPaint(mozilla::TimeStamp aTime);
|
2014-05-29 01:43:41 +04:00
|
|
|
|
|
|
|
// nsARefreshObserver
|
2015-03-21 19:28:04 +03:00
|
|
|
NS_IMETHOD_(MozExternalRefCountType) AddRef(void) override { return TransactionIdAllocator::AddRef(); }
|
|
|
|
NS_IMETHOD_(MozExternalRefCountType) Release(void) override { return TransactionIdAllocator::Release(); }
|
|
|
|
virtual void WillRefresh(mozilla::TimeStamp aTime) override;
|
2016-06-06 16:51:15 +03:00
|
|
|
|
2016-08-22 15:52:45 +03:00
|
|
|
/**
|
|
|
|
* Compute the time when the currently active refresh driver timer
|
|
|
|
* will start its next tick.
|
|
|
|
*
|
2017-05-25 04:11:12 +03:00
|
|
|
* Expects a non-null default value that is the upper bound of the
|
|
|
|
* expected deadline. If the next expected deadline is later than
|
|
|
|
* the default value, the default value is returned.
|
2016-08-22 15:52:45 +03:00
|
|
|
*
|
2017-05-25 04:11:12 +03:00
|
|
|
* If we're animating and we have skipped paints a time in the past
|
|
|
|
* is returned.
|
2016-08-22 15:52:45 +03:00
|
|
|
*/
|
2017-05-25 04:11:12 +03:00
|
|
|
static mozilla::TimeStamp GetIdleDeadlineHint(mozilla::TimeStamp aDefault);
|
2016-08-22 15:52:45 +03:00
|
|
|
|
2017-03-21 10:44:12 +03:00
|
|
|
/**
|
|
|
|
* It returns the expected timestamp of the next tick or nothing if the next
|
|
|
|
* tick is missed.
|
|
|
|
*/
|
|
|
|
static mozilla::Maybe<mozilla::TimeStamp> GetNextTickHint();
|
|
|
|
|
2017-06-10 02:38:50 +03:00
|
|
|
static void DispatchIdleRunnableAfterTick(nsIRunnable* aRunnable,
|
|
|
|
uint32_t aDelay);
|
|
|
|
static void CancelIdleRunnable(nsIRunnable* aRunnable);
|
|
|
|
|
2018-04-27 01:36:52 +03:00
|
|
|
void NotifyDOMContentLoaded();
|
|
|
|
|
2009-12-22 00:46:24 +03:00
|
|
|
private:
|
2009-10-08 07:22:42 +04:00
|
|
|
typedef nsTObserverArray<nsARefreshObserver*> ObserverArray;
|
2017-08-10 04:08:38 +03:00
|
|
|
typedef nsTArray<RefPtr<mozilla::Runnable>> ScrollEventArray;
|
2011-11-10 01:39:16 +04:00
|
|
|
typedef nsTHashtable<nsISupportsHashKey> RequestTable;
|
2013-05-18 00:57:26 +04:00
|
|
|
struct ImageStartData {
|
|
|
|
ImageStartData()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::Maybe<mozilla::TimeStamp> mStartTime;
|
|
|
|
RequestTable mEntries;
|
|
|
|
};
|
|
|
|
typedef nsClassHashtable<nsUint32HashKey, ImageStartData> ImageStartTable;
|
2009-10-08 07:22:42 +04:00
|
|
|
|
2015-07-02 12:12:31 +03:00
|
|
|
void DispatchPendingEvents();
|
2015-07-29 04:57:39 +03:00
|
|
|
void DispatchAnimationEvents();
|
2015-07-27 02:06:00 +03:00
|
|
|
void RunFrameRequestCallbacks(mozilla::TimeStamp aNowTime);
|
2018-01-26 14:11:17 +03:00
|
|
|
void UpdateIntersectionObservations();
|
2018-07-11 00:15:00 +03:00
|
|
|
void Tick(mozilla::TimeStamp aNowTime);
|
2012-12-12 02:15:32 +04:00
|
|
|
|
2015-01-06 04:56:02 +03:00
|
|
|
enum EnsureTimerStartedFlags {
|
|
|
|
eNone = 0,
|
2016-01-05 06:50:59 +03:00
|
|
|
eForceAdjustTimer = 1 << 0,
|
2016-01-05 06:50:59 +03:00
|
|
|
eAllowTimeToGoBackwards = 1 << 1,
|
|
|
|
eNeverAdjustTimer = 1 << 2,
|
2015-01-06 04:56:02 +03:00
|
|
|
};
|
|
|
|
void EnsureTimerStarted(EnsureTimerStartedFlags aFlags = eNone);
|
2009-10-08 07:22:42 +04:00
|
|
|
void StopTimer();
|
2011-11-10 01:39:16 +04:00
|
|
|
|
2018-01-27 15:17:26 +03:00
|
|
|
bool HasObservers() const;
|
2018-07-03 04:57:12 +03:00
|
|
|
// Note: This should only be called in the dtor of nsRefreshDriver.
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t ObserverCount() const;
|
2018-01-27 15:17:26 +03:00
|
|
|
bool HasImageRequests() const;
|
2017-01-05 10:31:56 +03:00
|
|
|
ObserverArray& ArrayFor(mozilla::FlushType aFlushType);
|
2010-02-04 00:17:55 +03:00
|
|
|
// Trigger a refresh immediately, if haven't been disconnected or frozen.
|
|
|
|
void DoRefresh();
|
2009-10-08 07:22:42 +04:00
|
|
|
|
2018-05-16 15:32:18 +03:00
|
|
|
double GetRegularTimerInterval() const;
|
2015-04-21 19:44:40 +03:00
|
|
|
static double GetThrottledTimerInterval();
|
2011-03-04 18:27:02 +03:00
|
|
|
|
2015-05-30 09:50:51 +03:00
|
|
|
static mozilla::TimeDuration GetMinRecomputeVisibilityInterval();
|
|
|
|
|
2011-11-28 16:48:30 +04:00
|
|
|
bool HaveFrameRequestCallbacks() const {
|
|
|
|
return mFrameRequestCallbackDocs.Length() != 0;
|
2011-03-07 19:58:48 +03:00
|
|
|
}
|
|
|
|
|
2014-05-29 01:42:17 +04:00
|
|
|
void FinishedWaitingForTransaction();
|
|
|
|
|
2012-12-12 02:15:32 +04:00
|
|
|
mozilla::RefreshDriverTimer* ChooseTimer() const;
|
2015-01-14 02:38:00 +03:00
|
|
|
mozilla::RefreshDriverTimer* mActiveTimer;
|
2009-10-08 07:22:42 +04:00
|
|
|
|
2016-10-12 14:27:38 +03:00
|
|
|
// nsPresContext passed in constructor and unset in Disconnect.
|
|
|
|
mozilla::WeakPtr<nsPresContext> mPresContext;
|
2009-12-22 00:46:24 +03:00
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsRefreshDriver> mRootRefresh;
|
2014-05-29 01:43:41 +04:00
|
|
|
|
2014-05-29 01:42:17 +04:00
|
|
|
// The most recently allocated transaction id.
|
2018-09-06 05:21:39 +03:00
|
|
|
TransactionId mNextTransactionId;
|
|
|
|
// This number is mCompletedTransaction + (pending transaction count).
|
|
|
|
// When we revoke a transaction id, we revert this number (since it's
|
|
|
|
// no longer outstanding), but not mNextTransactionId (since we don't
|
|
|
|
// want to reuse the number).
|
|
|
|
TransactionId mOutstandingTransactionId;
|
2014-05-29 01:42:17 +04:00
|
|
|
// The most recently completed transaction id.
|
2018-04-20 22:13:06 +03:00
|
|
|
TransactionId mCompletedTransaction;
|
2014-05-29 01:42:17 +04:00
|
|
|
|
2013-12-20 01:38:35 +04:00
|
|
|
uint32_t mFreezeCount;
|
2015-04-21 19:44:40 +03:00
|
|
|
|
|
|
|
// How long we wait between ticks for throttled (which generally means
|
|
|
|
// non-visible) documents registered with a non-throttled refresh driver.
|
|
|
|
const mozilla::TimeDuration mThrottledFrameRequestInterval;
|
|
|
|
|
2016-03-26 00:49:43 +03:00
|
|
|
// How long we wait, at a minimum, before recomputing approximate frame
|
|
|
|
// visibility information. This is a minimum because, regardless of this
|
|
|
|
// interval, we only recompute visibility when we've seen a layout or style
|
|
|
|
// flush since the last time we did it.
|
2015-05-30 09:50:51 +03:00
|
|
|
const mozilla::TimeDuration mMinRecomputeVisibilityInterval;
|
|
|
|
|
2010-08-27 08:26:23 +04:00
|
|
|
bool mThrottled;
|
2015-05-30 09:50:51 +03:00
|
|
|
bool mNeedToRecomputeVisibility;
|
2011-04-12 10:18:43 +04:00
|
|
|
bool mTestControllingRefreshes;
|
2011-12-24 07:52:22 +04:00
|
|
|
bool mViewManagerFlushIsPending;
|
2017-10-03 11:00:38 +03:00
|
|
|
|
|
|
|
// True if the view manager needs a flush. Layers-free mode uses this value
|
|
|
|
// to know when to notify invalidation.
|
|
|
|
bool mHasScheduleFlush;
|
|
|
|
|
2013-09-04 15:47:21 +04:00
|
|
|
bool mInRefresh;
|
2012-12-12 02:15:32 +04:00
|
|
|
|
2014-05-29 01:42:17 +04:00
|
|
|
// True if the refresh driver is suspended waiting for transaction
|
|
|
|
// id's to be returned and shouldn't do any work during Tick().
|
|
|
|
bool mWaitingForTransaction;
|
|
|
|
// True if Tick() was skipped because of mWaitingForTransaction and
|
|
|
|
// we should schedule a new Tick immediately when resumed instead
|
|
|
|
// of waiting until the next interval.
|
2014-08-15 06:24:50 +04:00
|
|
|
bool mSkippedPaints;
|
2014-05-29 01:42:17 +04:00
|
|
|
|
2016-05-03 10:58:57 +03:00
|
|
|
// True if view managers should delay any resize request until the
|
|
|
|
// next tick by the refresh driver. This flag will be reset at the
|
|
|
|
// start of every tick.
|
|
|
|
bool mResizeSuppressed;
|
|
|
|
|
2018-04-27 01:36:52 +03:00
|
|
|
// True if the next tick should notify DOMContentFlushed.
|
|
|
|
bool mNotifyDOMContentFlushed;
|
|
|
|
|
2016-09-09 13:06:29 +03:00
|
|
|
// Number of seconds that the refresh driver is blocked waiting for a compositor
|
|
|
|
// transaction to be completed before we append a note to the gfx critical log.
|
|
|
|
// The number is doubled every time the threshold is hit.
|
|
|
|
uint64_t mWarningThreshold;
|
2012-12-12 02:15:32 +04:00
|
|
|
mozilla::TimeStamp mMostRecentRefresh;
|
2014-08-28 23:24:26 +04:00
|
|
|
mozilla::TimeStamp mTickStart;
|
2015-04-21 19:44:40 +03:00
|
|
|
mozilla::TimeStamp mNextThrottledFrameRequestTick;
|
2015-05-30 09:50:51 +03:00
|
|
|
mozilla::TimeStamp mNextRecomputeVisibilityTick;
|
2010-02-04 00:17:55 +03:00
|
|
|
|
2009-10-08 07:22:42 +04:00
|
|
|
// separate arrays for each flush type we support
|
2017-08-11 09:58:08 +03:00
|
|
|
ObserverArray mObservers[4];
|
2018-07-03 04:57:12 +03:00
|
|
|
// These observers should NOT be included in HasObservers() since that method
|
|
|
|
// is used to determine whether or not to stop the timer, or restore it when
|
|
|
|
// thawing the refresh driver. On the other hand these observers are intended
|
|
|
|
// to be called when the timer is re-started and should not influence its
|
|
|
|
// starting or stopping.
|
|
|
|
nsTObserverArray<nsATimerAdjustmentObserver*> mTimerAdjustmentObservers;
|
2011-11-10 01:39:16 +04:00
|
|
|
RequestTable mRequests;
|
2013-05-18 00:57:26 +04:00
|
|
|
ImageStartTable mStartTable;
|
2017-06-29 14:46:11 +03:00
|
|
|
AutoTArray<nsCOMPtr<nsIRunnable>, 16> mEarlyRunners;
|
2017-08-10 04:08:38 +03:00
|
|
|
ScrollEventArray mScrollEvents;
|
2011-11-10 01:39:16 +04:00
|
|
|
|
2015-07-02 12:12:31 +03:00
|
|
|
struct PendingEvent {
|
|
|
|
nsCOMPtr<nsINode> mTarget;
|
2018-04-05 20:42:41 +03:00
|
|
|
RefPtr<mozilla::dom::Event> mEvent;
|
2015-07-02 12:12:31 +03:00
|
|
|
};
|
|
|
|
|
2015-05-05 17:56:01 +03:00
|
|
|
AutoTArray<nsIPresShell*, 16> mResizeEventFlushObservers;
|
2016-02-02 18:36:30 +03:00
|
|
|
AutoTArray<nsIPresShell*, 16> mStyleFlushObservers;
|
|
|
|
AutoTArray<nsIPresShell*, 16> mLayoutFlushObservers;
|
2010-08-12 01:05:28 +04:00
|
|
|
// nsTArray on purpose, because we want to be able to swap.
|
2011-11-28 16:48:30 +04:00
|
|
|
nsTArray<nsIDocument*> mFrameRequestCallbackDocs;
|
2015-04-21 19:44:40 +03:00
|
|
|
nsTArray<nsIDocument*> mThrottledFrameRequestCallbackDocs;
|
2015-06-26 23:20:10 +03:00
|
|
|
nsTObserverArray<nsAPostRefreshObserver*> mPostRefreshObservers;
|
2015-07-02 12:12:31 +03:00
|
|
|
nsTArray<PendingEvent> mPendingEvents;
|
2018-01-27 15:17:27 +03:00
|
|
|
AutoTArray<mozilla::AnimationEventDispatcher*, 16>
|
|
|
|
mAnimationEventFlushObservers;
|
2011-03-04 18:27:02 +03:00
|
|
|
|
2015-10-23 07:16:45 +03:00
|
|
|
void BeginRefreshingImages(RequestTable& aEntries,
|
|
|
|
mozilla::TimeStamp aDesired);
|
2015-07-15 12:05:06 +03:00
|
|
|
|
2012-12-12 02:15:32 +04:00
|
|
|
friend class mozilla::RefreshDriverTimer;
|
|
|
|
|
2016-06-06 16:51:15 +03:00
|
|
|
static void Shutdown();
|
|
|
|
|
2015-10-30 16:35:46 +03:00
|
|
|
// `true` if we are currently in jank-critical mode.
|
|
|
|
//
|
|
|
|
// In jank-critical mode, any iteration of the event loop that takes
|
|
|
|
// more than 16ms to compute will cause an ongoing animation to miss
|
|
|
|
// frames.
|
|
|
|
//
|
|
|
|
// For simplicity, the current implementation assumes that we are
|
|
|
|
// in jank-critical mode if and only if the vsync driver has at least
|
|
|
|
// one observer.
|
|
|
|
static bool IsJankCritical();
|
2009-10-08 07:22:42 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* !defined(nsRefreshDriver_h_) */
|