Bug 840480 r=roc

This commit is contained in:
Matt Woodrow 2013-02-20 13:13:01 +13:00
parent 748b4717a1
commit bfb6ac7eab
6 changed files with 32 additions and 52 deletions

View File

@ -109,8 +109,7 @@ CollectRestyles(nsISupports* aElement,
inline void inline void
RestyleTracker::ProcessOneRestyle(Element* aElement, RestyleTracker::ProcessOneRestyle(Element* aElement,
nsRestyleHint aRestyleHint, nsRestyleHint aRestyleHint,
nsChangeHint aChangeHint, nsChangeHint aChangeHint)
OverflowChangedTracker& aTracker)
{ {
NS_PRECONDITION((aRestyleHint & eRestyle_LaterSiblings) == 0, NS_PRECONDITION((aRestyleHint & eRestyle_LaterSiblings) == 0,
"Someone should have handled this before calling us"); "Someone should have handled this before calling us");
@ -122,15 +121,14 @@ RestyleTracker::ProcessOneRestyle(Element* aElement,
if (aRestyleHint & (eRestyle_Self | eRestyle_Subtree)) { if (aRestyleHint & (eRestyle_Self | eRestyle_Subtree)) {
mFrameConstructor->RestyleElement(aElement, primaryFrame, aChangeHint, mFrameConstructor->RestyleElement(aElement, primaryFrame, aChangeHint,
*this, *this,
(aRestyleHint & eRestyle_Subtree) != 0, (aRestyleHint & eRestyle_Subtree) != 0);
aTracker);
} else if (aChangeHint && } else if (aChangeHint &&
(primaryFrame || (primaryFrame ||
(aChangeHint & nsChangeHint_ReconstructFrame))) { (aChangeHint & nsChangeHint_ReconstructFrame))) {
// Don't need to recompute style; just apply the hint // Don't need to recompute style; just apply the hint
nsStyleChangeList changeList; nsStyleChangeList changeList;
changeList.AppendChange(primaryFrame, aElement, aChangeHint); changeList.AppendChange(primaryFrame, aElement, aChangeHint);
mFrameConstructor->ProcessRestyledFrames(changeList, aTracker); mFrameConstructor->ProcessRestyledFrames(changeList);
} }
} }
@ -144,8 +142,6 @@ RestyleTracker::DoProcessRestyles()
mFrameConstructor->mInStyleRefresh = true; mFrameConstructor->mInStyleRefresh = true;
OverflowChangedTracker tracker;
// loop so that we process any restyle events generated by processing // loop so that we process any restyle events generated by processing
while (mPendingRestyles.Count()) { while (mPendingRestyles.Count()) {
if (mHaveLaterSiblingRestyles) { if (mHaveLaterSiblingRestyles) {
@ -210,7 +206,7 @@ RestyleTracker::DoProcessRestyles()
continue; continue;
} }
ProcessOneRestyle(element, data.mRestyleHint, data.mChangeHint, tracker); ProcessOneRestyle(element, data.mRestyleHint, data.mChangeHint);
} }
if (mHaveLaterSiblingRestyles) { if (mHaveLaterSiblingRestyles) {
@ -239,13 +235,12 @@ RestyleTracker::DoProcessRestyles()
++currentRestyle) { ++currentRestyle) {
ProcessOneRestyle(currentRestyle->mElement, ProcessOneRestyle(currentRestyle->mElement,
currentRestyle->mRestyleHint, currentRestyle->mRestyleHint,
currentRestyle->mChangeHint, currentRestyle->mChangeHint);
tracker);
} }
} }
} }
tracker.Flush(); mFrameConstructor->FlushOverflowChangedTracker();
// Set mInStyleRefresh to false now, since the EndUpdate call might // Set mInStyleRefresh to false now, since the EndUpdate call might
// add more restyles. // add more restyles.

View File

@ -31,6 +31,11 @@ class OverflowChangedTracker
{ {
public: public:
~OverflowChangedTracker()
{
NS_ASSERTION(mEntryList.empty(), "Need to flush before destroying!");
}
/** /**
* Add a frame that has had a style change, and needs its * Add a frame that has had a style change, and needs its
* overflow updated. * overflow updated.
@ -247,8 +252,7 @@ private:
*/ */
inline void ProcessOneRestyle(Element* aElement, inline void ProcessOneRestyle(Element* aElement,
nsRestyleHint aRestyleHint, nsRestyleHint aRestyleHint,
nsChangeHint aChangeHint, nsChangeHint aChangeHint);
OverflowChangedTracker& aTracker);
/** /**
* The guts of our restyle processing. * The guts of our restyle processing.

View File

@ -1437,7 +1437,6 @@ nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument *aDocument,
, mInStyleRefresh(false) , mInStyleRefresh(false)
, mHoverGeneration(0) , mHoverGeneration(0)
, mRebuildAllExtraHint(nsChangeHint(0)) , mRebuildAllExtraHint(nsChangeHint(0))
, mOverflowChangedTracker(nullptr)
, mAnimationGeneration(0) , mAnimationGeneration(0)
, mPendingRestyles(ELEMENT_HAS_PENDING_RESTYLE | , mPendingRestyles(ELEMENT_HAS_PENDING_RESTYLE |
ELEMENT_IS_POTENTIAL_RESTYLE_ROOT, this) ELEMENT_IS_POTENTIAL_RESTYLE_ROOT, this)
@ -1517,9 +1516,7 @@ nsCSSFrameConstructor::NotifyDestroyingFrame(nsIFrame* aFrame)
CountersDirty(); CountersDirty();
} }
if (mOverflowChangedTracker) { mOverflowChangedTracker.RemoveFrame(aFrame);
mOverflowChangedTracker->RemoveFrame(aFrame);
}
nsFrameManager::NotifyDestroyingFrame(aFrame); nsFrameManager::NotifyDestroyingFrame(aFrame);
} }
@ -8201,8 +8198,7 @@ NeedToReframeForAddingOrRemovingTransform(nsIFrame* aFrame)
} }
nsresult nsresult
nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList, nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
OverflowChangedTracker& aTracker)
{ {
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Someone forgot a script blocker"); "Someone forgot a script blocker");
@ -8212,10 +8208,6 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList,
SAMPLE_LABEL("CSS", "ProcessRestyledFrames"); SAMPLE_LABEL("CSS", "ProcessRestyledFrames");
MOZ_ASSERT(!GetOverflowChangedTracker(),
"Can't have multiple overflow changed trackers!");
SetOverflowChangedTracker(&aTracker);
// Make sure to not rebuild quote or counter lists while we're // Make sure to not rebuild quote or counter lists while we're
// processing restyles // processing restyles
BeginUpdate(); BeginUpdate();
@ -8346,7 +8338,7 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList,
// updating overflows since that will happen when it's reflowed. // updating overflows since that will happen when it's reflowed.
if (!(childFrame->GetStateBits() & if (!(childFrame->GetStateBits() &
(NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN))) { (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN))) {
aTracker.AddFrame(childFrame); mOverflowChangedTracker.AddFrame(childFrame);
} }
NS_ASSERTION(!nsLayoutUtils::GetNextContinuationOrSpecialSibling(childFrame), NS_ASSERTION(!nsLayoutUtils::GetNextContinuationOrSpecialSibling(childFrame),
"SVG frames should not have continuations or special siblings"); "SVG frames should not have continuations or special siblings");
@ -8359,7 +8351,7 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList,
if (!(frame->GetStateBits() & if (!(frame->GetStateBits() &
(NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN))) { (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN))) {
while (frame) { while (frame) {
aTracker.AddFrame(frame); mOverflowChangedTracker.AddFrame(frame);
frame = frame =
nsLayoutUtils::GetNextContinuationOrSpecialSibling(frame); nsLayoutUtils::GetNextContinuationOrSpecialSibling(frame);
@ -8401,7 +8393,6 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList,
#endif #endif
} }
SetOverflowChangedTracker(nullptr);
aChangeList.Clear(); aChangeList.Clear();
return NS_OK; return NS_OK;
} }
@ -8411,8 +8402,7 @@ nsCSSFrameConstructor::RestyleElement(Element *aElement,
nsIFrame *aPrimaryFrame, nsIFrame *aPrimaryFrame,
nsChangeHint aMinHint, nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker, RestyleTracker& aRestyleTracker,
bool aRestyleDescendants, bool aRestyleDescendants)
OverflowChangedTracker& aTracker)
{ {
NS_ASSERTION(aPrimaryFrame == aElement->GetPrimaryFrame(), NS_ASSERTION(aPrimaryFrame == aElement->GetPrimaryFrame(),
"frame/content mismatch"); "frame/content mismatch");
@ -8450,7 +8440,7 @@ nsCSSFrameConstructor::RestyleElement(Element *aElement,
nsStyleChangeList changeList; nsStyleChangeList changeList;
ComputeStyleChangeFor(aPrimaryFrame, &changeList, aMinHint, ComputeStyleChangeFor(aPrimaryFrame, &changeList, aMinHint,
aRestyleTracker, aRestyleDescendants); aRestyleTracker, aRestyleDescendants);
ProcessRestyledFrames(changeList, aTracker); ProcessRestyledFrames(changeList);
} else { } else {
// no frames, reconstruct for content // no frames, reconstruct for content
MaybeRecreateFramesForElement(aElement); MaybeRecreateFramesForElement(aElement);
@ -12234,9 +12224,8 @@ nsCSSFrameConstructor::DoRebuildAllStyleData(RestyleTracker& aRestyleTracker,
&changeList, aExtraHint, &changeList, aExtraHint,
aRestyleTracker, true); aRestyleTracker, true);
// Process the required changes // Process the required changes
OverflowChangedTracker tracker; ProcessRestyledFrames(changeList);
ProcessRestyledFrames(changeList, tracker); FlushOverflowChangedTracker();
tracker.Flush();
// Tell the style set it's safe to destroy the old rule tree. We // Tell the style set it's safe to destroy the old rule tree. We
// must do this after the ProcessRestyledFrames call in case the // must do this after the ProcessRestyledFrames call in case the

View File

@ -241,8 +241,7 @@ public:
// This function does not call ProcessAttachedQueue() on the binding manager. // This function does not call ProcessAttachedQueue() on the binding manager.
// If the caller wants that to happen synchronously, it needs to handle that // If the caller wants that to happen synchronously, it needs to handle that
// itself. // itself.
nsresult ProcessRestyledFrames(nsStyleChangeList& aRestyleArray, nsresult ProcessRestyledFrames(nsStyleChangeList& aRestyleArray);
OverflowChangedTracker& aTracker);
private: private:
@ -307,13 +306,9 @@ public:
PostRestyleEventCommon(aElement, aRestyleHint, aMinChangeHint, true); PostRestyleEventCommon(aElement, aRestyleHint, aMinChangeHint, true);
} }
OverflowChangedTracker *GetOverflowChangedTracker() const void FlushOverflowChangedTracker()
{
return mOverflowChangedTracker;
}
void SetOverflowChangedTracker(OverflowChangedTracker *aTracker)
{ {
mOverflowChangedTracker = aTracker; mOverflowChangedTracker.Flush();
} }
private: private:
@ -406,8 +401,7 @@ private:
nsIFrame* aPrimaryFrame, nsIFrame* aPrimaryFrame,
nsChangeHint aMinHint, nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker, RestyleTracker& aRestyleTracker,
bool aRestyleDescendants, bool aRestyleDescendants);
OverflowChangedTracker& aTracker);
nsresult InitAndRestoreFrame (const nsFrameConstructorState& aState, nsresult InitAndRestoreFrame (const nsFrameConstructorState& aState,
nsIContent* aContent, nsIContent* aContent,
@ -1914,7 +1908,7 @@ private:
nsCOMPtr<nsILayoutHistoryState> mTempFrameTreeState; nsCOMPtr<nsILayoutHistoryState> mTempFrameTreeState;
OverflowChangedTracker *mOverflowChangedTracker; OverflowChangedTracker mOverflowChangedTracker;
// The total number of animation flushes by this frame constructor. // The total number of animation flushes by this frame constructor.
// Used to keep the layer and animation manager in sync. // Used to keep the layer and animation manager in sync.

View File

@ -2734,9 +2734,8 @@ PresShell::RecreateFramesFor(nsIContent* aContent)
// Mark ourselves as not safe to flush while we're doing frame construction. // Mark ourselves as not safe to flush while we're doing frame construction.
++mChangeNestCount; ++mChangeNestCount;
css::OverflowChangedTracker tracker; nsresult rv = mFrameConstructor->ProcessRestyledFrames(changeList);
nsresult rv = mFrameConstructor->ProcessRestyledFrames(changeList, tracker); mFrameConstructor->FlushOverflowChangedTracker();
tracker.Flush();
--mChangeNestCount; --mChangeNestCount;
return rv; return rv;
@ -7899,9 +7898,8 @@ PresShell::Observe(nsISupports* aSubject,
{ {
nsAutoScriptBlocker scriptBlocker; nsAutoScriptBlocker scriptBlocker;
++mChangeNestCount; ++mChangeNestCount;
css::OverflowChangedTracker tracker; mFrameConstructor->ProcessRestyledFrames(changeList);
mFrameConstructor->ProcessRestyledFrames(changeList, tracker); mFrameConstructor->FlushOverflowChangedTracker();
tracker.Flush();
--mChangeNestCount; --mChangeNestCount;
} }
} }

View File

@ -429,10 +429,10 @@ nsTransitionManager::UpdateAllThrottledStyles()
} }
} }
OverflowChangedTracker tracker;
mPresContext->PresShell()->FrameConstructor()-> mPresContext->PresShell()->FrameConstructor()->
ProcessRestyledFrames(changeList, tracker); ProcessRestyledFrames(changeList);
tracker.Flush(); mPresContext->PresShell()->FrameConstructor()->
FlushOverflowChangedTracker();
} }
already_AddRefed<nsIStyleRule> already_AddRefed<nsIStyleRule>