Bug 1339690 - Part 6: Move GetComputedKeyframeValues into local static.
MozReview-Commit-ID: Ay3i9fDSbVg
--- 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