Bug 1339690 - Part 6: Move GetComputedKeyframeValues into local static. draft
authorBoris Chiou <boris.chiou@gmail.com>
Wed, 14 Jun 2017 12:51:27 +0800
changeset 594709 5dfddca5201194de9ffc34836e2296792c3629dc
parent 594708 6f829eb38b0b18958f8c10aa2d98c58c53d3861e
child 594710 c2c385fbee2efd575b216bdc266389d2d2a9b271
push id64112
push userbmo:boris.chiou@gmail.com
push dateThu, 15 Jun 2017 10:38:49 +0000
bugs1339690
milestone56.0a1
Bug 1339690 - Part 6: Move GetComputedKeyframeValues into local static. MozReview-Commit-ID: Ay3i9fDSbVg
dom/animation/KeyframeEffectReadOnly.cpp
dom/animation/KeyframeUtils.cpp
dom/animation/KeyframeUtils.h
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -917,25 +917,21 @@ KeyframeEffectReadOnly::BuildProperties(
   // When GetComputedKeyframeValues or GetAnimationPropertiesFromKeyframes
   // calculate computed values from |mKeyframes|, they could possibly
   // trigger a subsequent restyle in which we rebuild animations. If that
   // happens we could find that |mKeyframes| is overwritten while it is
   // being iterated over. Normally that shouldn't happen but just in case we
   // make a copy of |mKeyframes| first and iterate over that instead.
   auto keyframesCopy(mKeyframes);
 
-  nsTArray<ComputedKeyframeValues> computedValues =
-    KeyframeUtils::GetComputedKeyframeValues(keyframesCopy,
-                                             mTarget->mElement,
-                                             aStyle);
-
   result =
     KeyframeUtils::GetAnimationPropertiesFromKeyframes(
       keyframesCopy,
-      computedValues,
+      mTarget->mElement,
+      aStyle,
       mEffectOptions.mComposite);
 
 #ifdef DEBUG
   MOZ_ASSERT(SpecifiedKeyframeArraysAreEqual(mKeyframes, keyframesCopy),
              "Apart from the computed offset members, the keyframes array"
              " should not be modified");
 #endif
 
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -388,16 +388,26 @@ HasValidOffsets(const nsTArray<Keyframe>
 #ifdef DEBUG
 static void
 MarkAsComputeValuesFailureKey(PropertyValuePair& aPair);
 
 static bool
 IsComputeValuesFailureKey(const PropertyValuePair& aPair);
 #endif
 
+static nsTArray<ComputedKeyframeValues>
+GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
+                          dom::Element* aElement,
+                          nsStyleContext* aStyleContext);
+
+static nsTArray<ComputedKeyframeValues>
+GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
+                          dom::Element* aElement,
+                          const ServoComputedValues* aComputedValues);
+
 static void
 BuildSegmentsFromValueEntries(nsTArray<KeyframeValueEntry>& aEntries,
                               nsTArray<AnimationProperty>& aResult);
 
 static void
 GetKeyframeListFromPropertyIndexedKeyframe(JSContext* aCx,
                                            nsIDocument* aDocument,
                                            JS::Handle<JS::Value> aValue,
@@ -495,123 +505,35 @@ KeyframeUtils::DistributeKeyframes(nsTAr
     keyframeB->mComputedOffset = keyframeB->mOffset.valueOr(1.0);
 
     // Fill computed offsets in (keyframe A, keyframe B).
     DistributeRange(Range<Keyframe>(keyframeA, keyframeB + 1));
     keyframeA = keyframeB;
   }
 }
 
-/* static */ nsTArray<ComputedKeyframeValues>
-KeyframeUtils::GetComputedKeyframeValues(
-  const nsTArray<Keyframe>& aKeyframes,
-  dom::Element* aElement,
-  const ServoComputedValues* aComputedValues)
-{
-  MOZ_ASSERT(aElement);
-  MOZ_ASSERT(aElement->IsStyledByServo());
-
-  nsPresContext* presContext = nsContentUtils::GetContextForContent(aElement);
-  MOZ_ASSERT(presContext);
-
-  return presContext->StyleSet()->AsServo()
-    ->GetComputedKeyframeValuesFor(aKeyframes, aElement, aComputedValues);
-}
-
-/* static */ nsTArray<ComputedKeyframeValues>
-KeyframeUtils::GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
-                                         dom::Element* aElement,
-                                         nsStyleContext* aStyleContext)
-{
-  MOZ_ASSERT(aStyleContext);
-  MOZ_ASSERT(aElement);
-
-  const size_t len = aKeyframes.Length();
-  nsTArray<ComputedKeyframeValues> result(len);
-
-  for (const Keyframe& frame : aKeyframes) {
-    nsCSSPropertyIDSet propertiesOnThisKeyframe;
-    ComputedKeyframeValues* computedValues = result.AppendElement();
-    for (const PropertyValuePair& pair :
-           PropertyPriorityIterator(frame.mPropertyValues)) {
-      MOZ_ASSERT(!pair.mServoDeclarationBlock,
-                 "Animation values were parsed using Servo backend but target"
-                 " element is not using Servo backend?");
-
-      if (IsInvalidValuePair(pair, StyleBackendType::Gecko)) {
-        continue;
-      }
-
-      // Expand each value into the set of longhands and produce
-      // a KeyframeValueEntry for each value.
-      nsTArray<PropertyStyleAnimationValuePair> values;
-
-      // For shorthands, we store the string as a token stream so we need to
-      // extract that first.
-      if (nsCSSProps::IsShorthand(pair.mProperty)) {
-        nsCSSValueTokenStream* tokenStream = pair.mValue.GetTokenStreamValue();
-        if (!StyleAnimationValue::ComputeValues(pair.mProperty,
-              CSSEnabledState::eForAllContent, aElement, aStyleContext,
-              tokenStream->mTokenStream, /* aUseSVGMode */ false, values)) {
-          continue;
-        }
-
-#ifdef DEBUG
-        if (IsComputeValuesFailureKey(pair)) {
-          continue;
-        }
-#endif
-      } else if (pair.mValue.GetUnit() == eCSSUnit_Null) {
-        // An uninitialized nsCSSValue represents the underlying value which
-        // we represent as an uninitialized AnimationValue so we just leave
-        // neutralPair->mValue as-is.
-        PropertyStyleAnimationValuePair* neutralPair = values.AppendElement();
-        neutralPair->mProperty = pair.mProperty;
-      } else {
-        if (!StyleAnimationValue::ComputeValues(pair.mProperty,
-              CSSEnabledState::eForAllContent, aElement, aStyleContext,
-              pair.mValue, /* aUseSVGMode */ false, values)) {
-          continue;
-        }
-        MOZ_ASSERT(values.Length() == 1,
-                  "Longhand properties should produce a single"
-                  " StyleAnimationValue");
-      }
-
-      for (auto& value : values) {
-        // If we already got a value for this property on the keyframe,
-        // skip this one.
-        if (propertiesOnThisKeyframe.HasProperty(value.mProperty)) {
-          continue;
-        }
-        propertiesOnThisKeyframe.AddProperty(value.mProperty);
-        computedValues->AppendElement(Move(value));
-      }
-    }
-  }
-
-  MOZ_ASSERT(result.Length() == aKeyframes.Length(), "Array length mismatch");
-  return result;
-}
-
+template<typename StyleType>
 /* static */ nsTArray<AnimationProperty>
 KeyframeUtils::GetAnimationPropertiesFromKeyframes(
   const nsTArray<Keyframe>& aKeyframes,
-  const nsTArray<ComputedKeyframeValues>& aComputedValues,
+  dom::Element* aElement,
+  StyleType* aStyle,
   dom::CompositeOperation aEffectComposite)
 {
-  MOZ_ASSERT(aKeyframes.Length() == aComputedValues.Length(),
+  const nsTArray<ComputedKeyframeValues> computedValues =
+    GetComputedKeyframeValues(aKeyframes, aElement, aStyle);
+  MOZ_ASSERT(aKeyframes.Length() == computedValues.Length(),
              "Array length mismatch");
 
   nsTArray<KeyframeValueEntry> entries(aKeyframes.Length());
 
   const size_t len = aKeyframes.Length();
   for (size_t i = 0; i < len; ++i) {
     const Keyframe& frame = aKeyframes[i];
-    for (auto& value : aComputedValues[i]) {
+    for (auto& value : computedValues[i]) {
       MOZ_ASSERT(frame.mComputedOffset != Keyframe::kComputedOffsetNotSet,
                  "Invalid computed offset");
       KeyframeValueEntry* entry = entries.AppendElement();
       entry->mOffset = frame.mComputedOffset;
       entry->mProperty = value.mProperty;
       entry->mValue = value.mValue;
       entry->mTimingFunction = frame.mTimingFunction;
       entry->mComposite =
@@ -1072,16 +994,125 @@ MarkAsComputeValuesFailureKey(PropertyVa
 static bool
 IsComputeValuesFailureKey(const PropertyValuePair& aPair)
 {
   return nsCSSProps::IsShorthand(aPair.mProperty) &&
          aPair.mSimulateComputeValuesFailure;
 }
 #endif
 
+/**
+ * Calculate the StyleAnimationValues of properties of each keyframe.
+ * This involves expanding shorthand properties into longhand properties,
+ * removing the duplicated properties for each keyframe, and creating an
+ * array of |property:computed value| pairs for each keyframe.
+ *
+ * These computed values are used when computing the final set of
+ * per-property animation values (see GetAnimationPropertiesFromKeyframes).
+ *
+ * @param aKeyframes The input keyframes.
+ * @param aElement The context element.
+ * @param aStyleContext The style context to use when computing values.
+ * @return The set of ComputedKeyframeValues. The length will be the same as
+ *   aFrames.
+ */
+static nsTArray<ComputedKeyframeValues>
+GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
+                          dom::Element* aElement,
+                          nsStyleContext* aStyleContext)
+{
+  MOZ_ASSERT(aStyleContext);
+  MOZ_ASSERT(aElement);
+
+  const size_t len = aKeyframes.Length();
+  nsTArray<ComputedKeyframeValues> result(len);
+
+  for (const Keyframe& frame : aKeyframes) {
+    nsCSSPropertyIDSet propertiesOnThisKeyframe;
+    ComputedKeyframeValues* computedValues = result.AppendElement();
+    for (const PropertyValuePair& pair :
+           PropertyPriorityIterator(frame.mPropertyValues)) {
+      MOZ_ASSERT(!pair.mServoDeclarationBlock,
+                 "Animation values were parsed using Servo backend but target"
+                 " element is not using Servo backend?");
+
+      if (IsInvalidValuePair(pair, StyleBackendType::Gecko)) {
+        continue;
+      }
+
+      // Expand each value into the set of longhands and produce
+      // a KeyframeValueEntry for each value.
+      nsTArray<PropertyStyleAnimationValuePair> values;
+
+      // For shorthands, we store the string as a token stream so we need to
+      // extract that first.
+      if (nsCSSProps::IsShorthand(pair.mProperty)) {
+        nsCSSValueTokenStream* tokenStream = pair.mValue.GetTokenStreamValue();
+        if (!StyleAnimationValue::ComputeValues(pair.mProperty,
+              CSSEnabledState::eForAllContent, aElement, aStyleContext,
+              tokenStream->mTokenStream, /* aUseSVGMode */ false, values)) {
+          continue;
+        }
+
+#ifdef DEBUG
+        if (IsComputeValuesFailureKey(pair)) {
+          continue;
+        }
+#endif
+      } else if (pair.mValue.GetUnit() == eCSSUnit_Null) {
+        // An uninitialized nsCSSValue represents the underlying value which
+        // we represent as an uninitialized AnimationValue so we just leave
+        // neutralPair->mValue as-is.
+        PropertyStyleAnimationValuePair* neutralPair = values.AppendElement();
+        neutralPair->mProperty = pair.mProperty;
+      } else {
+        if (!StyleAnimationValue::ComputeValues(pair.mProperty,
+              CSSEnabledState::eForAllContent, aElement, aStyleContext,
+              pair.mValue, /* aUseSVGMode */ false, values)) {
+          continue;
+        }
+        MOZ_ASSERT(values.Length() == 1,
+                  "Longhand properties should produce a single"
+                  " StyleAnimationValue");
+      }
+
+      for (auto& value : values) {
+        // If we already got a value for this property on the keyframe,
+        // skip this one.
+        if (propertiesOnThisKeyframe.HasProperty(value.mProperty)) {
+          continue;
+        }
+        propertiesOnThisKeyframe.AddProperty(value.mProperty);
+        computedValues->AppendElement(Move(value));
+      }
+    }
+  }
+
+  MOZ_ASSERT(result.Length() == aKeyframes.Length(), "Array length mismatch");
+  return result;
+}
+
+/**
+ * The variation of the above function. This is for Servo backend.
+ */
+static nsTArray<ComputedKeyframeValues>
+GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
+                          dom::Element* aElement,
+                          const ServoComputedValues* aComputedValues)
+{
+  MOZ_ASSERT(aElement);
+  MOZ_ASSERT(aElement->IsStyledByServo());
+
+  nsPresContext* presContext = nsContentUtils::GetContextForContent(aElement);
+  MOZ_ASSERT(presContext);
+
+  return presContext->StyleSet()->AsServo()
+    ->GetComputedKeyframeValuesFor(aKeyframes, aElement, aComputedValues);
+}
+
 static void
 AppendInitialSegment(AnimationProperty* aAnimationProperty,
                      const KeyframeValueEntry& aFirstEntry)
 {
   AnimationPropertySegment* segment =
     aAnimationProperty->mSegments.AppendElement();
   segment->mFromKey        = 0.0f;
   segment->mToKey          = aFirstEntry.mOffset;
--- a/dom/animation/KeyframeUtils.h
+++ b/dom/animation/KeyframeUtils.h
@@ -60,73 +60,46 @@ public:
    */
   static nsTArray<Keyframe>
   GetKeyframesFromObject(JSContext* aCx,
                          nsIDocument* aDocument,
                          JS::Handle<JSObject*> aFrames,
                          ErrorResult& aRv);
 
   /**
-   * Calculate the StyleAnimationValues of properties of each keyframe.
-   * This involves expanding shorthand properties into longhand properties,
-   * removing the duplicated properties for each keyframe, and creating an
-   * array of |property:computed value| pairs for each keyframe.
-   *
-   * These computed values are used *both* when computing the final set of
-   * per-property animation values (see GetAnimationPropertiesFromKeyframes) as
-   * well when applying paced spacing. By returning these values here, we allow
-   * the result to be re-used in both operations.
-   *
-   * @param aKeyframes The input keyframes.
-   * @param aElement The context element.
-   * @param aStyleContext The style context to use when computing values.
-   * @return The set of ComputedKeyframeValues. The length will be the same as
-   *   aFrames.
-   */
-  static nsTArray<ComputedKeyframeValues>
-  GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
-                            dom::Element* aElement,
-                            nsStyleContext* aStyleContext);
-
-  static nsTArray<ComputedKeyframeValues>
-  GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
-                            dom::Element* aElement,
-                            const ServoComputedValues* aComputedValues);
-
-  /**
    * Calculate the computed offset of keyframes by evenly distributing keyframes
    * with a missing offset.
    *
    * @see https://w3c.github.io/web-animations/#calculating-computed-keyframes
    *
    * @param aKeyframes The set of keyframes to adjust.
    */
   static void DistributeKeyframes(nsTArray<Keyframe>& aKeyframes);
 
   /**
    * Converts an array of Keyframe objects into an array of AnimationProperty
    * objects. This involves creating an array of computed values for each
    * longhand property and determining the offset and timing function to use
    * for each value.
    *
    * @param aKeyframes The input keyframes.
-   * @param aComputedValues The computed keyframe values (as returned by
-   *   GetComputedKeyframeValues) used to fill in the individual
-   *   AnimationPropertySegment objects. Although these values could be
-   *   calculated from |aKeyframes|, passing them in as a separate parameter
-   *   allows the result of GetComputedKeyframeValues to be re-used here.
+   * @param aElement The context element.
+   * @param aStyleType The |ServoComputedValues| or |nsStyleContext| to use
+   *   when computing values.
    * @param aEffectComposite The composite operation specified on the effect.
    *   For any keyframes in |aKeyframes| that do not specify a composite
    *   operation, this value will be used.
    * @return The set of animation properties. If an error occurs, the returned
    *   array will be empty.
    */
+  template<typename StyleType>
   static nsTArray<AnimationProperty> GetAnimationPropertiesFromKeyframes(
     const nsTArray<Keyframe>& aKeyframes,
-    const nsTArray<ComputedKeyframeValues>& aComputedValues,
+    dom::Element* aElement,
+    StyleType* aStyleType,
     dom::CompositeOperation aEffectComposite);
 
   /**
    * Check if the property or, for shorthands, one or more of
    * its subproperties, is animatable.
    *
    * @param aProperty The property to check.
    * @param aBackend  The style backend, Servo or Gecko, that should determine