Bug 1341985 - Trigger the second traversal for updating CSS animations in the case of Servo_ResolveStyleLazily. r?heycam draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Fri, 10 Mar 2017 11:53:19 +0900
changeset 496379 a3188d2a79ed5027e38f061042e2280aa1482a1b
parent 496378 84dbb70cdc0c0b794d33281c1cd98d95c1675db6
child 496380 7a1204c2e3dc16d8c6b9f90ef84446b70766c951
push id48582
push userhikezoe@mozilla.com
push dateFri, 10 Mar 2017 03:13:33 +0000
reviewersheycam
bugs1341985
milestone55.0a1
Bug 1341985 - Trigger the second traversal for updating CSS animations in the case of Servo_ResolveStyleLazily. r?heycam MozReview-Commit-ID: 7E4unP9M7FQ
dom/animation/EffectCompositor.cpp
dom/animation/EffectCompositor.h
layout/style/ServoStyleSet.cpp
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -330,16 +330,18 @@ EffectCompositor::PostRestyleForAnimatio
       // In that case PreTraverse() will return true so that we know to do the
       // second traversal so we don't need to post any restyle requests to the
       // PresShell.
       return;
     } else if (!mPresContext->RestyleManager()->IsInStyleRefresh()) {
       // FIXME: stylo only supports Self and Subtree hints now, so we override
       // it for stylo if we are not in process of restyling.
       hint = eRestyle_Self | eRestyle_Subtree;
+    } else {
+      MOZ_ASSERT_UNREACHABLE("Should not request restyle");
     }
   }
   mPresContext->PresShell()->RestyleForAnimation(element, hint);
 }
 
 void
 EffectCompositor::PostRestyleForThrottledAnimations()
 {
@@ -991,49 +993,55 @@ EffectCompositor::PreTraverse()
       // Remove the element from the list of elements to restyle since we are
       // about to restyle it.
       iter.Remove();
     }
   }
   return foundElementsNeedingRestyle;
 }
 
-void
+bool
 EffectCompositor::PreTraverse(dom::Element* aElement, nsIAtom* aPseudoTagOrNull)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mPresContext->RestyleManager()->IsServo());
 
+  bool found = false;
   if (aPseudoTagOrNull &&
       aPseudoTagOrNull != nsGkAtoms::cssPseudoElementBeforeProperty &&
       aPseudoTagOrNull != nsGkAtoms::cssPseudoElementAfterProperty) {
-    return;
+    return found;
   }
 
   CSSPseudoElementType pseudoType =
     nsCSSPseudoElements::GetPseudoType(aPseudoTagOrNull,
                                        CSSEnabledState::eForAllContent);
 
   PseudoElementHashEntry::KeyType key = { aElement, pseudoType };
 
   for (auto& elementsToRestyle : mElementsToRestyle) {
     if (!elementsToRestyle.Get(key)) {
       // Ignore throttled restyle and no restyle request.
       continue;
     }
 
+    mPresContext->RestyleManager()->AsServo()->
+      PostRestyleEventForAnimations(aElement, eRestyle_Self);
+
     EffectSet* effects = EffectSet::GetEffectSet(aElement, pseudoType);
     if (effects) {
       for (KeyframeEffectReadOnly* effect : *effects) {
         effect->GetAnimation()->WillComposeStyle();
       }
     }
 
     elementsToRestyle.Remove(key);
+    found = true;
   }
+  return found;
 }
 
 // ---------------------------------------------------------
 //
 // Nested class: AnimationStyleRuleProcessor
 //
 // ---------------------------------------------------------
 
--- a/dom/animation/EffectCompositor.h
+++ b/dom/animation/EffectCompositor.h
@@ -228,17 +228,17 @@ public:
 
   // Do a bunch of stuff that we should avoid doing during the parallel
   // traversal (e.g. changing member variables) for all elements that we expect
   // to restyle on the next traversal.
   // Returns true if there are elements needing a restyle for animation.
   bool PreTraverse();
 
   // Similar to the above but only for the (pseudo-)element.
-  void PreTraverse(dom::Element* aElement, nsIAtom* aPseudoTagOrNull);
+  bool PreTraverse(dom::Element* aElement, nsIAtom* aPseudoTagOrNull);
 
 private:
   ~EffectCompositor() = default;
 
   // Rebuilds the animation rule corresponding to |aCascadeLevel| on the
   // EffectSet associated with the specified (pseudo-)element.
   static void ComposeAnimationRule(dom::Element* aElement,
                                    CSSPseudoElementType aPseudoType,
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -755,12 +755,23 @@ ServoStyleSet::ClearNonInheritingStyleCo
   }  
 }
 
 already_AddRefed<ServoComputedValues>
 ServoStyleSet::ResolveStyleLazily(Element* aElement, nsIAtom* aPseudoTag)
 {
   mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoTag);
 
-  return Servo_ResolveStyleLazily(aElement, aPseudoTag, mRawSet.get()).Consume();
+  MOZ_ASSERT(!sInServoTraversal);
+  sInServoTraversal = true;
+  RefPtr<ServoComputedValues> computedValues =
+    Servo_ResolveStyleLazily(aElement, aPseudoTag, mRawSet.get()).Consume();
+
+  if (mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoTag)) {
+    computedValues =
+      Servo_ResolveStyleLazily(aElement, aPseudoTag, mRawSet.get()).Consume();
+  }
+  sInServoTraversal = false;
+
+  return computedValues.forget();
 }
 
 bool ServoStyleSet::sInServoTraversal = false;