From 439420deeb445a0e0c1853b89951e38f0596af48 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Sat, 15 Jul 2017 13:16:11 +0900 Subject: [PATCH] Bug 1371450 - Recreate style context only if the element was restyled during the traversal. r=emilio MozReview-Commit-ID: CBYTB5FeikP --HG-- extra : rebase_source : e40d357ae70f9852e5b90eb6f3c41565bf1570a6 --- layout/base/ServoRestyleManager.cpp | 41 ++++++++++++----------------- layout/style/ServoBindingList.h | 3 ++- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/layout/base/ServoRestyleManager.cpp b/layout/base/ServoRestyleManager.cpp index dac53dded143..3ea4d584df34 100644 --- a/layout/base/ServoRestyleManager.cpp +++ b/layout/base/ServoRestyleManager.cpp @@ -250,7 +250,10 @@ ServoRestyleManager::ClearRestyleStateFromSubtree(Element* aElement) } } - Unused << Servo_TakeChangeHint(aElement, TraversalRestyleBehavior::Normal); + bool wasRestyled; + Unused << Servo_TakeChangeHint(aElement, + TraversalRestyleBehavior::Normal, + &wasRestyled); aElement->UnsetHasDirtyDescendantsForServo(); aElement->UnsetHasAnimationOnlyDirtyDescendantsForServo(); aElement->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES); @@ -467,7 +470,10 @@ ServoRestyleManager::ProcessPostTraversal( // In case of flushing throttled animations, any restyle hints other than // animations are preserved since they are the hints which will be processed // in normal restyle later. - nsChangeHint changeHint = Servo_TakeChangeHint(aElement, aRestyleBehavior); + bool wasRestyled; + nsChangeHint changeHint = Servo_TakeChangeHint(aElement, + aRestyleBehavior, + &wasRestyled); // We should really fix the weird primary frame mapping for image maps // (bug 135040)... @@ -526,22 +532,6 @@ ServoRestyleManager::ProcessPostTraversal( } } - RefPtr computedValues = - aRestyleState.StyleSet().ResolveServoStyle(aElement); - - // Note that we rely in the fact that we don't cascade pseudo-element styles - // separately right now (that is, if a pseudo style changes, the normal style - // changes too). - // - // Otherwise we should probably encode that information somehow to avoid - // expensive checks in the common case. - // - // Also, we're going to need to check for pseudos of display: contents - // elements, though that is buggy right now even in non-stylo mode, see - // bug 1251799. - const bool recreateContext = oldStyleContext && - oldStyleContext->ComputedValues() != computedValues; - Maybe thisFrameRestyleState; if (styleFrame) { auto type = isOutOfFlow @@ -557,8 +547,11 @@ ServoRestyleManager::ProcessPostTraversal( thisFrameRestyleState ? *thisFrameRestyleState : aRestyleState; RefPtr newContext = nullptr; - if (recreateContext) { + if (wasRestyled && oldStyleContext) { MOZ_ASSERT(styleFrame || displayContentsNode); + RefPtr computedValues = + aRestyleState.StyleSet().ResolveServoStyle(aElement); + MOZ_ASSERT(oldStyleContext->ComputedValues() != computedValues); auto pseudo = aElement->GetPseudoElementType(); nsIAtom* pseudoTag = pseudo == CSSPseudoElementType::NotPseudo @@ -622,15 +615,15 @@ ServoRestyleManager::ProcessPostTraversal( const bool forThrottledAnimationFlush = aRestyleBehavior == TraversalRestyleBehavior::ForThrottledAnimationFlush; const bool traverseTextChildren = - recreateContext || (!forThrottledAnimationFlush && descendantsNeedFrames); - bool recreatedAnyContext = recreateContext; + wasRestyled || (!forThrottledAnimationFlush && descendantsNeedFrames); + bool recreatedAnyContext = wasRestyled; if (traverseElementChildren || traverseTextChildren) { nsStyleContext* upToDateContext = - recreateContext ? newContext : oldStyleContext; + wasRestyled ? newContext : oldStyleContext; StyleChildrenIterator it(aElement); TextPostTraversalState textState(*upToDateContext, - displayContentsNode && recreateContext, + displayContentsNode && wasRestyled, childrenRestyleState); for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) { if (traverseElementChildren && n->IsElement()) { @@ -648,7 +641,7 @@ ServoRestyleManager::ProcessPostTraversal( // kids, because some of those updates (::first-line/::first-letter) need to // modify the styles of the kids, and the child traversal above would just // clobber those modifications. - if (recreateContext && styleFrame) { + if (wasRestyled && styleFrame) { UpdateFramePseudoElementStyles(styleFrame, childrenRestyleState); } diff --git a/layout/style/ServoBindingList.h b/layout/style/ServoBindingList.h index 711b9938730c..8e9ab92fe01d 100644 --- a/layout/style/ServoBindingList.h +++ b/layout/style/ServoBindingList.h @@ -494,7 +494,8 @@ SERVO_BINDING_FUNC(Servo_NoteExplicitHints, void, RawGeckoElementBorrowed elemen SERVO_BINDING_FUNC(Servo_TakeChangeHint, nsChangeHint, RawGeckoElementBorrowed element, - mozilla::TraversalRestyleBehavior restyle_behavior) + mozilla::TraversalRestyleBehavior restyle_behavior, + bool* was_restyled) SERVO_BINDING_FUNC(Servo_ResolveStyle, ServoComputedValuesStrong, RawGeckoElementBorrowed element, RawServoStyleSetBorrowed set)