Bug 1340958 - Templatize ComposeStyle. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Fri, 17 Mar 2017 13:22:13 +0900
changeset 500411 012bc91dd05a30dcdebdca7eece969ec170ccada
parent 500410 e831c88ec75c2cbd2d41ad305a541333e15342ab
child 500412 65829f2ad612553196750081c512523ad777208e
push id49724
push userhikezoe@mozilla.com
push dateFri, 17 Mar 2017 06:26:10 +0000
reviewersbirtles
bugs1340958
milestone55.0a1
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,