зеркало из https://github.com/mozilla/pjs.git
Bug 630127. Use a precise timer when we have animation frame callbacks. r=dbaron
This commit is contained in:
Родитель
ebb2194875
Коммит
a477fc5489
|
@ -58,6 +58,15 @@ using mozilla::TimeStamp;
|
|||
#define DEFAULT_FRAME_RATE 60
|
||||
#define DEFAULT_THROTTLED_FRAME_RATE 1
|
||||
|
||||
static PRBool sPrecisePref;
|
||||
|
||||
/* static */ void
|
||||
nsRefreshDriver::InitializeStatics()
|
||||
{
|
||||
nsContentUtils::AddBoolPrefVarCache("layout.frame_rate.precise",
|
||||
&sPrecisePref,
|
||||
PR_FALSE);
|
||||
}
|
||||
// Compute the interval to use for the refresh driver timer, in
|
||||
// milliseconds
|
||||
PRInt32
|
||||
|
@ -85,16 +94,17 @@ nsRefreshDriver::GetRefreshTimerType() const
|
|||
if (mThrottled) {
|
||||
return nsITimer::TYPE_ONE_SHOT;
|
||||
}
|
||||
PRBool precise =
|
||||
nsContentUtils::GetBoolPref("layout.frame_rate.precise", PR_FALSE);
|
||||
return precise ? (PRInt32)nsITimer::TYPE_REPEATING_PRECISE
|
||||
: (PRInt32)nsITimer::TYPE_REPEATING_SLACK;
|
||||
if (HaveAnimationFrameListeners() || sPrecisePref) {
|
||||
return nsITimer::TYPE_REPEATING_PRECISE;
|
||||
}
|
||||
return nsITimer::TYPE_REPEATING_SLACK;
|
||||
}
|
||||
|
||||
nsRefreshDriver::nsRefreshDriver(nsPresContext *aPresContext)
|
||||
: mPresContext(aPresContext),
|
||||
mFrozen(false),
|
||||
mThrottled(false)
|
||||
mThrottled(false),
|
||||
mTimerIsPrecise(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -157,9 +167,12 @@ nsRefreshDriver::EnsureTimerStarted()
|
|||
return;
|
||||
}
|
||||
|
||||
PRInt32 timerType = GetRefreshTimerType();
|
||||
mTimerIsPrecise = (timerType == nsITimer::TYPE_REPEATING_PRECISE);
|
||||
|
||||
nsresult rv = mTimer->InitWithCallback(this,
|
||||
GetRefreshTimerInterval(),
|
||||
GetRefreshTimerType());
|
||||
timerType);
|
||||
if (NS_FAILED(rv)) {
|
||||
mTimer = nsnull;
|
||||
}
|
||||
|
@ -338,12 +351,19 @@ nsRefreshDriver::Notify(nsITimer * /* unused */)
|
|||
}
|
||||
}
|
||||
|
||||
if (mThrottled) {
|
||||
// Stop the timer now and restart it here. Stopping is ok because either
|
||||
// it's already one-shot, and it just fired, and all we need to do is null
|
||||
// it out, or it's repeating and we need to reset it to be one-shot. Note
|
||||
// that the EnsureTimerStarted() call here is ok because EnsureTimerStarted
|
||||
// makes sure to not start the timer if it shouldn't be started.
|
||||
if (mThrottled ||
|
||||
(mTimerIsPrecise !=
|
||||
(GetRefreshTimerType() == nsITimer::TYPE_REPEATING_PRECISE))) {
|
||||
// Stop the timer now and restart it here. Stopping is in the mThrottled
|
||||
// case ok because either it's already one-shot, and it just fired, and all
|
||||
// we need to do is null it out, or it's repeating and we need to reset it
|
||||
// to be one-shot. Stopping and restarting in the case when we need to
|
||||
// switch from precise to slack timers or vice versa is unfortunately
|
||||
// required.
|
||||
|
||||
// Note that the EnsureTimerStarted() call here is ok because
|
||||
// EnsureTimerStarted makes sure to not start the timer if it shouldn't be
|
||||
// started.
|
||||
StopTimer();
|
||||
EnsureTimerStarted();
|
||||
}
|
||||
|
@ -421,6 +441,8 @@ nsRefreshDriver::ScheduleAnimationFrameListeners(nsIDocument* aDocument)
|
|||
mAnimationFrameListenerDocs.NoIndex,
|
||||
"Don't schedule the same document multiple times");
|
||||
mAnimationFrameListenerDocs.AppendElement(aDocument);
|
||||
// No need to worry about restarting our timer in precise mode if it's
|
||||
// already running; that will happen automatically when it fires.
|
||||
EnsureTimerStarted();
|
||||
}
|
||||
|
||||
|
@ -434,4 +456,6 @@ void
|
|||
nsRefreshDriver::RevokeAnimationFrameListeners(nsIDocument* aDocument)
|
||||
{
|
||||
mAnimationFrameListenerDocs.RemoveElement(aDocument);
|
||||
// No need to worry about restarting our timer in slack mode if it's already
|
||||
// running; that will happen automatically when it fires.
|
||||
}
|
||||
|
|
|
@ -79,6 +79,8 @@ public:
|
|||
nsRefreshDriver(nsPresContext *aPresContext);
|
||||
~nsRefreshDriver();
|
||||
|
||||
static void InitializeStatics();
|
||||
|
||||
// nsISupports implementation
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
@ -221,6 +223,10 @@ private:
|
|||
PRInt32 GetRefreshTimerInterval() const;
|
||||
PRInt32 GetRefreshTimerType() const;
|
||||
|
||||
bool HaveAnimationFrameListeners() const {
|
||||
return mAnimationFrameListenerDocs.Length() != 0;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
mozilla::TimeStamp mMostRecentRefresh; // only valid when mTimer non-null
|
||||
PRInt64 mMostRecentRefreshEpochTime; // same thing as mMostRecentRefresh,
|
||||
|
@ -231,6 +237,10 @@ private:
|
|||
|
||||
bool mFrozen;
|
||||
bool mThrottled;
|
||||
/* If mTimer is non-null, this boolean indicates whether the timer is
|
||||
a precise timer. If mTimer is null, this boolean's value can be
|
||||
anything. */
|
||||
bool mTimerIsPrecise;
|
||||
|
||||
// separate arrays for each flush type we support
|
||||
ObserverArray mObservers[3];
|
||||
|
|
|
@ -128,6 +128,7 @@
|
|||
#include "nsJSEnvironment.h"
|
||||
#include "nsContentSink.h"
|
||||
#include "nsFrameMessageManager.h"
|
||||
#include "nsRefreshDriver.h"
|
||||
|
||||
extern void NS_ShutdownChainItemPool();
|
||||
|
||||
|
@ -273,6 +274,7 @@ nsLayoutStatics::Initialize()
|
|||
nsContentSink::InitializeStatics();
|
||||
nsHtml5Module::InitializeStatics();
|
||||
nsIPresShell::InitializeStatics();
|
||||
nsRefreshDriver::InitializeStatics();
|
||||
|
||||
nsCrossSiteListenerProxy::Startup();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче