Bug 1339704 - Part 2 - Filter out unwanted CascadeLevel::Transitions. r=birtles,hiro
authorBoris Chiou <boris.chiou@gmail.com>
Mon, 13 Mar 2017 21:09:50 +0800
changeset 395953 bd0d3ac13d7aab6c84e65195f3c59cd8e8e7c438
parent 395952 a0c113ba3978af7438a8fd34dd559eb816499eb0
child 395954 adcc2ad6c0a1a75ae55e411426f1afb1a9d0f5ca
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbirtles, hiro
bugs1339704
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1339704 - Part 2 - Filter out unwanted CascadeLevel::Transitions. r=birtles,hiro We always call TElement::get_animation_rules() for both cascade levels while there are animations or transitions, so we want to handle the following cases: 1. Have both CascadeLevel::Animations and CascadeLevel::Transitions: * We use EffectSet::mPropertiesForAnimationsLevel to filter out CascadeLevel::Transitions because transitions are suppressed when both are presented. 2. Have CascadeLevel::Animations, but don't have CascadeLevel::Transitions: * We also use EffectSet::mPropertiesForAnimationsLevel to filter out the unwanted CascadeLevel::Transitions. 3. Don't Have CascadeLevel::Animations, but have CascadeLevel::Transitions: * EffectSet::mPropertiesForAnimationsLevel doesn't work for this case. In Gecko, mElementsToRestyle can help us to filter out the unwanted CascadeLevel::Animations, However, mElementsToRestyle is cleared in Pre-Traversal, so now we rely on the cascade ordering of transitions to override animations. I think we still need to optimize this eventually. 4. No animations: * EffectSet helps us to check if there is any animations/transitions. Therefore, we need to call MaybeUpdateCascadeResults(), which updates mPropertiesForAnimationsLevel, in Pre-Traversal. MozReview-Commit-ID: IHYw56EX7Ta
dom/animation/EffectCompositor.cpp
dom/animation/EffectCompositor.h
dom/animation/EffectSet.h
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -500,19 +500,20 @@ EffectCompositor::GetServoAnimationRule(
   sortedEffectList.Sort(EffectCompositeOrderComparator());
 
   AnimationRule& animRule = effectSet->AnimationRule(aCascadeLevel);
   animRule.mServo = nullptr;
 
   // If multiple animations affect the same property, animations with higher
   // composite order (priority) override or add or animations with lower
   // priority.
-  // stylo: we don't support animations on compositor now, so propertiesToSkip
-  // is an empty set.
-  const nsCSSPropertyIDSet propertiesToSkip;
+  const nsCSSPropertyIDSet propertiesToSkip =
+    aCascadeLevel == CascadeLevel::Animations
+      ? effectSet->PropertiesForAnimationsLevel().Inverse()
+      : effectSet->PropertiesForAnimationsLevel();
   for (KeyframeEffectReadOnly* effect : sortedEffectList) {
     effect->GetAnimation()->ComposeStyle(animRule, propertiesToSkip);
   }
 
   MOZ_ASSERT(effectSet == EffectSet::GetEffectSet(aElement, aPseudoType),
              "EffectSet should not change while composing style");
 
   return animRule.mServo;
@@ -681,16 +682,32 @@ EffectCompositor::MaybeUpdateCascadeResu
     }
   }
   UpdateCascadeResults(*effects, aElement, aPseudoType, styleContext);
 
   MOZ_ASSERT(!effects->CascadeNeedsUpdate(), "Failed to update cascade state");
 }
 
 /* static */ void
+EffectCompositor::MaybeUpdateCascadeResults(dom::Element* aElement,
+                                            CSSPseudoElementType aPseudoType)
+{
+  EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType);
+  MOZ_ASSERT(effects);
+  if (!effects->CascadeNeedsUpdate()) {
+    return;
+  }
+
+  // FIXME: Implement the rule node traversal for stylo in Bug 1334036.
+  UpdateCascadeResults(*effects, aElement, aPseudoType, nullptr);
+
+  MOZ_ASSERT(!effects->CascadeNeedsUpdate(), "Failed to update cascade state");
+}
+
+/* static */ void
 EffectCompositor::UpdateCascadeResults(Element* aElement,
                                        CSSPseudoElementType aPseudoType,
                                        nsStyleContext* aStyleContext)
 {
   EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType);
   if (!effects) {
     return;
   }
@@ -832,16 +849,20 @@ EffectCompositor::UpdateCascadeResults(E
 
   // Get properties that override the *animations* level of the cascade.
   //
   // We only do this for properties that we can animate on the compositor
   // since we will apply other properties on the main thread where the usual
   // cascade applies.
   nsCSSPropertyIDSet overriddenProperties;
   if (aStyleContext) {
+    // FIXME: Bug 1334036 (OMTA) will implement a FFI to get the properties
+    // overriding animation.
+    MOZ_ASSERT(!aStyleContext->StyleSource().IsServoComputedValues(),
+               "stylo: Not support get properties overriding animation yet.");
     GetOverriddenProperties(aStyleContext, aEffectSet, overriddenProperties);
   }
 
   // Returns a bitset the represents which properties from
   // LayerAnimationInfo::sRecords are present in |aPropertySet|.
   auto compositorPropertiesInSet =
     [](nsCSSPropertyIDSet& aPropertySet) ->
       std::bitset<LayerAnimationInfo::kRecords> {
@@ -971,16 +992,18 @@ EffectCompositor::PreTraverse()
       EffectSet* effects =
         EffectSet::GetEffectSet(target.mElement, target.mPseudoType);
       if (!effects) {
         // Drop EffectSets that have been destroyed.
         iter.Remove();
         continue;
       }
 
+      MaybeUpdateCascadeResults(target.mElement, target.mPseudoType);
+
       for (KeyframeEffectReadOnly* effect : *effects) {
         effect->GetAnimation()->WillComposeStyle();
       }
 
       // Remove the element from the list of elements to restyle since we are
       // about to restyle it.
       iter.Remove();
     }
@@ -1013,16 +1036,18 @@ EffectCompositor::PreTraverse(dom::Eleme
       continue;
     }
 
     mPresContext->RestyleManager()->AsServo()->
       PostRestyleEventForAnimations(aElement, eRestyle_Self);
 
     EffectSet* effects = EffectSet::GetEffectSet(aElement, pseudoType);
     if (effects) {
+      MaybeUpdateCascadeResults(aElement, pseudoType);
+
       for (KeyframeEffectReadOnly* effect : *effects) {
         effect->GetAnimation()->WillComposeStyle();
       }
     }
 
     elementsToRestyle.Remove(key);
     found = true;
   }
--- a/dom/animation/EffectCompositor.h
+++ b/dom/animation/EffectCompositor.h
@@ -191,16 +191,24 @@ public:
   //
   // This method does NOT detect if other styles that apply above the
   // animation level of the cascade have changed.
   static void
   MaybeUpdateCascadeResults(dom::Element* aElement,
                             CSSPseudoElementType aPseudoType,
                             nsStyleContext* aStyleContext);
 
+  // Variant of MaybeUpdateCascadeResults for the Servo backend.
+  // The Servo backend doesn't use an nsStyleContext to get the rule node
+  // to traverse the style tree to find !important rules and instead
+  // gets the rule node from |aElement|.
+  static void
+  MaybeUpdateCascadeResults(dom::Element* aElement,
+                            CSSPseudoElementType aPseudoType);
+
   // Update the mPropertiesWithImportantRules and
   // mPropertiesForAnimationsLevel members of the corresponding EffectSet.
   //
   // This can be expensive so we should only call it if styles that apply
   // above the animation level of the cascade might have changed. For all
   // other cases we should call MaybeUpdateCascadeResults.
   static void
   UpdateCascadeResults(dom::Element* aElement,
--- a/dom/animation/EffectSet.h
+++ b/dom/animation/EffectSet.h
@@ -190,16 +190,20 @@ public:
   nsCSSPropertyIDSet& PropertiesWithImportantRules()
   {
     return mPropertiesWithImportantRules;
   }
   nsCSSPropertyIDSet& PropertiesForAnimationsLevel()
   {
     return mPropertiesForAnimationsLevel;
   }
+  nsCSSPropertyIDSet PropertiesForAnimationsLevel() const
+  {
+    return mPropertiesForAnimationsLevel;
+  }
 
 private:
   static nsIAtom* GetEffectSetPropertyAtom(CSSPseudoElementType aPseudoType);
 
   OwningEffectSet mEffects;
 
   // These style rules contain the style data for currently animating
   // values.  They only match when styling with animation.  When we