Bug 1244590 - Part 6: Refactor the calculation of StyleAnimationValue. draft
authorBoris Chiou <boris.chiou@gmail.com>
Thu, 12 May 2016 16:10:29 +0800
changeset 369281 55f22e782b94108fce7fd4226972f1f730cf6e19
parent 369280 62c4f215a5d400c338cd931648a5edf14df0ea0e
child 369282 45cd569bdd7ae6b6a1feb46088dedebd959efe9a
push id18826
push userbmo:boris.chiou@gmail.com
push dateSat, 21 May 2016 11:25:24 +0000
bugs1244590
milestone49.0a1
Bug 1244590 - Part 6: Refactor the calculation of StyleAnimationValue. We want to reuse the StyleAnimationValues of properties of each keyframe when applying spacing and building animation property segments, so refactor this part. MozReview-Commit-ID: 8G56C3BU3FR
dom/animation/KeyframeEffect.cpp
dom/animation/KeyframeUtils.cpp
dom/animation/KeyframeUtils.h
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -510,21 +510,23 @@ KeyframeEffectReadOnly::HasAnimationOfPr
 
 void
 KeyframeEffectReadOnly::UpdateProperties(nsStyleContext* aStyleContext)
 {
   MOZ_ASSERT(aStyleContext);
 
   nsTArray<AnimationProperty> properties;
   if (mTarget) {
+    KeyframeAnimValues keyframeAnimValues =
+      KeyframeUtils::CalculateAnimationValues(mKeyframes, mTarget->mElement,
+                                              aStyleContext);
+
     properties =
-      KeyframeUtils::GetAnimationPropertiesFromKeyframes(aStyleContext,
-                                                         mTarget->mElement,
-                                                         mTarget->mPseudoType,
-                                                         mKeyframes);
+      KeyframeUtils::GetAnimationPropertiesFromKeyframes(mKeyframes,
+                                                         keyframeAnimValues);
   }
 
   if (mProperties == properties) {
     return;
   }
 
   // Preserve the state of mWinsInCascade and mIsRunningOnCompositor flags.
   nsCSSPropertySet winningInCascadeProperties;
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -487,32 +487,34 @@ KeyframeUtils::ApplySpacing(nsTArray<Key
     } else {
       // TODO
       MOZ_ASSERT(false, "not implement yet");
     }
     i = j;
   }
 }
 
-/* static */ nsTArray<AnimationProperty>
-KeyframeUtils::GetAnimationPropertiesFromKeyframes(
-    nsStyleContext* aStyleContext,
-    dom::Element* aElement,
-    CSSPseudoElementType aPseudoType,
-    const nsTArray<Keyframe>& aFrames)
+/* static */ KeyframeAnimValues
+KeyframeUtils::CalculateAnimationValues(const nsTArray<Keyframe>& aFrames,
+                                        dom::Element* aElement,
+                                        nsStyleContext* aStyleContext)
 {
   MOZ_ASSERT(aStyleContext);
   MOZ_ASSERT(aElement);
 
-  nsTArray<KeyframeValueEntry> entries;
+  // The length should be the same as aFrames.
+  const size_t len = aFrames.Length();
+  KeyframeAnimValues result;
+  result.SetLength(len);
+  MOZ_ASSERT(result.Length() == len);
 
-  for (const Keyframe& frame : aFrames) {
+  for (size_t i = 0; i < len; ++i) {
     nsCSSPropertySet propertiesOnThisKeyframe;
     for (const PropertyValuePair& pair :
-           PropertyPriorityIterator(frame.mPropertyValues)) {
+           PropertyPriorityIterator(aFrames[i].mPropertyValues)) {
       if (IsInvalidValuePair(pair)) {
         continue;
       }
 
       // Expand each value into the set of longhands and produce
       // a KeyframeValueEntry for each value.
       nsTArray<PropertyStyleAnimationValuePair> values;
 
@@ -537,29 +539,61 @@ KeyframeUtils::GetAnimationPropertiesFro
       }
 
       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;
         }
-
-        KeyframeValueEntry* entry = entries.AppendElement();
-        MOZ_ASSERT(frame.mComputedOffset != -1.0, "Invalid computed offset");
-        entry->mOffset = frame.mComputedOffset;
-        entry->mProperty = value.mProperty;
-        entry->mValue = value.mValue;
-        entry->mTimingFunction = frame.mTimingFunction;
-
+        result[i].AppendElement(value);
         propertiesOnThisKeyframe.AddProperty(value.mProperty);
       }
     }
   }
 
+  // debug
+  /*printf_stderr("[Boris] After calculate StyleAnimationValue\n");
+  for (size_t i = 0;i < result.Length(); ++i) {
+    for (auto& pair: result[i]) {
+      nsCString debug = nsCSSProps::GetStringValue(pair.mProperty);
+      printf_stderr("[Boris] Keyframes[%zu].mProperty = %s\n", i, debug.get());
+    }
+  }*/
+
+  return result;
+}
+
+/* static */ nsTArray<AnimationProperty>
+KeyframeUtils::GetAnimationPropertiesFromKeyframes(
+  const nsTArray<Keyframe>& aFrames,
+  const KeyframeAnimValues& aValues)
+{
+  MOZ_ASSERT(aFrames.Length() == aValues.Length(), "Array length mismatch");
+
+  nsTArray<KeyframeValueEntry> entries;
+
+  const size_t len = aFrames.Length();
+  for (size_t i = 0; i < len; ++i) {
+    const Keyframe& frame = aFrames[i];
+    for (auto& value : aValues[i]) {
+      KeyframeValueEntry* entry = entries.AppendElement();
+      entry->mOffset = frame.mComputedOffset;
+      entry->mProperty = value.mProperty;
+      entry->mValue = value.mValue;
+      entry->mTimingFunction = frame.mTimingFunction;
+
+      /*{
+        nsCString debug = nsCSSProps::GetStringValue(value.mProperty);
+        printf_stderr("[Boris] Create KeyframeValueEntry at %zu: (name: %s), (offset: %lf)\n",
+            i, debug.get(), entry->mOffset);
+      }*/
+    }
+  }
+
   nsTArray<AnimationProperty> result;
   BuildSegmentsFromValueEntries(entries, result);
 
   return result;
 }
 
 
 // ------------------------------------------------------------------
@@ -926,16 +960,25 @@ BuildSegmentsFromValueEntries(nsTArray<K
     return;
   }
 
   // Sort the KeyframeValueEntry objects so that all entries for a given
   // property are together, and the entries are sorted by offset otherwise.
   std::stable_sort(aEntries.begin(), aEntries.end(),
                    &KeyframeValueEntry::PropertyOffsetComparator::LessThan);
 
+
+  /*size_t count = 0;
+  for (auto& entry : aEntries) {
+
+    nsCString debug = nsCSSProps::GetStringValue(entry.mProperty);
+    printf_stderr("[Boris] Sorted KeyframeValueEntry at %zu: (name: %s), (offset: %lf)\n",
+        count++, debug.get(), entry.mOffset);
+  }*/
+
   MOZ_ASSERT(aEntries[0].mOffset == 0.0f);
   MOZ_ASSERT(aEntries.LastElement().mOffset == 1.0f);
 
   // For a given index i, we want to generate a segment from aEntries[i]
   // to aEntries[j], if:
   //
   //   * j > i,
   //   * aEntries[i + 1]'s offset/property is different from aEntries[i]'s, and
@@ -1182,19 +1225,17 @@ RequiresAdditiveAnimation(const nsTArray
     }
   }
 
   return !propertiesWithFromValue.Equals(properties) ||
          !propertiesWithToValue.Equals(properties);
 }
 
 /**
- * Apply evenly distributing computed offsets in (A, B). We should pass the
- * range keyframes in [A, B] and use A, B to calculate computed offsets in
- * (A, B).
+ * Apply evenly distributing computed offsets.
  *
  * @param aDistributeRange The set of keyframes.
  */
 static void
 ApplyDistributingOffset(const Range<Keyframe>& aDistributeRange)
 {
   const size_t n = aDistributeRange.length() - 1;
   const double start = aDistributeRange[0].mComputedOffset;
--- a/dom/animation/KeyframeUtils.h
+++ b/dom/animation/KeyframeUtils.h
@@ -22,16 +22,18 @@ struct Keyframe;
 namespace dom {
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 
 namespace mozilla {
 
+using KeyframeAnimValues = nsTArray<nsTArray<PropertyStyleAnimationValuePair>>;
+
 /**
  * Utility methods for processing keyframes.
  */
 class KeyframeUtils
 {
 public:
   /**
    * Converts a JS value representing a property-indexed keyframe or a sequence
@@ -47,41 +49,55 @@ public:
    *   returned.
    */
   static nsTArray<Keyframe>
   GetKeyframesFromObject(JSContext* aCx,
                          JS::Handle<JSObject*> aFrames,
                          ErrorResult& aRv);
 
   /**
+   * Calculate the StyleAnimationValues of properties of each keyframe.
+   *
+   * @param aFrames The input keyframes.
+   * @param aElement The context element.
+   * @param aStyleContext The style context to use when computing values.
+   * @return The set of nsTArray<PropertyStyleAnimationValuePair>. The length
+   *   should be the same as aFrames.
+   */
+  static KeyframeAnimValues
+  CalculateAnimationValues(const nsTArray<Keyframe>& aFrames,
+                           dom::Element* aElement,
+                           nsStyleContext* aStyleContext);
+
+  /**
    * Fills in the mComputedOffset member of each keyframe in the given array
    * using the specified spacing mode.
    *
    * http://w3c.github.io/web-animations/#spacing-keyframes
    *
    * @param aKeyframes The set of keyframes to adjust.
    * @param aSpacingMode The applied spacing mode to aKeyframes.
    */
-  static void ApplySpacing(nsTArray<Keyframe>& aKeyframes,
-                           SpacingMode aSpacingMode);
+  static void
+  ApplySpacing(nsTArray<Keyframe>& aKeyframes,
+               SpacingMode aSpacingMode);
 
   /**
    * Converts an array of Keyframe objects into an array of AnimationProperty
    * objects. This involves expanding shorthand properties into longhand
    * properties, creating an array of computed values for each longhand
    * property and determining the offset and timing function to use for each
    * value.
    *
-   * @param aStyleContext The style context to use when computing values.
    * @param aFrames The input keyframes.
+   * @param aValues The calculated StyleAnimatioValues of properties of each
+   *   keyframe.
    * @return The set of animation properties. If an error occurs, the returned
    *   array will be empty.
    */
   static nsTArray<AnimationProperty>
-  GetAnimationPropertiesFromKeyframes(nsStyleContext* aStyleContext,
-                                      dom::Element* aElement,
-                                      CSSPseudoElementType aPseudoType,
-                                      const nsTArray<Keyframe>& aFrames);
+  GetAnimationPropertiesFromKeyframes(const nsTArray<Keyframe>& aFrames,
+                                      const KeyframeAnimValues& aValues);
 };
 
 } // namespace mozilla
 
 #endif // mozilla_KeyframeUtils_h