Bug 1317208 - Stylo: Store servo computed values for animation properties; r?birtles,heycam
MozReview-Commit-ID: IoQLN5tdIBw
--- a/dom/animation/KeyframeEffectReadOnly.h
+++ b/dom/animation/KeyframeEffectReadOnly.h
@@ -15,18 +15,18 @@
#include "nsTArray.h"
#include "nsWrapperCache.h"
#include "mozilla/AnimationPerformanceWarning.h"
#include "mozilla/AnimationTarget.h"
#include "mozilla/Attributes.h"
#include "mozilla/ComputedTimingFunction.h"
#include "mozilla/EffectCompositor.h"
#include "mozilla/KeyframeEffectParams.h"
-#include "mozilla/ServoBindingTypes.h" // RawServoDeclarationBlock and
- // associated RefPtrTraits
+// RawServoDeclarationBlock and associated RefPtrTraits
+#include "mozilla/ServoBindingTypes.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/dom/AnimationEffectReadOnly.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/Element.h"
struct JSContext;
class JSObject;
class nsIContent;
@@ -118,16 +118,19 @@ struct Keyframe
};
struct AnimationPropertySegment
{
float mFromKey, mToKey;
// NOTE: In the case that no keyframe for 0 or 1 offset is specified
// the unit of mFromValue or mToValue is eUnit_Null.
StyleAnimationValue mFromValue, mToValue;
+ // FIXME add a deep == impl for RawServoAnimationValue
+ RefPtr<RawServoAnimationValue> mServoFromValue, mServoToValue;
+
Maybe<ComputedTimingFunction> mTimingFunction;
dom::CompositeOperation mFromComposite = dom::CompositeOperation::Replace;
dom::CompositeOperation mToComposite = dom::CompositeOperation::Replace;
bool operator==(const AnimationPropertySegment& aOther) const
{
return mFromKey == aOther.mFromKey &&
mToKey == aOther.mToKey &&
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -5,28 +5,30 @@
#include "mozilla/KeyframeUtils.h"
#include "mozilla/AnimationUtils.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/Move.h"
#include "mozilla/RangedArray.h"
#include "mozilla/ServoBindings.h"
+#include "mozilla/ServoBindingTypes.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/TimingParams.h"
#include "mozilla/dom/BaseKeyframeTypesBinding.h" // For FastBaseKeyframe etc.
#include "mozilla/dom/Element.h"
#include "mozilla/dom/KeyframeEffectBinding.h"
#include "mozilla/dom/KeyframeEffectReadOnly.h" // For PropertyValuesPair etc.
#include "jsapi.h" // For ForOfIterator etc.
#include "nsClassHashtable.h"
#include "nsCSSParser.h"
#include "nsCSSPropertyIDSet.h"
#include "nsCSSProps.h"
#include "nsCSSPseudoElements.h" // For CSSPseudoElementType
+#include "nsStyleContext.h"
#include "nsTArray.h"
#include <algorithm> // For std::stable_sort
namespace mozilla {
// ------------------------------------------------------------------
//
// Internal data types
@@ -265,16 +267,18 @@ struct AdditionalProperty
*
* KeyframeValueEntry is used in GetAnimationPropertiesFromKeyframes
* to gather data for each individual segment.
*/
struct KeyframeValueEntry
{
nsCSSPropertyID mProperty;
StyleAnimationValue mValue;
+ RefPtr<RawServoAnimationValue> mServoValue;
+
float mOffset;
Maybe<ComputedTimingFunction> mTimingFunction;
dom::CompositeOperation mComposite;
struct PropertyOffsetComparator
{
static bool Equals(const KeyframeValueEntry& aLhs,
const KeyframeValueEntry& aRhs)
@@ -595,16 +599,26 @@ KeyframeUtils::GetComputedKeyframeValues
MOZ_ASSERT(aStyleContext);
MOZ_ASSERT(aElement);
StyleBackendType styleBackend = aElement->OwnerDoc()->GetStyleBackendType();
const size_t len = aKeyframes.Length();
nsTArray<ComputedKeyframeValues> result(len);
+ const ServoComputedValues* currentStyle = nullptr;
+ const ServoComputedValues* parentStyle = nullptr;
+
+ if (styleBackend == StyleBackendType::Servo) {
+ currentStyle = aStyleContext->StyleSource().AsServoComputedValues();
+ if (aStyleContext->GetParent()) {
+ parentStyle = aStyleContext->GetParent()->StyleSource().AsServoComputedValues();
+ }
+ }
+
for (const Keyframe& frame : aKeyframes) {
nsCSSPropertyIDSet propertiesOnThisKeyframe;
ComputedKeyframeValues* computedValues = result.AppendElement();
for (const PropertyValuePair& pair :
PropertyPriorityIterator(frame.mPropertyValues)) {
MOZ_ASSERT(!pair.mServoDeclarationBlock ||
styleBackend == StyleBackendType::Servo,
"Animation values were parsed using Servo backend but target"
@@ -619,16 +633,21 @@ KeyframeUtils::GetComputedKeyframeValues
nsTArray<PropertyStyleAnimationValuePair> values;
if (styleBackend == StyleBackendType::Servo) {
if (!StyleAnimationValue::ComputeValues(pair.mProperty,
CSSEnabledState::eForAllContent, aStyleContext,
*pair.mServoDeclarationBlock, values)) {
continue;
}
+ Servo_AnimationValues_Populate(&values,
+ pair.mServoDeclarationBlock,
+ currentStyle,
+ parentStyle,
+ aStyleContext->PresContext());
} else {
// 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) ||
@@ -648,18 +667,18 @@ KeyframeUtils::GetComputedKeyframeValues
}
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;
}
- computedValues->AppendElement(value);
propertiesOnThisKeyframe.AddProperty(value.mProperty);
+ computedValues->AppendElement(Move(value));
}
}
}
MOZ_ASSERT(result.Length() == aKeyframes.Length(), "Array length mismatch");
return result;
}
@@ -680,16 +699,17 @@ KeyframeUtils::GetAnimationPropertiesFro
const Keyframe& frame = aKeyframes[i];
for (auto& value : aComputedValues[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->mServoValue = value.mServoValue;
entry->mTimingFunction = frame.mTimingFunction;
entry->mComposite =
frame.mComposite ? frame.mComposite.value() : aEffectComposite;
}
}
nsTArray<AnimationProperty> result;
BuildSegmentsFromValueEntries(entries, result);
@@ -1366,23 +1386,25 @@ BuildSegmentsFromValueEntries(nsTArray<K
lastProperty = aEntries[i].mProperty;
}
MOZ_ASSERT(animationProperty, "animationProperty should be valid pointer.");
// Now generate the segment.
AnimationPropertySegment* segment =
animationProperty->mSegments.AppendElement();
- segment->mFromKey = aEntries[i].mOffset;
- segment->mToKey = aEntries[j].mOffset;
- segment->mFromValue = aEntries[i].mValue;
- segment->mToValue = aEntries[j].mValue;
+ segment->mFromKey = aEntries[i].mOffset;
+ segment->mToKey = aEntries[j].mOffset;
+ segment->mFromValue = aEntries[i].mValue;
+ segment->mToValue = aEntries[j].mValue;
+ segment->mServoFromValue = aEntries[i].mServoValue;
+ segment->mServoToValue = aEntries[j].mServoValue;
segment->mTimingFunction = aEntries[i].mTimingFunction;
- segment->mFromComposite = aEntries[i].mComposite;
- segment->mToComposite = aEntries[j].mComposite;
+ segment->mFromComposite = aEntries[i].mComposite;
+ segment->mToComposite = aEntries[j].mComposite;
i = j;
}
}
/**
* Converts a JS object representing a property-indexed keyframe into
* an array of Keyframe objects.
--- a/layout/style/ServoArcTypeList.h
+++ b/layout/style/ServoArcTypeList.h
@@ -7,8 +7,9 @@
/* a list of all Servo Arc types used in stylo bindings for preprocessing */
SERVO_ARC_TYPE(CssRules, ServoCssRules)
SERVO_ARC_TYPE(StyleSheet, RawServoStyleSheet)
SERVO_ARC_TYPE(ComputedValues, ServoComputedValues)
SERVO_ARC_TYPE(DeclarationBlock, RawServoDeclarationBlock)
SERVO_ARC_TYPE(StyleRule, RawServoStyleRule)
SERVO_ARC_TYPE(ImportRule, RawServoImportRule)
+SERVO_ARC_TYPE(AnimationValue, RawServoAnimationValue)
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -102,16 +102,24 @@ SERVO_BINDING_FUNC(Servo_ParseProperty,
ThreadSafeURIHolder* referrer,
ThreadSafePrincipalHolder* principal)
SERVO_BINDING_FUNC(Servo_RestyleWithAddedDeclaration,
ServoComputedValuesStrong,
RawServoStyleSetBorrowed set,
RawServoDeclarationBlockBorrowed declarations,
ServoComputedValuesBorrowed previous_style)
+// AnimationValues handling
+SERVO_BINDING_FUNC(Servo_AnimationValues_Populate, void,
+ RawGeckoAnimationValueListBorrowedMut,
+ RawServoDeclarationBlockBorrowed,
+ ServoComputedValuesBorrowed,
+ ServoComputedValuesBorrowedOrNull,
+ RawGeckoPresContextBorrowed)
+
// Style attribute
SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, RawServoDeclarationBlockStrong,
const nsACString* data)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_CreateEmpty,
RawServoDeclarationBlockStrong)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_Clone, RawServoDeclarationBlockStrong,
RawServoDeclarationBlockBorrowed declarations)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_Equals, bool,
--- a/layout/style/ServoBindingTypes.h
+++ b/layout/style/ServoBindingTypes.h
@@ -3,44 +3,49 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ServoBindingTypes_h
#define mozilla_ServoBindingTypes_h
#include "mozilla/RefPtr.h"
+#include "mozilla/ServoTypes.h"
#include "mozilla/UniquePtr.h"
+#include "nsTArray.h"
+struct RawServoAnimationValue;
struct RawServoStyleSet;
#define SERVO_ARC_TYPE(name_, type_) struct type_;
#include "mozilla/ServoArcTypeList.h"
#undef SERVO_ARC_TYPE
namespace mozilla {
class ServoElementSnapshot;
namespace dom {
class Element;
class StyleChildrenIterator;
} // namespace dom
+struct PropertyStyleAnimationValuePair;
} // namespace mozilla
class nsCSSValue;
class nsIDocument;
class nsINode;
class nsPresContext;
using mozilla::dom::StyleChildrenIterator;
using mozilla::ServoElementSnapshot;
typedef nsINode RawGeckoNode;
typedef mozilla::dom::Element RawGeckoElement;
typedef nsIDocument RawGeckoDocument;
typedef nsPresContext RawGeckoPresContext;
+typedef nsTArray<mozilla::PropertyStyleAnimationValuePair> RawGeckoAnimationValueList;
// We have these helper types so that we can directly generate
// things like &T or Borrowed<T> on the Rust side in the function, providing
// additional safety benefits.
//
// FFI has a problem with templated types, so we just use raw pointers here.
//
// The "Borrowed" types generate &T or Borrowed<T> in the nullable case.
@@ -98,16 +103,17 @@ DECL_BORROWED_REF_TYPE_FOR(RawGeckoEleme
DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoElement)
DECL_BORROWED_REF_TYPE_FOR(RawGeckoDocument)
DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoDocument)
DECL_BORROWED_MUT_REF_TYPE_FOR(StyleChildrenIterator)
DECL_BORROWED_MUT_REF_TYPE_FOR(ServoElementSnapshot)
DECL_BORROWED_REF_TYPE_FOR(nsCSSValue)
DECL_BORROWED_MUT_REF_TYPE_FOR(nsCSSValue)
DECL_BORROWED_REF_TYPE_FOR(RawGeckoPresContext)
+DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoAnimationValueList)
#undef DECL_ARC_REF_TYPE_FOR
#undef DECL_OWNED_REF_TYPE_FOR
#undef DECL_NULLABLE_OWNED_REF_TYPE_FOR
#undef DECL_BORROWED_REF_TYPE_FOR
#undef DECL_NULLABLE_BORROWED_REF_TYPE_FOR
#undef DECL_BORROWED_MUT_REF_TYPE_FOR
#undef DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR
@@ -125,23 +131,27 @@ DECL_BORROWED_REF_TYPE_FOR(RawGeckoPresC
static void Release(type_* aPtr) { \
Servo_##name_##_Release(aPtr); \
} \
}; \
}
#include "mozilla/ServoArcTypeList.h"
#undef SERVO_ARC_TYPE
-extern "C" void Servo_StyleSet_Drop(RawServoStyleSetOwned ptr);
+#define DEFINE_BOXED_TYPE(name_, type_) \
+ extern "C" void Servo_##name_##_Drop(type_##Owned ptr); \
+ namespace mozilla { \
+ template<> \
+ class DefaultDelete<type_> \
+ { \
+ public: \
+ void operator()(type_* aPtr) const \
+ { \
+ Servo_##name_##_Drop(aPtr); \
+ } \
+ }; \
+ }
-namespace mozilla {
-template<>
-class DefaultDelete<RawServoStyleSet>
-{
-public:
- void operator()(RawServoStyleSet* aPtr) const
- {
- Servo_StyleSet_Drop(aPtr);
- }
-};
-}
+DEFINE_BOXED_TYPE(StyleSet, RawServoStyleSet);
+
+#undef DEFINE_BOXED_TYPE
#endif // mozilla_ServoBindingTypes_h
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -4,16 +4,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Utilities for animation of computed style values */
#ifndef mozilla_StyleAnimationValue_h_
#define mozilla_StyleAnimationValue_h_
#include "mozilla/gfx/MatrixFwd.h"
+#include "mozilla/ServoBindingTypes.h"
#include "mozilla/UniquePtr.h"
#include "nsStringFwd.h"
#include "nsStringBuffer.h"
#include "nsCoord.h"
#include "nsColor.h"
#include "nsCSSProps.h"
#include "nsCSSValue.h"
#include "nsStyleCoord.h"
@@ -580,12 +581,13 @@ private:
return aUnit == eUnit_UnparsedString;
}
};
struct PropertyStyleAnimationValuePair
{
nsCSSPropertyID mProperty;
StyleAnimationValue mValue;
+ RefPtr<RawServoAnimationValue> mServoValue;
};
} // namespace mozilla
#endif