Bug 1340958 - Templatize ComposeStyle. r=birtles
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Fri, 17 Mar 2017 13:22:13 +0900
changeset 396257 e9870de9fa97c34349160198f3a1ded5aa3657a7
parent 396256 f2fdcee9cb8fce2728e7f7e1c057caaf00fcb40c
child 396258 205110b44b6972fe9bbb48fb9c0717489d3e8e3a
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
bugs1340958
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 1340958 - Templatize ComposeStyle. r=birtles Later in this patch series we will replace ServoAnimationRule with a hashmap. At that point, we would like to pass the hashmap to ComposeStyle. In order to achieve that, this patch templatizes the 'animation rule' parameter of ComposeStyle in both Animation and KeyframeEffectReadOnly so that it can represent a hashmap instead. MozReview-Commit-ID: H5bMxjN3W8n
dom/animation/Animation.cpp
dom/animation/Animation.h
dom/animation/EffectCompositor.cpp
dom/animation/KeyframeEffectReadOnly.cpp
dom/animation/KeyframeEffectReadOnly.h
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/dom/AnimationBinding.h"
 #include "mozilla/dom/AnimationPlaybackEvent.h"
 #include "mozilla/dom/DocumentTimeline.h"
 #include "mozilla/AnimationTarget.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/AsyncEventDispatcher.h" // For AsyncEventDispatcher
 #include "mozilla/Maybe.h" // For Maybe
 #include "mozilla/AnimationRule.h" // For AnimationRule
+#include "mozilla/TypeTraits.h" // For Forward<>
 #include "nsAnimationManager.h" // For CSSAnimation
 #include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
 #include "nsIDocument.h" // For nsIDocument
 #include "nsIPresShell.h" // For nsIPresShell
 #include "nsThreadUtils.h" // For nsRunnableMethod and nsRevocableEventPtr
 #include "nsTransitionManager.h" // For CSSTransition
 #include "PendingAnimationTracker.h" // For PendingAnimationTracker
 
@@ -937,18 +938,19 @@ Animation::WillComposeStyle()
   MOZ_ASSERT(mEffect);
 
   KeyframeEffectReadOnly* keyframeEffect = mEffect->AsKeyframeEffect();
   if (keyframeEffect) {
     keyframeEffect->WillComposeStyle();
   }
 }
 
+template<typename ComposeAnimationResult>
 void
-Animation::ComposeStyle(AnimationRule& aStyleRule,
+Animation::ComposeStyle(ComposeAnimationResult&& aComposeResult,
                         const nsCSSPropertyIDSet& aPropertiesToSkip)
 {
   if (!mEffect) {
     return;
   }
 
   // In order to prevent flicker, there are a few cases where we want to use
   // a different time for rendering that would otherwise be returned by
@@ -1000,17 +1002,18 @@ Animation::ComposeStyle(AnimationRule& a
       if (!timeToUse.IsNull()) {
         mHoldTime.SetValue((timeToUse.Value() - mStartTime.Value())
                             .MultDouble(mPlaybackRate));
       }
     }
 
     KeyframeEffectReadOnly* keyframeEffect = mEffect->AsKeyframeEffect();
     if (keyframeEffect) {
-      keyframeEffect->ComposeStyle(aStyleRule, aPropertiesToSkip);
+      keyframeEffect->ComposeStyle(Forward<ComposeAnimationResult>(aComposeResult),
+                                   aPropertiesToSkip);
     }
   }
 
   MOZ_ASSERT(playState == PlayState(),
              "Play state should not change during the course of compositing");
 }
 
 void
@@ -1501,10 +1504,22 @@ Animation::DispatchPlaybackEvent(const n
 bool
 Animation::IsRunningOnCompositor() const
 {
   return mEffect &&
          mEffect->AsKeyframeEffect() &&
          mEffect->AsKeyframeEffect()->IsRunningOnCompositor();
 }
 
+template
+void
+Animation::ComposeStyle<RefPtr<AnimValuesStyleRule>&>(
+  RefPtr<AnimValuesStyleRule>& aAnimationRule,
+  const nsCSSPropertyIDSet& aPropertiesToSkip);
+
+template
+void
+Animation::ComposeStyle<RefPtr<ServoAnimationRule>&>(
+  RefPtr<ServoAnimationRule>& aAnimationRule,
+  const nsCSSPropertyIDSet& aPropertiesToSkip);
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/animation/Animation.h
+++ b/dom/animation/Animation.h
@@ -316,22 +316,23 @@ public:
   /**
    * Updates various bits of state that we need to update as the result of
    * running ComposeStyle().
    * See the comment of KeyframeEffectReadOnly::WillComposeStyle for more detail.
    */
   void WillComposeStyle();
 
   /**
-   * Updates |aStyleRule| with the animation values of this animation's effect,
-   * if any.
+   * Updates |aComposeResult| with the animation values of this animation's
+   * effect, if any.
    * Any properties contained in |aPropertiesToSkip| will not be added or
-   * updated in |aStyleRule|.
+   * updated in |aComposeResult|.
    */
-  void ComposeStyle(AnimationRule& aStyleRule,
+  template<typename ComposeAnimationResult>
+  void ComposeStyle(ComposeAnimationResult&& aComposeResult,
                     const nsCSSPropertyIDSet& aPropertiesToSkip);
 
   void NotifyEffectTimingUpdated();
   void NotifyGeometricAnimationsStartingThisFrame();
 
   /**
    * Used by subclasses to synchronously queue a cancel event in situations
    * where the Animation may have been cancelled.
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -503,17 +503,17 @@ EffectCompositor::GetServoAnimationRule(
   // If multiple animations affect the same property, animations with higher
   // composite order (priority) override or add or animations with lower
   // priority.
   const nsCSSPropertyIDSet propertiesToSkip =
     aCascadeLevel == CascadeLevel::Animations
       ? effectSet->PropertiesForAnimationsLevel().Inverse()
       : effectSet->PropertiesForAnimationsLevel();
   for (KeyframeEffectReadOnly* effect : sortedEffectList) {
-    effect->GetAnimation()->ComposeStyle(animRule, propertiesToSkip);
+    effect->GetAnimation()->ComposeStyle(animRule.mServo, propertiesToSkip);
   }
 
   MOZ_ASSERT(effectSet == EffectSet::GetEffectSet(aElement, aPseudoType),
              "EffectSet should not change while composing style");
 
   return animRule.mServo;
 }
 
@@ -778,17 +778,17 @@ EffectCompositor::ComposeAnimationRule(d
   // composite order (priority) override or add or animations with lower
   // priority except properties in propertiesToSkip.
   const nsCSSPropertyIDSet& propertiesToSkip =
     aCascadeLevel == CascadeLevel::Animations
     ? effects->PropertiesForAnimationsLevel().Inverse()
     : effects->PropertiesForAnimationsLevel();
   for (KeyframeEffectReadOnly* effect : sortedEffectList) {
     effect->GetAnimation()->WillComposeStyle();
-    effect->GetAnimation()->ComposeStyle(animRule, propertiesToSkip);
+    effect->GetAnimation()->ComposeStyle(animRule.mGecko, propertiesToSkip);
   }
 
   MOZ_ASSERT(effects == EffectSet::GetEffectSet(aElement, aPseudoType),
              "EffectSet should not change while composing style");
 }
 
 /* static */ void
 EffectCompositor::GetOverriddenProperties(nsStyleContext* aStyleContext,
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -644,19 +644,20 @@ KeyframeEffectReadOnly::ComposeStyleRule
     aAnimationRule->AddValue(aProperty.mProperty, interpolated);
   } else if (valuePosition < 0.5) {
     aAnimationRule->AddValue(aProperty.mProperty, servoFromValue);
   } else {
     aAnimationRule->AddValue(aProperty.mProperty, servoToValue);
   }
 }
 
+template<typename ComposeAnimationResult>
 void
 KeyframeEffectReadOnly::ComposeStyle(
-  AnimationRule& aStyleRule,
+  ComposeAnimationResult&& aComposeResult,
   const nsCSSPropertyIDSet& aPropertiesToSkip)
 {
   MOZ_DIAGNOSTIC_ASSERT(!mIsComposingStyle,
                         "Should not be called recursively");
   if (mIsComposingStyle) {
     return;
   }
 
@@ -666,18 +667,16 @@ KeyframeEffectReadOnly::ComposeStyle(
   ComputedTiming computedTiming = GetComputedTiming();
 
   // If the progress is null, we don't have fill data for the current
   // time so we shouldn't animate.
   if (computedTiming.mProgress.IsNull()) {
     return;
   }
 
-  bool isServoBackend = mDocument->IsStyledByServo();
-
   for (size_t propIdx = 0, propEnd = mProperties.Length();
        propIdx != propEnd; ++propIdx)
   {
     const AnimationProperty& prop = mProperties[propIdx];
 
     MOZ_ASSERT(prop.mSegments[0].mFromKey == 0.0, "incorrect first from key");
     MOZ_ASSERT(prop.mSegments[prop.mSegments.Length() - 1].mToKey == 1.0,
                "incorrect last to key");
@@ -701,27 +700,20 @@ KeyframeEffectReadOnly::ComposeStyle(
       MOZ_ASSERT(segment->mFromKey == (segment-1)->mToKey, "incorrect keys");
     }
     MOZ_ASSERT(segment->mFromKey <= segment->mToKey, "incorrect keys");
     MOZ_ASSERT(segment >= prop.mSegments.Elements() &&
                size_t(segment - prop.mSegments.Elements()) <
                  prop.mSegments.Length(),
                "out of array bounds");
 
-    if (isServoBackend) {
-      ComposeStyleRule(aStyleRule.mServo,
-                       prop,
-                       *segment,
-                       computedTiming);
-    } else {
-      ComposeStyleRule(aStyleRule.mGecko,
-                       prop,
-                       *segment,
-                       computedTiming);
-    }
+    ComposeStyleRule(Forward<ComposeAnimationResult>(aComposeResult),
+                     prop,
+                     *segment,
+                     computedTiming);
   }
 }
 
 bool
 KeyframeEffectReadOnly::IsRunningOnCompositor() const
 {
   // We consider animation is running on compositor if there is at least
   // one property running on compositor.
@@ -1816,10 +1808,22 @@ KeyframeEffectReadOnly::ContainsAnimated
         }
       }
     }
   }
 
   return false;
 }
 
+template
+void
+KeyframeEffectReadOnly::ComposeStyle<RefPtr<AnimValuesStyleRule>&>(
+  RefPtr<AnimValuesStyleRule>& aAnimationRule,
+  const nsCSSPropertyIDSet& aPropertiesToSkip);
+
+template
+void
+KeyframeEffectReadOnly::ComposeStyle<RefPtr<ServoAnimationRule>&>(
+  RefPtr<ServoAnimationRule>& aAnimationRule,
+  const nsCSSPropertyIDSet& aPropertiesToSkip);
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/animation/KeyframeEffectReadOnly.h
+++ b/dom/animation/KeyframeEffectReadOnly.h
@@ -250,20 +250,21 @@ public:
   void UpdateProperties(const ServoComputedStyleValues& aServoValues);
 
   // Update various bits of state related to running ComposeStyle().
   // We need to update this outside ComposeStyle() because we should avoid
   // mutating any state in ComposeStyle() since it might be called during
   // parallel traversal.
   void WillComposeStyle();
 
-  // Updates |aStyleRule| with the animation values produced by this
+  // Updates |aComposeResult| with the animation values produced by this
   // AnimationEffect for the current time except any properties contained
   // in |aPropertiesToSkip|.
-  void ComposeStyle(AnimationRule& aStyleRule,
+  template<typename ComposeAnimationResult>
+  void ComposeStyle(ComposeAnimationResult&& aRestultContainer,
                     const nsCSSPropertyIDSet& aPropertiesToSkip);
 
   // Composite |aValueToComposite| on |aUnderlyingValue| with
   // |aCompositeOperation|.
   // Returns |aValueToComposite| if |aCompositeOperation| is Replace.
   static StyleAnimationValue CompositeValue(
     nsCSSPropertyID aProperty,
     const StyleAnimationValue& aValueToComposite,