From b8e6ffef574c0dd7a607100626cf1d4c40b06e72 Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Tue, 13 Jan 2015 21:03:12 -0800 Subject: [PATCH] Bug 1115812 patch 11 - Move the beginning part of the rebuild-all process to StartRebuildAllStyleData. r=heycam Here we call StartRebuildAllStyleData from BeginProcessingRestyles (much like patch 9 and EndProcessingRestyles). But we will later also call it from the code that handles a root element font size change when we have 'rem' units. That's because it's fine to *start* the rebuild process in the middle of processing the queue of pending restyles. (We have to end after the whole process is done, though, in order to avoid wanting to destroy the old rule tree while we still have style contexts referencing it.) We only call StartRebuildAllStyleData in this case when we're processing our primary restyle queue (mPendingRestyles), not the animation restyles (to be removed in bug 960465) or the animation-only restyles, since a rebuild-all should be processed (in terms of animation phases, or in terms of having an animation-only update before it) like a normal restyle. (This isn't true for the 'rem' unit restyle, which could happen during any sort of update.) --- layout/base/RestyleManager.cpp | 28 ++++++++++++++++++++-------- layout/base/RestyleManager.h | 11 +++++++++-- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 6c684a3f8006..40c0a96abe53 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -1479,13 +1479,14 @@ RestyleManager::RebuildAllStyleData(nsChangeHint aExtraHint, "Should not reconstruct the root of the frame tree. " "Use ReconstructDocElementHierarchy instead."); - mDoRebuildAllStyleData = false; NS_UpdateHint(mRebuildAllExtraHint, aExtraHint); mRebuildAllRestyleHint |= aRestyleHint; nsIPresShell* presShell = mPresContext->GetPresShell(); - if (!presShell || !presShell->GetRootFrame()) + if (!presShell || !presShell->GetRootFrame()) { + mDoRebuildAllStyleData = false; return; + } // Make sure that the viewmanager will outlive the presshell nsRefPtr vm = presShell->GetViewManager(); @@ -1528,9 +1529,9 @@ RestyleManager::RebuildAllStyleData(nsChangeHint aExtraHint, } void -RestyleManager::DoRebuildAllStyleData(RestyleTracker& aRestyleTracker) +RestyleManager::StartRebuildAllStyleData(RestyleTracker& aRestyleTracker) { - BeginProcessingRestyles(aRestyleTracker); + MOZ_ASSERT(mIsProcessingRestyles); mInRebuildAllStyleData = true; @@ -1538,7 +1539,7 @@ RestyleManager::DoRebuildAllStyleData(RestyleTracker& aRestyleTracker) // so we can recalculate while maintaining rule tree immutability nsresult rv = mPresContext->StyleSet()->BeginReconstruct(); if (NS_FAILED(rv)) { - return; + MOZ_CRASH("unable to rebuild style data"); } nsRestyleHint restyleHint = mRebuildAllRestyleHint; @@ -1571,16 +1572,22 @@ RestyleManager::DoRebuildAllStyleData(RestyleTracker& aRestyleTracker) restyleHint = nsRestyleHint(0); } - // Recalculate all of the style contexts for the document + // Recalculate all of the style contexts for the document, from the + // root frame. We can't do this with a change hint, since we can't + // post a change hint for the root frame. // Note that we can ignore the return value of ComputeStyleChangeFor - // because we never need to reframe the root frame + // because we never need to reframe the root frame. // XXX Does it matter that we're passing aExtraHint to the real root // frame and not the root node's primary frame? (We could do // roughly what we do for aRestyleHint above.) - // Note: The restyle tracker we pass in here doesn't matter. ComputeAndProcessStyleChange(mPresContext->PresShell()->GetRootFrame(), changeHint, aRestyleTracker, restyleHint); +} +void +RestyleManager::DoRebuildAllStyleData(RestyleTracker& aRestyleTracker) +{ + BeginProcessingRestyles(aRestyleTracker); EndProcessingRestyles(); } @@ -1687,6 +1694,11 @@ RestyleManager::BeginProcessingRestyles(RestyleTracker& aRestyleTracker) mPresContext->FrameConstructor()->BeginUpdate(); mInStyleRefresh = true; + + if (ShouldStartRebuildAllFor(aRestyleTracker)) { + mDoRebuildAllStyleData = false; + StartRebuildAllStyleData(aRestyleTracker); + } } void diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 92b30602115d..f37568e3a9e7 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -453,6 +453,7 @@ private: RestyleTracker& aRestyleTracker, nsRestyleHint aRestyleHint); + void StartRebuildAllStyleData(RestyleTracker& aRestyleTracker); void FinishRebuildAllStyleData(); void StyleChangeReflow(nsIFrame* aFrame, nsChangeHint aHint); @@ -465,11 +466,17 @@ private: // be performed instead. bool RecomputePosition(nsIFrame* aFrame); + bool ShouldStartRebuildAllFor(RestyleTracker& aRestyleTracker) { + // When we process our primary restyle tracker and we have a pending + // rebuild-all, we need to process it. + return mDoRebuildAllStyleData && + &aRestyleTracker == &mPendingRestyles; + } + void ProcessRestyles(RestyleTracker& aRestyleTracker) { // Fast-path the common case (esp. for the animation restyle // tracker) of not having anything to do. - if (aRestyleTracker.Count() || - mInRebuildAllStyleData) { + if (aRestyleTracker.Count() || ShouldStartRebuildAllFor(aRestyleTracker)) { aRestyleTracker.DoProcessRestyles(); } }