Bug 996796 patch 23 - Make transition manager ignore StyleContextChanged notifications during an animation-only style update. r=heycam
authorL. David Baron <dbaron@dbaron.org>
Sat, 02 Aug 2014 19:37:48 -0700
changeset 197495 bc7a3787b5840de84f226eca8b32020e39e651ce
parent 197494 0c1136091a68100400db5bb09b99f355e89841e7
child 197496 ebf41f7c81b233b13b03a6caf7f254a41131e4d2
push id47142
push userdbaron@mozilla.com
push dateSun, 03 Aug 2014 02:38:23 +0000
treeherdermozilla-inbound@1636ae2d7b53 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs996796
milestone34.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 996796 patch 23 - Make transition manager ignore StyleContextChanged notifications during an animation-only style update. r=heycam This will be necessary when we use the restyle tracker for the animation-only style flush.
layout/base/RestyleManager.cpp
layout/style/nsTransitionManager.cpp
layout/style/nsTransitionManager.h
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -1569,18 +1569,25 @@ void
 RestyleManager::UpdateOnlyAnimationStyles()
 {
   TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh();
   if (mLastUpdateForThrottledAnimations == now) {
     return;
   }
   mLastUpdateForThrottledAnimations = now;
 
-  mPresContext->TransitionManager()->UpdateAllThrottledStyles();
-  mPresContext->AnimationManager()->UpdateAllThrottledStyles();
+  nsTransitionManager* transitionManager = mPresContext->TransitionManager();
+  nsAnimationManager* animationManager = mPresContext->AnimationManager();
+
+  transitionManager->SetInAnimationOnlyStyleUpdate(true);
+
+  transitionManager->UpdateAllThrottledStyles();
+  animationManager->UpdateAllThrottledStyles();
+
+  transitionManager->SetInAnimationOnlyStyleUpdate(false);
 }
 
 void
 RestyleManager::PostRestyleEventCommon(Element* aElement,
                                        nsRestyleHint aRestyleHint,
                                        nsChangeHint aMinChangeHint,
                                        bool aForAnimation)
 {
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -158,16 +158,25 @@ nsTransitionManager::StyleContextChanged
   // If we were called from ReparentStyleContext, this assertion would
   // actually fire.  If we need to be called from there, we can probably
   // just remove it; the condition probably isn't critical, although
   // it's worth thinking about some more.
   NS_PRECONDITION(aOldStyleContext->HasPseudoElementData() ==
                       aNewStyleContext->HasPseudoElementData(),
                   "pseudo type mismatch");
 
+  if (mInAnimationOnlyStyleUpdate) {
+    // If we're doing an animation-only style update, return, since the
+    // purpose of an animation-only style update is to update only the
+    // animation styles so that we don't consider style changes
+    // resulting from changes in the animation time for starting a
+    // transition.
+    return nullptr;
+  }
+
   if (!mPresContext->IsDynamic()) {
     // For print or print preview, ignore transitions.
     return nullptr;
   }
 
   // NOTE: Things in this function (and ConsiderStartingTransition)
   // should never call PeekStyleData because we don't preserve gotten
   // structs across reframes.
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -62,16 +62,17 @@ struct ElementPropertyTransition : publi
 } // namespace mozilla
 
 class nsTransitionManager MOZ_FINAL
   : public mozilla::css::CommonAnimationManager
 {
 public:
   nsTransitionManager(nsPresContext *aPresContext)
     : mozilla::css::CommonAnimationManager(aPresContext)
+    , mInAnimationOnlyStyleUpdate(false)
   {
   }
 
   typedef mozilla::ElementAnimationCollection ElementAnimationCollection;
 
   static ElementAnimationCollection*
   GetTransitions(nsIContent* aContent) {
     return static_cast<ElementAnimationCollection*>
@@ -112,16 +113,20 @@ public:
    * element *again* with the original sequence of rules plus the
    * returned cover rule as the most specific rule.
    */
   already_AddRefed<nsIStyleRule>
     StyleContextChanged(mozilla::dom::Element *aElement,
                         nsStyleContext *aOldStyleContext,
                         nsStyleContext *aNewStyleContext);
 
+  void SetInAnimationOnlyStyleUpdate(bool aInAnimationOnlyUpdate) {
+    mInAnimationOnlyStyleUpdate = aInAnimationOnlyUpdate;
+  }
+
   // nsIStyleRuleProcessor (parts)
   virtual void RulesMatching(ElementRuleProcessorData* aData) MOZ_OVERRIDE;
   virtual void RulesMatching(PseudoElementRuleProcessorData* aData) MOZ_OVERRIDE;
   virtual void RulesMatching(AnonBoxRuleProcessorData* aData) MOZ_OVERRIDE;
 #ifdef MOZ_XUL
   virtual void RulesMatching(XULTreeRuleProcessorData* aData) MOZ_OVERRIDE;
 #endif
   virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
@@ -179,11 +184,13 @@ private:
                           nsCSSPseudoElements::Type aPseudoType);
   // Update the animated styles of an element and its descendants.
   // If the element has a transition, it is flushed back to its primary frame.
   // If the element does not have a transition, then its style is reparented.
   void UpdateThrottledStylesForSubtree(nsIContent* aContent,
                                        nsStyleContext* aParentStyle,
                                        nsStyleChangeList &aChangeList);
   void UpdateAllThrottledStylesInternal();
+
+  bool mInAnimationOnlyStyleUpdate;
 };
 
 #endif /* !defined(nsTransitionManager_h_) */