diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index c946f0954ead..dace0bc7216b 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -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 //------------------------------------------------------ diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 2287e609fa74..85a5c65fc6f2 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -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 diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 39e06efd2435..ae08b8220567 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -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; diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 777713f7d4ba..5f44b3029a41 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -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; diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index c57686a3cc25..c4deb3b286f9 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -1868,9 +1868,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) } nsCOMPtr 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 shellKungFuDeathGrip(shell); - shell->mReflowScheduled = false; + shell->mObservingLayoutFlushes = false; shell->mSuppressInterruptibleReflows = false; FlushType flushType = HasPendingAnimations(shell) ? FlushType::Layout