Bug 1354947 - Merge keyframe values at the same offset and of the same timing function. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Sat, 13 May 2017 16:34:38 +0900
changeset 577320 5f5bccab920952be291ffc0b1e28892f216652d4
parent 577319 d9b937ed5ba68d2545e35ae1b28235dd80a63621
child 577321 f9b43acf73fcf3c3a1415990349357a5cb93bfd0
push id58655
push userhikezoe@mozilla.com
push dateSat, 13 May 2017 07:47:48 +0000
reviewersbirtles
bugs1354947
milestone55.0a1
Bug 1354947 - Merge keyframe values at the same offset and of the same timing function. r?birtles MozReview-Commit-ID: 4BTYAGjFb3V
js/src/devtools/rootAnalysis/analyzeHeapWrites.js
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
--- a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
+++ b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
@@ -188,16 +188,17 @@ function treatAsSafeArgument(entry, varN
         ["Gecko_EnsureTArrayCapacity", "aArray", null],
         ["Gecko_ClearPODTArray", "aArray", null],
         ["Gecko_ClearAndResizeStyleContents", "aContent", null],
         [/Gecko_ClearAndResizeCounter/, "aContent", null],
         [/Gecko_CopyCounter.*?From/, "aContent", null],
         [/Gecko_SetContentData/, "aContent", null],
         [/Gecko_EnsureStyle.*?ArrayLength/, "aArray", null],
         ["Gecko_AnimationAppendKeyframe", "aKeyframes", null],
+        ["Gecko_GetOrCreateKeyframeAtStart", "aKeyframes", null],
         ["Gecko_SetStyleCoordCalcValue", null, null],
         ["Gecko_StyleClipPath_SetURLValue", "aClip", null],
         ["Gecko_nsStyleFilter_SetURLValue", "aEffects", null],
         ["Gecko_nsStyleSVGPaint_CopyFrom", "aDest", null],
         ["Gecko_nsStyleSVGPaint_SetURLValue", "aPaint", null],
         ["Gecko_nsStyleSVGPaint_Reset", "aPaint", null],
         ["Gecko_nsStyleSVG_SetDashArrayLength", "aSvg", null],
         ["Gecko_nsStyleSVG_CopyDashArray", "aDst", null],
@@ -369,16 +370,17 @@ function ignoreContents(entry)
         / EmptyString\(\)/,
         /nsCSSProps::LookupPropertyValue/,
         /nsCSSProps::ValueToKeyword/,
         /nsCSSKeywords::GetStringValue/,
 
         // The analysis can't cope with the indirection used for the objects
         // being initialized here.
         "Gecko_AnimationAppendKeyframe",
+        "Gecko_GetOrCreateKeyframeAtStart",
         "Gecko_NewStyleQuoteValues",
         "Gecko_NewCSSValueSharedList",
         "Gecko_NewGridTemplateAreasValue",
         /nsCSSValue::SetCalcValue/,
         /CSSValueSerializeCalcOps::Append/,
         "Gecko_CSSValue_SetFunction",
         "Gecko_CSSValue_SetArray",
         "Gecko_EnsureMozBorderColors",
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -1463,16 +1463,48 @@ Gecko_AnimationAppendKeyframe(RawGeckoKe
       aTimingFunction->mType != nsTimingFunction::Type::Linear) {
     keyframe->mTimingFunction.emplace();
     keyframe->mTimingFunction->Init(*aTimingFunction);
   }
 
   return keyframe;
 }
 
+Keyframe*
+Gecko_GetOrCreateKeyframeAtStart(nsTArray<Keyframe>* aKeyframes,
+                                 float aOffset,
+                                 const nsTimingFunction* aTimingFunction)
+{
+  MOZ_ASSERT(aKeyframes, "The keyframe array should be valid");
+  MOZ_ASSERT(aTimingFunction, "The timing function should be valid");
+  MOZ_ASSERT(aOffset >= 0. && aOffset <= 1.,
+             "The offset should be in the range of [0.0, 1.0]");
+  MOZ_ASSERT(aKeyframes->IsEmpty() ||
+             aKeyframes->ElementAt(0).mOffset.value() >= aOffset,
+             "The offset should be less than or equal to the first keyframe's "
+             "offset if there are exisiting keyframes");
+
+  size_t keyframeIndex;
+  if (nsAnimationManager::FindMatchingKeyframe(*aKeyframes,
+                                               aOffset,
+                                               *aTimingFunction,
+                                               keyframeIndex)) {
+    return &(*aKeyframes)[keyframeIndex];
+  }
+
+  Keyframe* keyframe = aKeyframes->InsertElementAt(0);
+  keyframe->mOffset.emplace(aOffset);
+  if (aTimingFunction->mType != nsTimingFunction::Type::Linear) {
+    keyframe->mTimingFunction.emplace();
+    keyframe->mTimingFunction->Init(*aTimingFunction);
+  }
+
+  return keyframe;
+}
+
 void
 Gecko_ResetStyleCoord(nsStyleUnit* aUnit, nsStyleUnion* aValue)
 {
   nsStyleCoord::Reset(*aUnit, *aValue);
 }
 
 void
 Gecko_SetStyleCoordCalcValue(nsStyleUnit* aUnit, nsStyleUnion* aValue, nsStyleCoord::CalcValue aCalc)
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -367,16 +367,36 @@ void Gecko_EnsureStyleTransitionArrayLen
 void Gecko_ClearWillChange(nsStyleDisplay* display, size_t length);
 void Gecko_AppendWillChange(nsStyleDisplay* display, nsIAtom* atom);
 void Gecko_CopyWillChangeFrom(nsStyleDisplay* dest, nsStyleDisplay* src);
 
 mozilla::Keyframe* Gecko_AnimationAppendKeyframe(RawGeckoKeyframeListBorrowedMut keyframes,
                                                  float offset,
                                                  const nsTimingFunction* timingFunction);
 
+// Searches from the beginning of |keyframes| for a Keyframe object with the
+// specified offset and timing function. If none is found, a new Keyframe object
+// with the specified |offset| and |timingFunction| will be prepended to
+// |keyframes|.
+//
+// @param keyframes  An array of Keyframe objects, sorted by offset.
+//                   The first Keyframe in the array, if any, MUST have an
+//                   offset greater than or equal to |offset|.
+// @param offset  The offset to search for, or, if no suitable Keyframe is
+//                found, the offset to use for the created Keyframe.
+//                Must be a floating point number in the range [0.0, 1.0].
+// @param timingFunction  The timing function to match, or, if no suitable
+//                        Keyframe is found, to set on the created Keyframe.
+//
+// @returns  The matching or created Keyframe.
+mozilla::Keyframe* Gecko_GetOrCreateKeyframeAtStart(
+  RawGeckoKeyframeListBorrowedMut keyframes,
+  float offset,
+  const nsTimingFunction* timingFunction);
+
 // Clean up pointer-based coordinates
 void Gecko_ResetStyleCoord(nsStyleUnit* unit, nsStyleUnion* value);
 
 // Set an nsStyleCoord to a computed `calc()` value
 void Gecko_SetStyleCoordCalcValue(nsStyleUnit* unit, nsStyleUnion* value, nsStyleCoord::CalcValue calc);
 
 void Gecko_CopyShapeSourceFrom(mozilla::StyleShapeSource* dst, const mozilla::StyleShapeSource* src);