Bug 1415780 - Don't count all observers for nsRefreshDriver. r=smaug

We just need information whether there is still an observer or not in most
cases.  The only case we need to know the count is in an assertion in the
dtor of nsRefreshDriver.  In the dtor we are checking there remains no
observers other than early runners.

Note that the order in HasObserver() was adjusted to reflect that we check
boolean flag first (mViewManagerFlushIsPending) and subsequently check observer
which is likey happen to.  mFrameRequestCallbackDocs should have checked prior
to mResizeEventFlushObservers though.

MozReview-Commit-ID: E1qplusqw1Y

--HG--
extra : rebase_source : ebd9e6eb08952df954c55860638233c9a8729856
This commit is contained in:
Hiroyuki Ikezoe 2018-01-27 21:17:26 +09:00
Родитель f4d1fdc0b1
Коммит 357f94c98c
2 изменённых файлов: 33 добавлений и 10 удалений

Просмотреть файл

@ -1439,14 +1439,35 @@ nsRefreshDriver::ObserverCount() const
return sum;
}
uint32_t
nsRefreshDriver::ImageRequestCount() const
bool
nsRefreshDriver::HasObservers() const
{
uint32_t count = 0;
for (auto iter = mStartTable.ConstIter(); !iter.Done(); iter.Next()) {
count += iter.UserData()->mEntries.Count();
for (uint32_t i = 0; i < ArrayLength(mObservers); ++i) {
if (!mObservers[i].IsEmpty()) {
return true;
}
}
return count + mRequests.Count();
return mViewManagerFlushIsPending ||
!mStyleFlushObservers.IsEmpty() ||
!mLayoutFlushObservers.IsEmpty() ||
!mResizeEventFlushObservers.IsEmpty() ||
!mPendingEvents.IsEmpty() ||
!mFrameRequestCallbackDocs.IsEmpty() ||
!mThrottledFrameRequestCallbackDocs.IsEmpty() ||
!mEarlyRunners.IsEmpty();
}
bool
nsRefreshDriver::HasImageRequests() const
{
for (auto iter = mStartTable.ConstIter(); !iter.Done(); iter.Next()) {
if (!iter.UserData()->mEntries.IsEmpty()) {
return true;
}
}
return !mRequests.IsEmpty();
}
nsRefreshDriver::ObserverArray&
@ -1818,7 +1839,8 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
mWarningThreshold = 1;
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
if (!presShell || (ObserverCount() == 0 && ImageRequestCount() == 0 && mScrollEvents.Length() == 0)) {
if (!presShell ||
(!HasObservers() && !HasImageRequests() && mScrollEvents.IsEmpty())) {
// Things are being destroyed, or we no longer have any observers.
// We don't want to stop the timer when observers are initially
// removed, because sometimes observers can be added and removed
@ -2140,7 +2162,7 @@ nsRefreshDriver::Thaw()
}
if (mFreezeCount == 0) {
if (ObserverCount() || ImageRequestCount()) {
if (HasObservers() || HasImageRequests()) {
// FIXME: This isn't quite right, since our EnsureTimerStarted call
// updates our mMostRecentRefresh, but the DoRefresh call won't run
// and notify our observers until we get back to the event loop.
@ -2165,7 +2187,7 @@ nsRefreshDriver::FinishedWaitingForTransaction()
mWaitingForTransaction = false;
if (mSkippedPaints &&
!IsInRefresh() &&
(ObserverCount() || ImageRequestCount())) {
(HasObservers() || HasImageRequests())) {
AUTO_PROFILER_TRACING("Paint", "RefreshDriverTick");
DoRefresh();
}

Просмотреть файл

@ -397,8 +397,9 @@ private:
void EnsureTimerStarted(EnsureTimerStartedFlags aFlags = eNone);
void StopTimer();
bool HasObservers() const;
uint32_t ObserverCount() const;
uint32_t ImageRequestCount() const;
bool HasImageRequests() const;
ObserverArray& ArrayFor(mozilla::FlushType aFlushType);
// Trigger a refresh immediately, if haven't been disconnected or frozen.
void DoRefresh();