Bug 1340005 - Part 5: Implement SampleValue for Servo backend.
Use the new added FFI, Servo_ComposeAnimationSegment, to compose an
animation segment from Servo backend on the compositor.
MozReview-Commit-ID: LNgpCSIlDl9
--- a/gfx/layers/AnimationHelper.cpp
+++ b/gfx/layers/AnimationHelper.cpp
@@ -13,21 +13,16 @@
#include "mozilla/layers/LayerAnimationUtils.h" // for TimingFunctionToComputedTimingFunction
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
#include "nsDeviceContext.h" // for AppUnitsPerCSSPixel
#include "nsDisplayList.h" // for nsDisplayTransform, etc
namespace mozilla {
namespace layers {
-struct StyleAnimationValueCompositePair {
- StyleAnimationValue mValue;
- dom::CompositeOperation mComposite;
-};
-
void
CompositorAnimationStorage::Clear()
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
mAnimatedValues.Clear();
mAnimations.Clear();
}
@@ -134,36 +129,37 @@ CompositorAnimationStorage::SetAnimation
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
AnimationArray* value = new AnimationArray(aValue);
mAnimations.Put(aId, value);
}
static StyleAnimationValue
SampleValue(double aPortion, const layers::Animation& aAnimation,
- const StyleAnimationValueCompositePair& aStart,
- const StyleAnimationValueCompositePair& aEnd,
+ const AnimationPropertySegment&& aSegment,
const StyleAnimationValue& aLastValue,
uint64_t aCurrentIteration,
const StyleAnimationValue& aUnderlyingValue)
{
- NS_ASSERTION(aStart.mValue.IsNull() || aEnd.mValue.IsNull() ||
- aStart.mValue.GetUnit() == aEnd.mValue.GetUnit(),
+ NS_ASSERTION(aSegment.mFromValue.mGecko.IsNull() ||
+ aSegment.mToValue.mGecko.IsNull() ||
+ aSegment.mFromValue.mGecko.GetUnit() ==
+ aSegment.mToValue.mGecko.GetUnit(),
"Must have same unit");
StyleAnimationValue startValue =
dom::KeyframeEffectReadOnly::CompositeValue(aAnimation.property(),
- aStart.mValue,
+ aSegment.mFromValue.mGecko,
aUnderlyingValue,
- aStart.mComposite);
+ aSegment.mFromComposite);
StyleAnimationValue endValue =
dom::KeyframeEffectReadOnly::CompositeValue(aAnimation.property(),
- aEnd.mValue,
+ aSegment.mToValue.mGecko,
aUnderlyingValue,
- aEnd.mComposite);
+ aSegment.mToComposite);
// Iteration composition for accumulate
if (static_cast<dom::IterationCompositeOperation>
(aAnimation.iterationComposite()) ==
dom::IterationCompositeOperation::Accumulate &&
aCurrentIteration > 0) {
// FIXME: Bug 1293492: Add a utility function to calculate both of
// below StyleAnimationValues.
@@ -264,32 +260,51 @@ AnimationHelper::SampleAnimationForEachN
(computedTiming.mProgress.Value() - segment->startPortion()) /
(segment->endPortion() - segment->startPortion());
double portion =
ComputedTimingFunction::GetPortion(animData.mFunctions[segmentIndex],
positionInSegment,
computedTiming.mBeforeFlag);
- StyleAnimationValueCompositePair from {
- animData.mStartValues[segmentIndex].mGecko,
- static_cast<dom::CompositeOperation>(segment->startComposite())
- };
- StyleAnimationValueCompositePair to {
- animData.mEndValues[segmentIndex].mGecko,
- static_cast<dom::CompositeOperation>(segment->endComposite())
- };
+ AnimationPropertySegment animSegment;
+ animSegment.mFromKey = 0.0;
+ animSegment.mToKey = 1.0;
+ animSegment.mFromValue = animData.mStartValues[segmentIndex];
+ animSegment.mToValue = animData.mEndValues[segmentIndex];
+ animSegment.mFromComposite =
+ static_cast<dom::CompositeOperation>(segment->startComposite());
+ animSegment.mToComposite =
+ static_cast<dom::CompositeOperation>(segment->endComposite());
+
// interpolate the property
- aAnimationValue.mGecko =
- SampleValue(portion,
- animation,
- from, to,
- animData.mEndValues.LastElement().mGecko,
- computedTiming.mCurrentIteration,
- aAnimationValue.mGecko);
+ bool isServo = animSegment.mFromValue.mServo ||
+ animSegment.mToValue.mServo;
+ if (isServo) {
+ dom::IterationCompositeOperation iterCompositeOperation =
+ static_cast<dom::IterationCompositeOperation>(
+ animation.iterationComposite());
+
+ aAnimationValue.mServo =
+ Servo_ComposeAnimationSegment(
+ &animSegment,
+ aAnimationValue.mServo,
+ animData.mEndValues.LastElement().mServo,
+ iterCompositeOperation,
+ portion,
+ computedTiming.mCurrentIteration).Consume();
+ } else {
+ aAnimationValue.mGecko =
+ SampleValue(portion,
+ animation,
+ Move(animSegment),
+ animData.mEndValues.LastElement().mGecko,
+ computedTiming.mCurrentIteration,
+ aAnimationValue.mGecko);
+ }
aHasInEffectAnimations = true;
}
#ifdef DEBUG
// Sanity check that all of animation data are the same.
const AnimationData& lastData = aAnimations.LastElement().data();
for (const Animation& animation : aAnimations) {
const AnimationData& data = animation.data();
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -449,25 +449,41 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
SERVO_BINDING_FUNC(Servo_DeclarationBlock_RemovePropertyById, bool,
RawServoDeclarationBlockBorrowed declarations,
nsCSSPropertyID property)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_HasCSSWideKeyword, bool,
RawServoDeclarationBlockBorrowed declarations,
nsCSSPropertyID property)
// Compose animation value for a given property.
// |base_values| is nsRefPtrHashtable<nsUint32HashKey, RawServoAnimationValue>.
-// We use RawServoAnimationValueTableBorrowed to avoid exposing nsRefPtrHashtable in FFI.
+// We use RawServoAnimationValueTableBorrowed to avoid exposing
+// nsRefPtrHashtable in FFI.
SERVO_BINDING_FUNC(Servo_AnimationCompose, void,
RawServoAnimationValueMapBorrowedMut animation_values,
RawServoAnimationValueTableBorrowed base_values,
nsCSSPropertyID property,
RawGeckoAnimationPropertySegmentBorrowed animation_segment,
RawGeckoAnimationPropertySegmentBorrowed last_segment,
RawGeckoComputedTimingBorrowed computed_timing,
- mozilla::dom::IterationCompositeOperation iteration_composite)
+ mozilla::dom::IterationCompositeOperation iter_composite)
+// Calculate the result of interpolating given animation segment at the given
+// progress and current iteration.
+// This includes combining the segment endpoints with the underlying value
+// and/or last value depending the composite modes specified on the
+// segment endpoints and the supplied iteration composite mode.
+// The caller is responsible for providing an underlying value and
+// last value in all situations where there are needed.
+SERVO_BINDING_FUNC(Servo_ComposeAnimationSegment,
+ RawServoAnimationValueStrong,
+ RawGeckoAnimationPropertySegmentBorrowed animation_segment,
+ RawServoAnimationValueBorrowedOrNull underlying_value,
+ RawServoAnimationValueBorrowedOrNull last_value,
+ mozilla::dom::IterationCompositeOperation iter_composite,
+ double progress,
+ uint64_t current_iteration)
// presentation attributes
SERVO_BINDING_FUNC(Servo_DeclarationBlock_PropertyIsSet, bool,
RawServoDeclarationBlockBorrowed declarations,
nsCSSPropertyID property)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetIdentStringValue, void,
RawServoDeclarationBlockBorrowed declarations,
nsCSSPropertyID property,