Bug 1354947 - Merge keyframe values at the same offset and of the same timing function. r=birtles
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Sat, 13 May 2017 16:34:38 +0900
changeset 406327 ff4aff7e187625419e54bfc6299736edb3fdcc11
parent 406326 bdc6e25aafacaa9d88af37936e9d7b346b0ad4a4
child 406328 74d863bcc6dd0497288f41040a0383afaed64167
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
bugs1354947
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 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);