Bug 1341372 - Part 1: Let animation-only restyle include css-transition. draft
authorBoris Chiou <boris.chiou@gmail.com>
Mon, 17 Apr 2017 14:22:28 +0800
changeset 563572 a1448beee892e749d5d6b9f01ac3afcfb6b1171e
parent 563571 fbd277ddf47f9e882486513b79fea7c8fa350842
child 563573 5ed611a3ef6e898c046bb52a6bf4f17fb5d7420e
push id54353
push userbmo:boris.chiou@gmail.com
push dateMon, 17 Apr 2017 09:07:14 +0000
bugs1341372
milestone55.0a1
Bug 1341372 - Part 1: Let animation-only restyle include css-transition. Animation-only restyle should include both Animation and Transition cascade levels. MozReview-Commit-ID: Jo1sb5fGUC0
dom/animation/EffectCompositor.cpp
layout/style/ServoStyleSet.cpp
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -311,22 +311,22 @@ EffectCompositor::PostRestyleForAnimatio
                                         eRestyle_CSSTransitions :
                                         eRestyle_CSSAnimations;
 
   if (mPresContext->StyleSet()->IsServo()) {
     MOZ_ASSERT(NS_IsMainThread(),
                "Restyle request during restyling should be requested only on "
                "the main-thread. e.g. after the parallel traversal");
     if (ServoStyleSet::IsInServoTraversal()) {
-      // FIXME: Bug 1302946: We will handle eRestyle_CSSTransitions.
-      MOZ_ASSERT(hint == eRestyle_CSSAnimations);
+      MOZ_ASSERT(hint == eRestyle_CSSAnimations ||
+                 hint == eRestyle_CSSTransitions);
 
       // We can't call Servo_NoteExplicitHints here since AtomicRefCell does not
       // allow us mutate ElementData of the |aElement| in SequentialTask.
-      // Instead we call Servo_NoteExplicitHints for the element in PreTraverse() right
+      // Instead we call Servo_NoteExplicitHints for the element in PreTraverse()
       // which will be called right before the second traversal that we do for
       // updating CSS animations.
       // 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 {
       MOZ_ASSERT(!mPresContext->RestyleManager()->IsInStyleRefresh());
@@ -977,18 +977,20 @@ IsFlattenedTreeDescendantOf(nsINode* aPo
 
 bool
 EffectCompositor::PreTraverseInSubtree(Element* aRoot)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mPresContext->RestyleManager()->IsServo());
 
   bool foundElementsNeedingRestyle = false;
-  for (auto& elementsToRestyle : mElementsToRestyle) {
-    for (auto iter = elementsToRestyle.Iter(); !iter.Done(); iter.Next()) {
+  for (size_t i = 0; i < kCascadeLevelCount; ++i) {
+    CascadeLevel cascadeLevel = CascadeLevel(i);
+    for (auto iter = mElementsToRestyle[cascadeLevel].Iter();
+         !iter.Done(); iter.Next()) {
       bool postedRestyle = iter.Data();
       // Ignore throttled restyle.
       if (!postedRestyle) {
         continue;
       }
 
       NonOwningAnimationTarget target = iter.Key();
 
@@ -998,17 +1000,20 @@ EffectCompositor::PreTraverseInSubtree(E
         continue;
       }
 
       // We need to post restyle hints even if the target is not in EffectSet to
       // ensure the final restyling for removed animations.
       // We can't call PostRestyleEvent directly here since we are still in the
       // middle of the servo traversal.
       mPresContext->RestyleManager()->AsServo()->
-        PostRestyleEventForAnimations(target.mElement, eRestyle_CSSAnimations);
+        PostRestyleEventForAnimations(target.mElement,
+                                      cascadeLevel == CascadeLevel::Transitions
+                                        ? eRestyle_CSSTransitions
+                                        : eRestyle_CSSAnimations);
 
       foundElementsNeedingRestyle = true;
 
       EffectSet* effects =
         EffectSet::GetEffectSet(target.mElement, target.mPseudoType);
       if (!effects) {
         // Drop EffectSets that have been destroyed.
         iter.Remove();
@@ -1043,35 +1048,42 @@ EffectCompositor::PreTraverse(dom::Eleme
   }
 
   CSSPseudoElementType pseudoType =
     nsCSSPseudoElements::GetPseudoType(aPseudoTagOrNull,
                                        CSSEnabledState::eForAllContent);
 
   PseudoElementHashEntry::KeyType key = { aElement, pseudoType };
 
-  for (auto& elementsToRestyle : mElementsToRestyle) {
-    if (!elementsToRestyle.Get(key)) {
+
+  for (size_t i = 0; i < kCascadeLevelCount; ++i) {
+    CascadeLevel cascadeLevel = CascadeLevel(i);
+    auto& elementSet = mElementsToRestyle[cascadeLevel];
+
+    if (!elementSet.Get(key)) {
       // Ignore throttled restyle and no restyle request.
       continue;
     }
 
     mPresContext->RestyleManager()->AsServo()->
-      PostRestyleEventForAnimations(aElement, eRestyle_CSSAnimations);
+      PostRestyleEventForAnimations(aElement,
+                                    cascadeLevel == CascadeLevel::Transitions
+                                      ? eRestyle_CSSTransitions
+                                      : eRestyle_CSSAnimations);
 
     EffectSet* effects = EffectSet::GetEffectSet(aElement, pseudoType);
     if (effects) {
       MaybeUpdateCascadeResults(aElement, pseudoType);
 
       for (KeyframeEffectReadOnly* effect : *effects) {
         effect->GetAnimation()->WillComposeStyle();
       }
     }
 
-    elementsToRestyle.Remove(key);
+    elementSet.Remove(key);
     found = true;
   }
   return found;
 }
 
 // ---------------------------------------------------------
 //
 // Nested class: AnimationStyleRuleProcessor
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -286,17 +286,17 @@ ServoStyleSet::PrepareAndTraverseSubtree
     aRestyleBehavior == TraversalRestyleBehavior::ForReconstruct;
   bool postTraversalRequired =
     Servo_TraverseSubtree(aRoot, mRawSet.get(), aRootBehavior, aRestyleBehavior);
   MOZ_ASSERT_IF(isInitial || forReconstruct, !postTraversalRequired);
 
   auto root = const_cast<Element*>(aRoot);
 
   // If there are still animation restyles needed, trigger a second traversal to
-  // update CSS animations' styles.
+  // update CSS animations or transitions' styles.
   EffectCompositor* compositor = mPresContext->EffectCompositor();
   if (forReconstruct ? compositor->PreTraverseInSubtree(root)
                      : compositor->PreTraverse()) {
     if (Servo_TraverseSubtree(aRoot, mRawSet.get(),
                               aRootBehavior, aRestyleBehavior)) {
       MOZ_ASSERT(!forReconstruct);
       if (isInitial) {
         // We're doing initial styling, and the additional animation