Bug 1351275: Move style flush observer logic to nsIPresShell, and align layout observing code. r=bholley

MozReview-Commit-ID: 2oUTNfTS4Ku
Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>

--HG--
extra : rebase_source : 97d055e6682cbe81eaf32c365004f194a0ae1935
This commit is contained in:
Emilio Cobos Álvarez 2017-03-29 15:41:11 +02:00
Родитель c066af0f0e
Коммит fc80cf434d
5 изменённых файлов: 53 добавлений и 37 удалений

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

@ -466,7 +466,7 @@ struct nsCallbackEventRequest
// ----------------------------------------------------------------------------
#define ASSERT_REFLOW_SCHEDULED_STATE() \
NS_ASSERTION(mReflowScheduled == \
NS_ASSERTION(ObservingLayoutFlushes() == \
GetPresContext()->RefreshDriver()-> \
IsLayoutFlushObserver(this), "Unexpected state")
@ -794,11 +794,12 @@ nsIPresShell::nsIPresShell()
, mFrozen(false)
, mIsFirstPaint(false)
, mObservesMutationsForPrint(false)
, mReflowScheduled(false)
, mSuppressInterruptibleReflows(false)
, mScrollPositionClampingScrollPortSizeSet(false)
, mNeedLayoutFlush(true)
, mNeedStyleFlush(true)
, mObservingStyleFlushes(false)
, mObservingLayoutFlushes(false)
, mNeedThrottledAnimationFlush(true)
, mPresShellId(0)
, mFontSizeInflationEmPerLine(0)
@ -1827,7 +1828,7 @@ PresShell::Initialize(nscoord aWidth, nscoord aHeight)
FrameNeedsReflow(rootFrame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
NS_ASSERTION(mDirtyRoots.Contains(rootFrame),
"Should be in mDirtyRoots now");
NS_ASSERTION(mReflowScheduled, "Why no reflow scheduled?");
NS_ASSERTION(mObservingLayoutFlushes, "Why no reflow scheduled?");
}
// Restore our root scroll position now if we're getting here after EndLoad
@ -2864,9 +2865,9 @@ PresShell::CancelAllPendingReflows()
{
mDirtyRoots.Clear();
if (mReflowScheduled) {
if (mObservingLayoutFlushes) {
GetPresContext()->RefreshDriver()->RemoveLayoutFlushObserver(this);
mReflowScheduled = false;
mObservingLayoutFlushes = false;
}
ASSERT_REFLOW_SCHEDULED_STATE();
@ -9080,8 +9081,8 @@ void
PresShell::MaybeScheduleReflow()
{
ASSERT_REFLOW_SCHEDULED_STATE();
if (mReflowScheduled || mIsDestroying || mIsReflowing ||
mDirtyRoots.Length() == 0)
if (mObservingLayoutFlushes || mIsDestroying || mIsReflowing ||
mDirtyRoots.IsEmpty())
return;
if (!mPresContext->HasPendingInterrupt() || !ScheduleReflowOffTimer()) {
@ -9094,13 +9095,8 @@ PresShell::MaybeScheduleReflow()
void
PresShell::ScheduleReflow()
{
NS_PRECONDITION(!mReflowScheduled, "Why are we trying to schedule a reflow?");
ASSERT_REFLOW_SCHEDULED_STATE();
if (GetPresContext()->RefreshDriver()->AddLayoutFlushObserver(this)) {
mReflowScheduled = true;
}
DoObserveLayoutFlushes();
ASSERT_REFLOW_SCHEDULED_STATE();
}
@ -9175,7 +9171,7 @@ PresShell::sReflowContinueCallback(nsITimer* aTimer, void* aPresShell)
bool
PresShell::ScheduleReflowOffTimer()
{
NS_PRECONDITION(!mReflowScheduled, "Shouldn't get here");
NS_PRECONDITION(!mObservingLayoutFlushes, "Shouldn't get here");
ASSERT_REFLOW_SCHEDULED_STATE();
if (!mReflowContinueTimer) {
@ -9732,6 +9728,22 @@ nsIPresShell::RemovePostRefreshObserver(nsAPostRefreshObserver* aObserver)
return true;
}
void
nsIPresShell::DoObserveStyleFlushes()
{
MOZ_ASSERT(!ObservingStyleFlushes());
mObservingStyleFlushes =
mPresContext->RefreshDriver()->AddStyleFlushObserver(this);
}
void
nsIPresShell::DoObserveLayoutFlushes()
{
MOZ_ASSERT(!ObservingLayoutFlushes());
mObservingLayoutFlushes =
mPresContext->RefreshDriver()->AddLayoutFlushObserver(this);
}
//------------------------------------------------------
// End of protected and private methods on the PresShell
//------------------------------------------------------

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

@ -18,7 +18,6 @@ RestyleManager::RestyleManager(StyleBackendType aType,
, mRestyleGeneration(1)
, mHoverGeneration(0)
, mType(aType)
, mObservingRefreshDriver(false)
, mInStyleRefresh(false)
{
MOZ_ASSERT(mPresContext);
@ -503,9 +502,8 @@ RestyleManager::PostRestyleEventInternal(bool aForLazyConstruction)
// add ourselves as a refresh observer until then.
bool inRefresh = !aForLazyConstruction && mInStyleRefresh;
nsIPresShell* presShell = PresContext()->PresShell();
if (!ObservingRefreshDriver() && !inRefresh) {
SetObservingRefreshDriver(PresContext()->RefreshDriver()->
AddStyleFlushObserver(presShell));
if (!inRefresh) {
presShell->ObserveStyleFlushes();
}
// Unconditionally flag our document as needing a flush. The other

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

@ -44,12 +44,6 @@ public:
// as a result of a change to the :hover content state.
uint32_t GetHoverGeneration() const { return mHoverGeneration; }
bool ObservingRefreshDriver() const { return mObservingRefreshDriver; }
void SetObservingRefreshDriver(bool aObserving) {
mObservingRefreshDriver = aObserving;
}
void Disconnect() { mPresContext = nullptr; }
static nsCString RestyleHintToString(nsRestyleHint aHint);
@ -235,9 +229,6 @@ private:
const StyleBackendType mType;
// True if we're already waiting for a refresh notification.
bool mObservingRefreshDriver;
protected:
// True if we're in the middle of a nsRefreshDriver refresh
bool mInStyleRefresh;

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

@ -643,7 +643,16 @@ public:
inline void SetNeedLayoutFlush();
inline void SetNeedThrottledAnimationFlush();
bool NeedStyleFlush() { return mNeedStyleFlush; }
bool ObservingStyleFlushes() const { return mObservingStyleFlushes; }
bool ObservingLayoutFlushes() const { return mObservingLayoutFlushes; }
void ObserveStyleFlushes()
{
if (!ObservingStyleFlushes())
DoObserveStyleFlushes();
}
bool NeedStyleFlush() const { return mNeedStyleFlush; }
/**
* Callbacks will be called even if reflow itself fails for
@ -1701,6 +1710,9 @@ protected:
bool RemoveRefreshObserverInternal(nsARefreshObserver* aObserver,
mozilla::FlushType aFlushType);
void DoObserveStyleFlushes();
void DoObserveLayoutFlushes();
/**
* Do computations necessary to determine if font size inflation is enabled.
* This value is cached after computation, as the computation is somewhat
@ -1791,7 +1803,7 @@ public:
}
bool HasPendingReflow() const
{ return mReflowScheduled || mReflowContinueTimer; }
{ return mObservingLayoutFlushes || mReflowContinueTimer; }
void SyncWindowProperties(nsView* aView);
@ -1888,10 +1900,6 @@ protected:
bool mIsFirstPaint : 1;
bool mObservesMutationsForPrint : 1;
// If true, we have a reflow scheduled. Guaranteed to be false if
// mReflowContinueTimer is non-null.
bool mReflowScheduled : 1;
bool mSuppressInterruptibleReflows : 1;
bool mScrollPositionClampingScrollPortSizeSet : 1;
@ -1901,6 +1909,15 @@ protected:
// True if a style flush might not be a no-op
bool mNeedStyleFlush : 1;
// True if we're observing the refresh driver for style flushes.
bool mObservingStyleFlushes: 1;
// True if we're observing the refresh driver for layout flushes, that is, if
// we have a reflow scheduled.
//
// Guaranteed to be false if mReflowContinueTimer is non-null.
bool mObservingLayoutFlushes: 1;
// True if there are throttled animations that would be processed when
// performing a flush with mFlushAnimations == true.
bool mNeedThrottledAnimationFlush : 1;

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

@ -1868,9 +1868,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
}
nsCOMPtr<nsIPresShell> shellKungFuDeathGrip(shell);
RestyleManager* restyleManager =
shell->GetPresContext()->RestyleManager();
restyleManager->SetObservingRefreshDriver(false);
shell->mObservingStyleFlushes = false;
shell->FlushPendingNotifications(ChangesToFlush(FlushType::Style, false));
// Inform the FontFaceSet that we ticked, so that it can resolve its
// ready promise if it needs to (though it might still be waiting on
@ -1901,7 +1899,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
}
nsCOMPtr<nsIPresShell> shellKungFuDeathGrip(shell);
shell->mReflowScheduled = false;
shell->mObservingLayoutFlushes = false;
shell->mSuppressInterruptibleReflows = false;
FlushType flushType = HasPendingAnimations(shell)
? FlushType::Layout