Bug 1330190 - Part 2: Add a new function named ResolveStyleWithoutAnimation. r=heycam
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Mon, 16 Jan 2017 16:57:13 +0900
changeset 374538 b418519ea4d0693f1a86d869d2be1afa494a00b4
parent 374537 fd18ab48f5c3cbce6b9d6f26f0df4b0d436278a2
child 374539 69a81a6bb0bde892cd1e91dd069e0fdb6ece32f4
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1330190
milestone53.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 1330190 - Part 2: Add a new function named ResolveStyleWithoutAnimation. r=heycam Unlike the other one this function does not need an old nsStyleContext. This function just resolves style without all animation data in the first place. The existing ResolveStyleWithoutAnimation is renamed to ResolveStyleByRemovingAnimation. MozReview-Commit-ID: 1RmCQNw0MmW
dom/animation/EffectCompositor.cpp
layout/style/nsAnimationManager.cpp
layout/style/nsStyleSet.cpp
layout/style/nsStyleSet.h
layout/style/nsTransitionManager.cpp
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -905,18 +905,18 @@ EffectCompositor::GetBaseStyle(nsCSSProp
   // Check whether there is a cached style.
   result = effectSet->GetBaseStyle(aProperty);
   if (!result.IsNull()) {
     return result;
   }
 
   RefPtr<nsStyleContext> styleContextWithoutAnimation =
     aStyleContext->PresContext()->StyleSet()->AsGecko()->
-      ResolveStyleWithoutAnimation(&aElement, aStyleContext,
-                                   eRestyle_AllHintsWithAnimations);
+      ResolveStyleByRemovingAnimation(&aElement, aStyleContext,
+                                      eRestyle_AllHintsWithAnimations);
 
   DebugOnly<bool> success =
     StyleAnimationValue::ExtractComputedValue(aProperty,
                                               styleContextWithoutAnimation,
                                               result);
   MOZ_ASSERT(success, "Should be able to extract computed animation value");
   MOZ_ASSERT(!result.IsNull(), "Should have a valid StyleAnimationValue");
 
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -1036,18 +1036,18 @@ CSSAnimationBuilder::GetComputedValue(ns
   nsCSSValue result;
   StyleAnimationValue computedValue;
 
   if (!mStyleWithoutAnimation) {
     MOZ_ASSERT(aPresContext->StyleSet()->IsGecko(),
                "ServoStyleSet should not use nsAnimationManager for "
                "animations");
     mStyleWithoutAnimation = aPresContext->StyleSet()->AsGecko()->
-      ResolveStyleWithoutAnimation(mTarget, mStyleContext,
-                                   eRestyle_AllHintsWithAnimations);
+      ResolveStyleByRemovingAnimation(mTarget, mStyleContext,
+                                      eRestyle_AllHintsWithAnimations);
   }
 
   if (StyleAnimationValue::ExtractComputedValue(aProperty,
                                                 mStyleWithoutAnimation,
                                                 computedValue)) {
     DebugOnly<bool> uncomputeResult =
       StyleAnimationValue::UncomputeValue(aProperty, Move(computedValue),
                                           result);
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -1346,19 +1346,20 @@ nsStyleSet::ResolveStyleFor(Element* aEl
 {
   TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
                                aElement->OwnerDoc());
   InitStyleScopes(treeContext, aElement);
   return ResolveStyleFor(aElement, aParentContext, treeContext);
 }
 
 already_AddRefed<nsStyleContext>
-nsStyleSet::ResolveStyleFor(Element* aElement,
-                            nsStyleContext* aParentContext,
-                            TreeMatchContext& aTreeMatchContext)
+nsStyleSet::ResolveStyleForInternal(Element* aElement,
+                                    nsStyleContext* aParentContext,
+                                    TreeMatchContext& aTreeMatchContext,
+                                    AnimationFlag aAnimationFlag)
 {
   NS_ENSURE_FALSE(mInShutdown, nullptr);
   NS_ASSERTION(aElement, "aElement must not be null");
 
   nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled);
   aTreeMatchContext.ResetForUnvisitedMatching();
   ElementRuleProcessorData data(PresContext(), aElement, &ruleWalker,
                                 aTreeMatchContext);
@@ -1372,17 +1373,17 @@ nsStyleSet::ResolveStyleFor(Element* aEl
   if (aTreeMatchContext.HaveRelevantLink()) {
     aTreeMatchContext.ResetForVisitedMatching();
     ruleWalker.Reset();
     FileRules(EnumRulesMatching<ElementRuleProcessorData>, &data, aElement,
               &ruleWalker);
     visitedRuleNode = ruleWalker.CurrentNode();
   }
 
-  uint32_t flags = eDoAnimation;
+  uint32_t flags = (aAnimationFlag == eWithAnimation) ? eDoAnimation : eNoFlags;
   if (nsCSSRuleProcessor::IsLink(aElement)) {
     flags |= eIsLink;
   }
   if (nsCSSRuleProcessor::GetContentState(aElement, aTreeMatchContext).
                             HasState(NS_EVENT_STATE_VISITED)) {
     flags |= eIsVisitedLink;
   }
   if (aTreeMatchContext.mSkippingParentDisplayBasedStyleFixup) {
@@ -1390,16 +1391,27 @@ nsStyleSet::ResolveStyleFor(Element* aEl
   }
 
   return GetContext(aParentContext, ruleNode, visitedRuleNode,
                     nullptr, CSSPseudoElementType::NotPseudo,
                     aElement, flags);
 }
 
 already_AddRefed<nsStyleContext>
+nsStyleSet::ResolveStyleFor(Element* aElement,
+                            nsStyleContext* aParentContext,
+                            TreeMatchContext& aTreeMatchContext)
+{
+  return ResolveStyleForInternal(aElement,
+                                 aParentContext,
+                                 aTreeMatchContext,
+                                 eWithAnimation);
+}
+
+already_AddRefed<nsStyleContext>
 nsStyleSet::ResolveStyleForRules(nsStyleContext* aParentContext,
                                  const nsTArray< nsCOMPtr<nsIStyleRule> > &aRules)
 {
   NS_ENSURE_FALSE(mInShutdown, nullptr);
 
   nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled);
   // FIXME: Perhaps this should be passed in, but it probably doesn't
   // matter.
@@ -1743,19 +1755,19 @@ nsStyleSet::ResolveStyleWithReplacement(
   }
 
   return GetContext(aNewParentContext, ruleNode, visitedRuleNode,
                     aOldStyleContext->GetPseudo(), pseudoType,
                     elementForAnimation, flags);
 }
 
 already_AddRefed<nsStyleContext>
-nsStyleSet::ResolveStyleWithoutAnimation(dom::Element* aTarget,
-                                         nsStyleContext* aStyleContext,
-                                         nsRestyleHint aWhichToRemove)
+nsStyleSet::ResolveStyleByRemovingAnimation(dom::Element* aTarget,
+                                            nsStyleContext* aStyleContext,
+                                            nsRestyleHint aWhichToRemove)
 {
 #ifdef DEBUG
   CSSPseudoElementType pseudoType = aStyleContext->GetPseudoType();
 #endif
   MOZ_ASSERT(pseudoType == CSSPseudoElementType::NotPseudo ||
              pseudoType == CSSPseudoElementType::before ||
              pseudoType == CSSPseudoElementType::after,
              "unexpected type for animations");
@@ -1773,16 +1785,44 @@ nsStyleSet::ResolveStyleWithoutAnimation
                                 eSkipStartingAnimations);
 
   restyleManager->SetSkipAnimationRules(oldSkipAnimationRules);
 
   return result.forget();
 }
 
 already_AddRefed<nsStyleContext>
+nsStyleSet::ResolveStyleWithoutAnimation(Element* aTarget,
+                                         nsStyleContext* aParentContext)
+{
+  RestyleManager* restyleManager = PresContext()->RestyleManager()->AsGecko();
+
+  TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
+                               aTarget->OwnerDoc());
+  InitStyleScopes(treeContext, aTarget);
+
+  bool oldSkipAnimationRules = restyleManager->SkipAnimationRules();
+  restyleManager->SetSkipAnimationRules(true);
+
+  // Here we can call ResolveStyleForInternal() instead of
+  // ResolveStyleWithReplacement() since we don't need any animation rules
+  // (CSS Animations, Transitions and script animations). That's because
+  // EffectCompositor::GetAnimationRule() skips all of animations rules if
+  // SkipAnimationRules flag is true.
+  RefPtr<nsStyleContext> result = ResolveStyleForInternal(aTarget,
+                                                          aParentContext,
+                                                          treeContext,
+                                                          eWithoutAnimation);
+
+  restyleManager->SetSkipAnimationRules(oldSkipAnimationRules);
+
+  return result.forget();
+}
+
+already_AddRefed<nsStyleContext>
 nsStyleSet::ResolveStyleForText(nsIContent* aTextNode,
                                 nsStyleContext* aParentContext)
 {
   MOZ_ASSERT(aTextNode && aTextNode->IsNodeOfType(nsINode::eTEXT));
   return GetContext(aParentContext, mRuleTree, nullptr,
                     nsCSSAnonBoxes::mozText,
                     CSSPseudoElementType::AnonBox, nullptr, eNoFlags);
 }
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -176,19 +176,25 @@ class nsStyleSet final
                               nsRestyleHint aReplacements,
                               uint32_t aFlags = 0);
 
   // Resolve style by returning a style context with the specified
   // animation data removed.  It is allowable to remove all animation
   // data with eRestyle_AllHintsWithAnimations, or by using any other
   // hints that are allowed by ResolveStyleWithReplacement.
   already_AddRefed<nsStyleContext>
-    ResolveStyleWithoutAnimation(mozilla::dom::Element* aElement,
-                                 nsStyleContext* aStyleContext,
-                                 nsRestyleHint aWhichToRemove);
+    ResolveStyleByRemovingAnimation(mozilla::dom::Element* aElement,
+                                    nsStyleContext* aStyleContext,
+                                    nsRestyleHint aWhichToRemove);
+
+  // Similar to the above, but resolving style without all animation data in
+  // the first place.
+  already_AddRefed<nsStyleContext>
+    ResolveStyleWithoutAnimation(mozilla::dom::Element* aTarget,
+                                 nsStyleContext* aParentContext);
 
   // Get a style context for a text node (which no rules will match).
   //
   // The returned style context will have nsCSSAnonBoxes::mozText as its pseudo.
   //
   // (Perhaps mozText should go away and we shouldn't even create style
   // contexts for such content nodes, when text-combine-upright is not
   // present.  However, not doing any rule matching for them is a first step.)
@@ -521,16 +527,26 @@ private:
   GetContext(nsStyleContext* aParentContext,
              nsRuleNode* aRuleNode,
              nsRuleNode* aVisitedRuleNode,
              nsIAtom* aPseudoTag,
              mozilla::CSSPseudoElementType aPseudoType,
              mozilla::dom::Element* aElementForAnimation,
              uint32_t aFlags);
 
+  enum AnimationFlag {
+    eWithAnimation,
+    eWithoutAnimation,
+  };
+  already_AddRefed<nsStyleContext>
+  ResolveStyleForInternal(mozilla::dom::Element* aElement,
+                          nsStyleContext* aParentContext,
+                          TreeMatchContext& aTreeMatchContext,
+                          AnimationFlag aAnimationFlag);
+
   nsPresContext* PresContext() { return mRuleTree->PresContext(); }
 
   // The sheets in each array in mSheets are stored with the most significant
   // sheet last.
   // The arrays for ePresHintSheet, eStyleAttrSheet, eTransitionSheet,
   // eAnimationSheet and eSVGAttrAnimationSheet are always empty.
   // (FIXME:  We should reduce the storage needed for them.)
   mozilla::EnumeratedArray<mozilla::SheetType, mozilla::SheetType::Count,
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -553,18 +553,18 @@ nsTransitionManager::StyleContextChanged
   // not stopping or starting right now.
   RefPtr<nsStyleContext> afterChangeStyle;
   if (collection) {
     MOZ_ASSERT(mPresContext->StyleSet()->IsGecko(),
                "ServoStyleSets should not use nsTransitionManager "
                "for transitions");
     nsStyleSet* styleSet = mPresContext->StyleSet()->AsGecko();
     afterChangeStyle =
-      styleSet->ResolveStyleWithoutAnimation(aElement, newStyleContext,
-                                             eRestyle_CSSTransitions);
+      styleSet->ResolveStyleByRemovingAnimation(aElement, newStyleContext,
+                                                eRestyle_CSSTransitions);
   } else {
     afterChangeStyle = newStyleContext;
   }
 
   nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
 
   DebugOnly<bool> startedAny = false;
   // We don't have to update transitions if display:none, although we will