Bug 1351535 - Part 4: Add a TraversalRestyleBehavior argument to traversal functions. r=bholley draft
authorCameron McCormack <cam@mcc.id.au>
Sat, 08 Apr 2017 22:57:08 +0800
changeset 558892 0836d2e91bd0f7bce471154b1c78727e19e4f75f
parent 558862 30d4c9f84cfdd9c3ae0b8c8d5eff90c573d4f27c
child 558893 0d25cca9d788bc246b30f84032ab89e643782949
push id52984
push userbmo:cam@mcc.id.au
push dateSat, 08 Apr 2017 15:03:01 +0000
reviewersbholley
bugs1351535
milestone55.0a1
Bug 1351535 - Part 4: Add a TraversalRestyleBehavior argument to traversal functions. r=bholley This argument will be used to control whether we are restyling in preparation for reframing a subtree, which can avoid generating any change hints, as we aren't preserving the frames that they would otherwise apply to. MozReview-Commit-ID: DkLVCUnNGt
layout/style/ServoBindingList.h
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
layout/style/ServoTypes.h
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -319,17 +319,18 @@ SERVO_BINDING_FUNC(Servo_ResolvePseudoSt
 SERVO_BINDING_FUNC(Servo_ResolveStyleLazily, ServoComputedValuesStrong,
                    RawGeckoElementBorrowed element, nsIAtom* pseudo_tag,
                    RawServoStyleSetBorrowed set)
 
 // Use ServoStyleSet::PrepareAndTraverseSubtree instead of calling this
 // directly
 SERVO_BINDING_FUNC(Servo_TraverseSubtree, bool,
                    RawGeckoElementBorrowed root, RawServoStyleSetBorrowed set,
-                   mozilla::TraversalRootBehavior root_behavior)
+                   mozilla::TraversalRootBehavior root_behavior,
+                   mozilla::TraversalRestyleBehavior restyle_behavior)
 
 // Assert that the tree has no pending or unconsumed restyles.
 SERVO_BINDING_FUNC(Servo_AssertTreeIsClean, void, RawGeckoElementBorrowed root)
 
 // Returns computed values for the given element without any animations rules.
 SERVO_BINDING_FUNC(Servo_StyleSet_GetBaseComputedValuesForElement,
                    ServoComputedValuesStrong,
                    RawServoStyleSetBorrowed set,
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -220,35 +220,38 @@ ServoStyleSet::PreTraverse()
 
   // Process animation stuff that we should avoid doing during the parallel
   // traversal.
   mPresContext->EffectCompositor()->PreTraverse();
 }
 
 bool
 ServoStyleSet::PrepareAndTraverseSubtree(RawGeckoElementBorrowed aRoot,
-                                         mozilla::TraversalRootBehavior aRootBehavior)
+                                         TraversalRootBehavior aRootBehavior,
+                                         TraversalRestyleBehavior
+                                           aRestyleBehavior)
 {
   // Get the Document's root element to ensure that the cache is valid before
   // calling into the (potentially-parallel) Servo traversal, where a cache hit
   // is necessary to avoid a data race when updating the cache.
   mozilla::Unused << aRoot->OwnerDoc()->GetRootElement();
 
   MOZ_ASSERT(!sInServoTraversal);
   sInServoTraversal = true;
 
   bool isInitial = !aRoot->HasServoData();
   bool postTraversalRequired =
-    Servo_TraverseSubtree(aRoot, mRawSet.get(), aRootBehavior);
+    Servo_TraverseSubtree(aRoot, mRawSet.get(), aRootBehavior, aRestyleBehavior);
   MOZ_ASSERT_IF(isInitial, !postTraversalRequired);
 
   // If there are still animation restyles needed, trigger a second traversal to
   // update CSS animations' styles.
   if (mPresContext->EffectCompositor()->PreTraverse()) {
-    if (Servo_TraverseSubtree(aRoot, mRawSet.get(), aRootBehavior)) {
+    if (Servo_TraverseSubtree(aRoot, mRawSet.get(),
+                              aRootBehavior, aRestyleBehavior)) {
       if (isInitial) {
         // We're doing initial styling, and the additional animation
         // traversal changed the styles that were set by the first traversal.
         // This would normally require a post-traversal to update the style
         // contexts, and the DOM now has dirty descendant bits and RestyleData
         // in expectation of that post-traversal. But since this is actually
         // the initial styling, there are no style contexts to update and no
         // frames to apply the change hints to, so we don't need to do that
@@ -703,41 +706,47 @@ ServoStyleSet::StyleDocument()
 {
   PreTraverse();
 
   // Restyle the document from the root element and each of the document level
   // NAC subtree roots.
   bool postTraversalRequired = false;
   DocumentStyleRootIterator iter(mPresContext->Document());
   while (Element* root = iter.GetNextStyleRoot()) {
-    if (PrepareAndTraverseSubtree(root, TraversalRootBehavior::Normal)) {
+    if (PrepareAndTraverseSubtree(root,
+                                  TraversalRootBehavior::Normal,
+                                  TraversalRestyleBehavior::Normal)) {
       postTraversalRequired = true;
     }
   }
   return postTraversalRequired;
 }
 
 void
 ServoStyleSet::StyleNewSubtree(Element* aRoot)
 {
   MOZ_ASSERT(!aRoot->HasServoData());
 
   PreTraverse();
 
   DebugOnly<bool> postTraversalRequired =
-    PrepareAndTraverseSubtree(aRoot, TraversalRootBehavior::Normal);
+    PrepareAndTraverseSubtree(aRoot,
+                              TraversalRootBehavior::Normal,
+                              TraversalRestyleBehavior::Normal);
   MOZ_ASSERT(!postTraversalRequired);
 }
 
 void
 ServoStyleSet::StyleNewChildren(Element* aParent)
 {
   PreTraverse();
 
-  PrepareAndTraverseSubtree(aParent, TraversalRootBehavior::UnstyledChildrenOnly);
+  PrepareAndTraverseSubtree(aParent,
+                            TraversalRootBehavior::UnstyledChildrenOnly,
+                            TraversalRestyleBehavior::Normal);
   // We can't assert that Servo_TraverseSubtree returns false, since aParent
   // or some of its other children might have pending restyles.
 }
 
 void
 ServoStyleSet::NoteStyleSheetsChanged()
 {
   Servo_StyleSet_NoteStyleSheetsChanged(mRawSet.get());
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -297,17 +297,18 @@ private:
    */
   void ResolveMappedAttrDeclarationBlocks();
 
   /**
    * Perform all lazy operations required before traversing
    * a subtree.  Returns whether a post-traversal is required.
    */
   bool PrepareAndTraverseSubtree(RawGeckoElementBorrowed aRoot,
-                                 mozilla::TraversalRootBehavior aRootBehavior);
+                                 TraversalRootBehavior aRootBehavior,
+                                 TraversalRestyleBehavior aRestyleBehavior);
 
   /**
    * Clear our cached mNonInheritingStyleContexts.  We do this when we want to
    * make sure those style contexts won't live too long (e.g. when rebuilding
    * all style data or when shutting down the style set).
    */
   void ClearNonInheritingStyleContexts();
 
--- a/layout/style/ServoTypes.h
+++ b/layout/style/ServoTypes.h
@@ -48,16 +48,26 @@ enum class LazyComputeBehavior {
 // Indicates whether the Servo style system should perform normal processing or
 // whether it should only process unstyled children of the root and their
 // descendants.
 enum class TraversalRootBehavior {
   Normal,
   UnstyledChildrenOnly,
 };
 
+// Indicates whether the Servo style system should perform normal processing or
+// whether it should traverse in a mode that doesn't generate any change hints,
+// which is what's required when handling frame reconstruction.  The change
+// hints in this case are unneeded, since the old frames have already been
+// destroyed.
+enum class TraversalRestyleBehavior {
+  Normal,
+  ForReconstruct,
+};
+
 // Represents which tasks are performed in a SequentialTask of UpdateAnimations.
 enum class UpdateAnimationsTasks : uint8_t {
   CSSAnimations    = 1 << 0,
   CSSTransitions   = 1 << 1,
   EffectProperties = 1 << 2,
   CascadeResults   = 1 << 3,
 };