mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 14:25:52 +00:00
Bug 1210261. Tick root refresh driver last. r=mattwoodrow
This commit is contained in:
parent
5219bd1cea
commit
675f9bf1f2
@ -104,17 +104,24 @@ public:
|
||||
|
||||
virtual ~RefreshDriverTimer()
|
||||
{
|
||||
NS_ASSERTION(mRefreshDrivers.Length() == 0, "Should have removed all refresh drivers from here by now!");
|
||||
MOZ_ASSERT(mContentRefreshDrivers.Length() == 0, "Should have removed all content refresh drivers from here by now!");
|
||||
MOZ_ASSERT(mRootRefreshDrivers.Length() == 0, "Should have removed all root refresh drivers from here by now!");
|
||||
}
|
||||
|
||||
virtual void AddRefreshDriver(nsRefreshDriver* aDriver)
|
||||
{
|
||||
LOG("[%p] AddRefreshDriver %p", this, aDriver);
|
||||
|
||||
NS_ASSERTION(!mRefreshDrivers.Contains(aDriver), "AddRefreshDriver for a refresh driver that's already in the list!");
|
||||
mRefreshDrivers.AppendElement(aDriver);
|
||||
bool startTimer = mContentRefreshDrivers.IsEmpty() && mRootRefreshDrivers.IsEmpty();
|
||||
if (IsRootRefreshDriver(aDriver)) {
|
||||
NS_ASSERTION(!mRootRefreshDrivers.Contains(aDriver), "Adding a duplicate root refresh driver!");
|
||||
mRootRefreshDrivers.AppendElement(aDriver);
|
||||
} else {
|
||||
NS_ASSERTION(!mContentRefreshDrivers.Contains(aDriver), "Adding a duplicate content refresh driver!");
|
||||
mContentRefreshDrivers.AppendElement(aDriver);
|
||||
}
|
||||
|
||||
if (mRefreshDrivers.Length() == 1) {
|
||||
if (startTimer) {
|
||||
StartTimer();
|
||||
}
|
||||
}
|
||||
@ -123,10 +130,30 @@ public:
|
||||
{
|
||||
LOG("[%p] RemoveRefreshDriver %p", this, aDriver);
|
||||
|
||||
NS_ASSERTION(mRefreshDrivers.Contains(aDriver), "RemoveRefreshDriver for a refresh driver that's not in the list!");
|
||||
mRefreshDrivers.RemoveElement(aDriver);
|
||||
if (IsRootRefreshDriver(aDriver)) {
|
||||
NS_ASSERTION(mRootRefreshDrivers.Contains(aDriver), "RemoveRefreshDriver for a refresh driver that's not in the root refresh list!");
|
||||
mRootRefreshDrivers.RemoveElement(aDriver);
|
||||
} else {
|
||||
nsPresContext* displayRoot = aDriver->PresContext()->GetDisplayRootPresContext();
|
||||
// During PresContext shutdown, we can't accurately detect
|
||||
// if a root refresh driver exists or not. Therefore, we have to
|
||||
// search and find out which list this driver exists in.
|
||||
if (!displayRoot) {
|
||||
if (mRootRefreshDrivers.Contains(aDriver)) {
|
||||
mRootRefreshDrivers.RemoveElement(aDriver);
|
||||
} else {
|
||||
NS_ASSERTION(mContentRefreshDrivers.Contains(aDriver),
|
||||
"RemoveRefreshDriver without a display root for a driver that is not in the content refresh list");
|
||||
mContentRefreshDrivers.RemoveElement(aDriver);
|
||||
}
|
||||
} else {
|
||||
NS_ASSERTION(mContentRefreshDrivers.Contains(aDriver), "RemoveRefreshDriver for a driver that is not in the content refresh list");
|
||||
mContentRefreshDrivers.RemoveElement(aDriver);
|
||||
}
|
||||
}
|
||||
|
||||
if (mRefreshDrivers.Length() == 0) {
|
||||
bool stopTimer = mContentRefreshDrivers.IsEmpty() && mRootRefreshDrivers.IsEmpty();
|
||||
if (stopTimer) {
|
||||
StopTimer();
|
||||
}
|
||||
}
|
||||
@ -138,11 +165,17 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
for (nsRefreshDriver* driver : mRefreshDrivers) {
|
||||
for (nsRefreshDriver* driver : mContentRefreshDrivers) {
|
||||
aNewTimer->AddRefreshDriver(driver);
|
||||
driver->mActiveTimer = aNewTimer;
|
||||
}
|
||||
mRefreshDrivers.Clear();
|
||||
mContentRefreshDrivers.Clear();
|
||||
|
||||
for (nsRefreshDriver* driver : mRootRefreshDrivers) {
|
||||
aNewTimer->AddRefreshDriver(driver);
|
||||
driver->mActiveTimer = aNewTimer;
|
||||
}
|
||||
mRootRefreshDrivers.Clear();
|
||||
|
||||
aNewTimer->mLastFireEpoch = mLastFireEpoch;
|
||||
aNewTimer->mLastFireTime = mLastFireTime;
|
||||
@ -153,6 +186,17 @@ protected:
|
||||
virtual void StopTimer() = 0;
|
||||
virtual void ScheduleNextTick(TimeStamp aNowTime) = 0;
|
||||
|
||||
bool IsRootRefreshDriver(nsRefreshDriver* aDriver)
|
||||
{
|
||||
nsPresContext* displayRoot = aDriver->PresContext()->GetDisplayRootPresContext();
|
||||
if (!displayRoot) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefreshDriver* rootRefreshDriver = displayRoot->GetRootPresContext()->RefreshDriver();
|
||||
return aDriver == rootRefreshDriver;
|
||||
}
|
||||
|
||||
/*
|
||||
* Actually runs a tick, poking all the attached RefreshDrivers.
|
||||
* Grabs the "now" time via JS_Now and TimeStamp::Now().
|
||||
@ -164,6 +208,23 @@ protected:
|
||||
Tick(jsnow, now);
|
||||
}
|
||||
|
||||
void TickRefreshDrivers(int64_t aJsNow, TimeStamp aNow, nsTArray<RefPtr<nsRefreshDriver>>& aDrivers)
|
||||
{
|
||||
if (aDrivers.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<RefPtr<nsRefreshDriver> > drivers(aDrivers);
|
||||
for (nsRefreshDriver* driver : drivers) {
|
||||
// don't poke this driver if it's in test mode
|
||||
if (driver->IsTestControllingRefreshesEnabled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TickDriver(driver, aJsNow, aNow);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Tick the refresh drivers based on the given timestamp.
|
||||
*/
|
||||
@ -175,17 +236,12 @@ protected:
|
||||
mLastFireTime = now;
|
||||
|
||||
LOG("[%p] ticking drivers...", this);
|
||||
nsTArray<RefPtr<nsRefreshDriver> > drivers(mRefreshDrivers);
|
||||
// RD is short for RefreshDriver
|
||||
profiler_tracing("Paint", "RD", TRACING_INTERVAL_START);
|
||||
for (nsRefreshDriver* driver : drivers) {
|
||||
// don't poke this driver if it's in test mode
|
||||
if (driver->IsTestControllingRefreshesEnabled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TickDriver(driver, jsnow, now);
|
||||
}
|
||||
TickRefreshDrivers(jsnow, now, mContentRefreshDrivers);
|
||||
TickRefreshDrivers(jsnow, now, mRootRefreshDrivers);
|
||||
|
||||
profiler_tracing("Paint", "RD", TRACING_INTERVAL_END);
|
||||
LOG("[%p] done.", this);
|
||||
}
|
||||
@ -200,7 +256,8 @@ protected:
|
||||
TimeStamp mLastFireTime;
|
||||
TimeStamp mTargetTime;
|
||||
|
||||
nsTArray<RefPtr<nsRefreshDriver> > mRefreshDrivers;
|
||||
nsTArray<RefPtr<nsRefreshDriver> > mContentRefreshDrivers;
|
||||
nsTArray<RefPtr<nsRefreshDriver> > mRootRefreshDrivers;
|
||||
|
||||
// useful callback for nsITimer-based derived classes, here
|
||||
// bacause of c++ protected shenanigans
|
||||
@ -558,13 +615,18 @@ public:
|
||||
|
||||
// we don't really have to start with the newly added one, but we may as well
|
||||
// not tick the old ones at the fastest rate any more than we need to.
|
||||
mNextDriverIndex = mRefreshDrivers.Length() - 1;
|
||||
mNextDriverIndex = GetRefreshDriverCount() - 1;
|
||||
|
||||
StopTimer();
|
||||
StartTimer();
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32_t GetRefreshDriverCount()
|
||||
{
|
||||
return mContentRefreshDrivers.Length() + mRootRefreshDrivers.Length();
|
||||
}
|
||||
|
||||
virtual void StartTimer()
|
||||
{
|
||||
mLastFireEpoch = JS_Now();
|
||||
@ -593,7 +655,7 @@ protected:
|
||||
}
|
||||
|
||||
// double the next tick time if we've already gone through all of them once
|
||||
if (mNextDriverIndex >= mRefreshDrivers.Length()) {
|
||||
if (mNextDriverIndex >= GetRefreshDriverCount()) {
|
||||
mNextTickDuration *= 2.0;
|
||||
mNextDriverIndex = 0;
|
||||
}
|
||||
@ -603,7 +665,7 @@ protected:
|
||||
mTimer->InitWithFuncCallback(TimerTickOne, this, delay, nsITimer::TYPE_ONE_SHOT);
|
||||
|
||||
LOG("[%p] inactive timer next tick in %f ms [index %d/%d]", this, mNextTickDuration,
|
||||
mNextDriverIndex, mRefreshDrivers.Length());
|
||||
mNextDriverIndex, GetRefreshDriverCount());
|
||||
}
|
||||
|
||||
/* Runs just one driver's tick. */
|
||||
@ -617,7 +679,9 @@ protected:
|
||||
mLastFireEpoch = jsnow;
|
||||
mLastFireTime = now;
|
||||
|
||||
nsTArray<RefPtr<nsRefreshDriver> > drivers(mRefreshDrivers);
|
||||
nsTArray<RefPtr<nsRefreshDriver> > drivers(mContentRefreshDrivers);
|
||||
drivers.AppendElements(mRootRefreshDrivers);
|
||||
|
||||
if (mNextDriverIndex < drivers.Length() &&
|
||||
!drivers[mNextDriverIndex]->IsTestControllingRefreshesEnabled())
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user