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
--- 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