Bug 1340005 - Part 3: Use AnimationValue on the compositor thread.
MozReview-Commit-ID: CtnDLsdcr9x
--- a/gfx/layers/AnimationHelper.cpp
+++ b/gfx/layers/AnimationHelper.cpp
@@ -190,21 +190,22 @@ SampleValue(double aPortion, const layer
StyleAnimationValue::Interpolate(aAnimation.property(),
startValue, endValue,
aPortion, interpolatedValue);
MOZ_ASSERT(uncomputeResult, "could not uncompute value");
return interpolatedValue;
}
bool
-AnimationHelper::SampleAnimationForEachNode(TimeStamp aTime,
- AnimationArray& aAnimations,
- InfallibleTArray<AnimData>& aAnimationData,
- StyleAnimationValue& aAnimationValue,
- bool& aHasInEffectAnimations)
+AnimationHelper::SampleAnimationForEachNode(
+ TimeStamp aTime,
+ AnimationArray& aAnimations,
+ InfallibleTArray<AnimData>& aAnimationData,
+ AnimationValue& aAnimationValue,
+ bool& aHasInEffectAnimations)
{
bool activeAnimations = false;
if (aAnimations.IsEmpty()) {
return activeAnimations;
}
// Process in order, since later aAnimations override earlier ones.
@@ -264,30 +265,31 @@ AnimationHelper::SampleAnimationForEachN
(segment->endPortion() - segment->startPortion());
double portion =
ComputedTimingFunction::GetPortion(animData.mFunctions[segmentIndex],
positionInSegment,
computedTiming.mBeforeFlag);
StyleAnimationValueCompositePair from {
- animData.mStartValues[segmentIndex],
+ animData.mStartValues[segmentIndex].mGecko,
static_cast<dom::CompositeOperation>(segment->startComposite())
};
StyleAnimationValueCompositePair to {
- animData.mEndValues[segmentIndex],
+ animData.mEndValues[segmentIndex].mGecko,
static_cast<dom::CompositeOperation>(segment->endComposite())
};
// interpolate the property
- aAnimationValue = SampleValue(portion,
- animation,
- from, to,
- animData.mEndValues.LastElement(),
- computedTiming.mCurrentIteration,
- aAnimationValue);
+ aAnimationValue.mGecko =
+ SampleValue(portion,
+ animation,
+ from, to,
+ 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();
@@ -488,17 +490,17 @@ ToAnimationValue(const Animatable& aAnim
}
return result;
}
void
AnimationHelper::SetAnimations(AnimationArray& aAnimations,
InfallibleTArray<AnimData>& aAnimData,
- StyleAnimationValue& aBaseAnimationStyle)
+ AnimationValue& aBaseAnimationStyle)
{
for (uint32_t i = 0; i < aAnimations.Length(); i++) {
Animation& animation = aAnimations[i];
// Adjust fill mode to fill forwards so that if the main thread is delayed
// in clearing this animation we don't introduce flicker by jumping back to
// the old underlying value
switch (static_cast<dom::FillMode>(animation.fillMode())) {
case dom::FillMode::None:
@@ -507,29 +509,29 @@ AnimationHelper::SetAnimations(Animation
case dom::FillMode::Backwards:
animation.fillMode() = static_cast<uint8_t>(dom::FillMode::Both);
break;
default:
break;
}
if (animation.baseStyle().type() != Animatable::Tnull_t) {
- aBaseAnimationStyle = ToAnimationValue(animation.baseStyle()).mGecko;
+ aBaseAnimationStyle = ToAnimationValue(animation.baseStyle());
}
AnimData* data = aAnimData.AppendElement();
InfallibleTArray<Maybe<ComputedTimingFunction>>& functions =
data->mFunctions;
- InfallibleTArray<StyleAnimationValue>& startValues = data->mStartValues;
- InfallibleTArray<StyleAnimationValue>& endValues = data->mEndValues;
+ InfallibleTArray<AnimationValue>& startValues = data->mStartValues;
+ InfallibleTArray<AnimationValue>& endValues = data->mEndValues;
const InfallibleTArray<AnimationSegment>& segments = animation.segments();
for (const AnimationSegment& segment : segments) {
- startValues.AppendElement(ToAnimationValue(segment.startState()).mGecko);
- endValues.AppendElement(ToAnimationValue(segment.endState()).mGecko);
+ startValues.AppendElement(ToAnimationValue(segment.startState()));
+ endValues.AppendElement(ToAnimationValue(segment.endState()));
TimingFunction tf = segment.sampleFn();
Maybe<ComputedTimingFunction> ctf =
AnimationUtils::TimingFunctionToComputedTimingFunction(tf);
functions.AppendElement(ctf);
}
}
}
@@ -557,17 +559,17 @@ AnimationHelper::SampleAnimations(Compos
return;
}
//Sample the animations in CompositorAnimationStorage
for (auto iter = aStorage->ConstAnimationsTableIter();
!iter.Done(); iter.Next()) {
bool hasInEffectAnimations = false;
AnimationArray* animations = iter.UserData();
- StyleAnimationValue animationValue;
+ AnimationValue animationValue;
InfallibleTArray<AnimData> animationData;
AnimationHelper::SetAnimations(*animations,
animationData,
animationValue);
AnimationHelper::SampleAnimationForEachNode(aTime,
*animations,
animationData,
animationValue,
@@ -576,22 +578,22 @@ AnimationHelper::SampleAnimations(Compos
if (!hasInEffectAnimations) {
continue;
}
// Store the AnimatedValue
Animation& animation = animations->LastElement();
switch (animation.property()) {
case eCSSProperty_opacity: {
- aStorage->SetAnimatedValue(iter.Key(),
- animationValue.GetFloatValue());
+ aStorage->SetAnimatedValue(iter.Key(), animationValue.GetOpacity());
break;
}
case eCSSProperty_transform: {
- nsCSSValueSharedList* list = animationValue.GetCSSValueSharedListValue();
+ // TODO: Convert AnimationValue into css shared list.
+ nsCSSValueSharedList* list = animationValue.mGecko.GetCSSValueSharedListValue();
const TransformData& transformData = animation.data().get_TransformData();
nsPoint origin = transformData.origin();
// we expect all our transform data to arrive in device pixels
gfx::Point3D transformOrigin = transformData.transformOrigin();
nsDisplayTransform::FrameTransformProperties props(list,
transformOrigin);
gfx::Matrix4x4 transform =
--- a/gfx/layers/AnimationHelper.h
+++ b/gfx/layers/AnimationHelper.h
@@ -8,25 +8,25 @@
#define mozilla_layers_AnimationHelper_h
#include "mozilla/ComputedTimingFunction.h" // for ComputedTimingFunction
#include "mozilla/layers/LayersMessages.h" // for TransformData, etc
#include "mozilla/TimeStamp.h" // for TimeStamp
namespace mozilla {
-class StyleAnimationValue;
+struct AnimationValue;
namespace layers {
class Animation;
typedef InfallibleTArray<layers::Animation> AnimationArray;
struct AnimData {
- InfallibleTArray<mozilla::StyleAnimationValue> mStartValues;
- InfallibleTArray<mozilla::StyleAnimationValue> mEndValues;
+ InfallibleTArray<mozilla::AnimationValue> mStartValues;
+ InfallibleTArray<mozilla::AnimationValue> mEndValues;
InfallibleTArray<Maybe<mozilla::ComputedTimingFunction>> mFunctions;
};
struct AnimationTransform {
/*
* This transform is calculated from sampleanimation in device pixel
* and used by compositor.
*/
@@ -198,26 +198,26 @@ public:
* its animation data.
* Returns true if there exists compositor animation, and stores corresponding
* animated value in |aAnimationValue|.
*/
static bool
SampleAnimationForEachNode(TimeStamp aTime,
AnimationArray& aAnimations,
InfallibleTArray<AnimData>& aAnimationData,
- StyleAnimationValue& aAnimationValue,
+ AnimationValue& aAnimationValue,
bool& aHasInEffectAnimations);
/**
* Populates AnimData stuctures into |aAnimData| and |aBaseAnimationStyle|
* based on |aAnimations|.
*/
static void
SetAnimations(AnimationArray& aAnimations,
InfallibleTArray<AnimData>& aAnimData,
- StyleAnimationValue& aBaseAnimationStyle);
+ AnimationValue& aBaseAnimationStyle);
/**
* Get a unique id to represent the compositor animation between child
* and parent side. This id will be used as a key to store animation
* data in the CompositorAnimationStorage per compositor.
* Each layer on the content side calls this when it gets new animation
* data.
*/
--- a/gfx/layers/AnimationInfo.h
+++ b/gfx/layers/AnimationInfo.h
@@ -45,32 +45,32 @@ public:
// ClearAnimations clears animations on this layer.
void ClearAnimations();
void ClearAnimationsForNextTransaction();
void SetCompositorAnimations(const CompositorAnimations& aCompositorAnimations);
bool StartPendingAnimations(const TimeStamp& aReadyTime);
void TransferMutatedFlagToLayer(Layer* aLayer);
uint64_t GetCompositorAnimationsId() { return mCompositorAnimationsId; }
- StyleAnimationValue GetBaseAnimationStyle() const { return mBaseAnimationStyle; }
+ AnimationValue GetBaseAnimationStyle() const { return mBaseAnimationStyle; }
InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; }
AnimationArray& GetAnimations() { return mAnimations; }
bool ApplyPendingUpdatesForThisTransaction();
bool HasOpacityAnimation() const;
bool HasTransformAnimation() const;
protected:
LayerManager* mManager;
AnimationArray mAnimations;
uint64_t mCompositorAnimationsId;
nsAutoPtr<AnimationArray> mPendingAnimations;
InfallibleTArray<AnimData> mAnimationData;
// If this layer is used for OMTA, then this counter is used to ensure we
// stay in sync with the animation manager
uint64_t mAnimationGeneration;
- StyleAnimationValue mBaseAnimationStyle;
+ AnimationValue mBaseAnimationStyle;
bool mMutated;
};
} // namespace layers
} // namespace mozilla
#endif // GFX_ANIMATIONINFO_H
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1431,17 +1431,17 @@ public:
uint64_t GetCompositorAnimationsId() { return mAnimationInfo.GetCompositorAnimationsId(); }
InfallibleTArray<AnimData>& GetAnimationData();
uint64_t GetAnimationGeneration() { return mAnimationInfo.GetAnimationGeneration(); }
bool HasTransformAnimation() const;
bool HasOpacityAnimation() const;
- StyleAnimationValue GetBaseAnimationStyle() const
+ AnimationValue GetBaseAnimationStyle() const
{
return mAnimationInfo.GetBaseAnimationStyle();
}
/**
* Returns the local transform for this layer: either mTransform or,
* for shadow layers, GetShadowBaseTransform(), in either case with the
* pre- and post-scales applied.
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -574,40 +574,39 @@ AsyncCompositionManager::AlignFixedAndSt
}
}
static void
ApplyAnimatedValue(Layer* aLayer,
CompositorAnimationStorage* aStorage,
nsCSSPropertyID aProperty,
const AnimationData& aAnimationData,
- const StyleAnimationValue& aValue)
+ const AnimationValue& aValue)
{
if (aValue.IsNull()) {
- // Return gracefully if we have no valid StyleAnimationValue.
+ // Return gracefully if we have no valid AnimationValue.
return;
}
HostLayer* layerCompositor = aLayer->AsHostLayer();
switch (aProperty) {
case eCSSProperty_opacity: {
- MOZ_ASSERT(aValue.GetUnit() == StyleAnimationValue::eUnit_Float,
- "Interpolated value for opacity should be float");
- layerCompositor->SetShadowOpacity(aValue.GetFloatValue());
+ layerCompositor->SetShadowOpacity(aValue.GetOpacity());
layerCompositor->SetShadowOpacitySetByAnimation(true);
aStorage->SetAnimatedValue(aLayer->GetCompositorAnimationsId(),
- aValue.GetFloatValue());
+ aValue.GetOpacity());
break;
}
case eCSSProperty_transform: {
- MOZ_ASSERT(aValue.GetUnit() == StyleAnimationValue::eUnit_Transform,
+ MOZ_ASSERT(aValue.mGecko.GetUnit() == StyleAnimationValue::eUnit_Transform,
"The unit of interpolated value for transform should be "
"transform");
- nsCSSValueSharedList* list = aValue.GetCSSValueSharedListValue();
+ // TODO: Convert AnimationValue into css shared list.
+ nsCSSValueSharedList* list = aValue.mGecko.GetCSSValueSharedListValue();
const TransformData& transformData = aAnimationData.get_TransformData();
nsPoint origin = transformData.origin();
// we expect all our transform data to arrive in device pixels
Point3D transformOrigin = transformData.transformOrigin();
nsDisplayTransform::FrameTransformProperties props(list,
transformOrigin);
@@ -664,17 +663,17 @@ SampleAnimations(Layer* aLayer,
aLayer,
[&] (Layer* layer)
{
if (!ancestorRefLayer) {
ancestorRefLayer = layer->AsRefLayer();
}
bool hasInEffectAnimations = false;
- StyleAnimationValue animationValue = layer->GetBaseAnimationStyle();
+ AnimationValue animationValue = layer->GetBaseAnimationStyle();
if (AnimationHelper::SampleAnimationForEachNode(aTime,
layer->GetAnimations(),
layer->GetAnimationData(),
animationValue,
hasInEffectAnimations)) {
animProcess |= (ancestorRefLayer ? AnimationProcessTypes::eContent
: AnimationProcessTypes::eChrome);
}
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -5349,16 +5349,18 @@ AnimationValue::operator!=(const Animati
{
return !operator==(aOther);
}
float
AnimationValue::GetOpacity() const
{
MOZ_ASSERT(!mServo != mGecko.IsNull());
+ MOZ_ASSERT(mServo || mGecko.GetUnit() == StyleAnimationValue::eUnit_Float,
+ "Should have the correct unit on Gecko backend");
return mServo ? Servo_AnimationValue_GetOpacity(mServo)
: mGecko.GetFloatValue();
}
gfxSize
AnimationValue::GetScaleValue(const nsIFrame* aFrame) const
{
MOZ_ASSERT(!mServo != mGecko.IsNull());