Bug 783893 - Clean up async animation code r=roc

This commit is contained in:
David Zbarsky 2012-08-21 00:06:47 -04:00
Родитель 3154e1b535
Коммит 8ec03cd866
5 изменённых файлов: 53 добавлений и 68 удалений

Просмотреть файл

@ -379,6 +379,10 @@ CreateCSSValueList(const InfallibleTArray<TransformFunction>& aFunctions)
NS_ASSERTION(false, "All functions should be implemented?");
}
}
if (aFunctions.Length() == 0) {
result = new nsCSSValueList();
result->mValue.SetNoneValue();
}
return result.forget();
}
@ -388,9 +392,8 @@ Layer::SetAnimations(const AnimationArray& aAnimations)
mAnimations = aAnimations;
mAnimationData.Clear();
for (PRUint32 i = 0; i < mAnimations.Length(); i++) {
AnimData data;
InfallibleTArray<css::ComputedTimingFunction*>* functions =
&data.mFunctions;
AnimData* data = mAnimationData.AppendElement();
InfallibleTArray<css::ComputedTimingFunction*>& functions = data->mFunctions;
nsTArray<AnimationSegment> segments = mAnimations.ElementAt(i).segments();
for (PRUint32 j = 0; j < segments.Length(); j++) {
TimingFunction tf = segments.ElementAt(j).sampleFn();
@ -411,56 +414,34 @@ Layer::SetAnimations(const AnimationArray& aAnimations)
break;
}
}
functions->AppendElement(ctf);
functions.AppendElement(ctf);
}
// Precompute the nsStyleAnimation::Values that we need if this is a transform
// animation.
InfallibleTArray<nsStyleAnimation::Value>* startValues =
&data.mStartValues;
InfallibleTArray<nsStyleAnimation::Value>* endValues =
&data.mEndValues;
InfallibleTArray<nsStyleAnimation::Value>& startValues = data->mStartValues;
InfallibleTArray<nsStyleAnimation::Value>& endValues = data->mEndValues;
for (PRUint32 j = 0; j < mAnimations[i].segments().Length(); j++) {
const AnimationSegment& segment = mAnimations[i].segments()[j];
nsStyleAnimation::Value* startValue = startValues.AppendElement();
nsStyleAnimation::Value* endValue = endValues.AppendElement();
if (segment.endState().type() == Animatable::TArrayOfTransformFunction) {
const InfallibleTArray<TransformFunction>& startFunctions =
segment.startState().get_ArrayOfTransformFunction();
nsStyleAnimation::Value startValue;
nsCSSValueList* startList;
if (startFunctions.Length() > 0) {
startList = CreateCSSValueList(startFunctions);
} else {
startList = new nsCSSValueList();
startList->mValue.SetNoneValue();
}
startValue.SetAndAdoptCSSValueListValue(startList, nsStyleAnimation::eUnit_Transform);
startValues->AppendElement(startValue);
startValue->SetAndAdoptCSSValueListValue(CreateCSSValueList(startFunctions),
nsStyleAnimation::eUnit_Transform);
const InfallibleTArray<TransformFunction>& endFunctions =
segment.endState().get_ArrayOfTransformFunction();
nsStyleAnimation::Value endValue;
nsCSSValueList* endList;
if (endFunctions.Length() > 0) {
endList = CreateCSSValueList(endFunctions);
} else {
endList = new nsCSSValueList();
endList->mValue.SetNoneValue();
}
endValue.SetAndAdoptCSSValueListValue(endList, nsStyleAnimation::eUnit_Transform);
endValues->AppendElement(endValue);
endValue->SetAndAdoptCSSValueListValue(CreateCSSValueList(endFunctions),
nsStyleAnimation::eUnit_Transform);
} else {
NS_ASSERTION(segment.endState().type() == Animatable::Tfloat,
"Unknown Animatable type");
nsStyleAnimation::Value startValue;
startValue.SetFloatValue(segment.startState().get_float());
startValues->AppendElement(startValue);
nsStyleAnimation::Value endValue;
endValue.SetFloatValue(segment.endState().get_float());
endValues->AppendElement(endValue);
startValue->SetFloatValue(segment.startState().get_float());
endValue->SetFloatValue(segment.endState().get_float());
}
}
mAnimationData.AppendElement(data);
}
Mutated();

Просмотреть файл

@ -630,14 +630,14 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint)
animation.direction());
if (positionInIteration == -1) {
animations.RemoveElementAt(i);
animationData.RemoveElementAt(i);
continue;
animations.RemoveElementAt(i);
animationData.RemoveElementAt(i);
continue;
}
NS_ABORT_IF_FALSE(0.0 <= positionInIteration &&
positionInIteration <= 1.0,
"position should be in [0-1]");
positionInIteration <= 1.0,
"position should be in [0-1]");
int segmentIndex = 0;
AnimationSegment* segment = animation.segments().Elements();
@ -660,9 +660,12 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint)
ShadowLayer* shadow = aLayer->AsShadowLayer();
switch (animation.property()) {
case eCSSProperty_opacity:
{
shadow->SetShadowOpacity(interpolatedValue.get_float());
break;
case eCSSProperty_transform: {
}
case eCSSProperty_transform:
{
gfx3DMatrix matrix = interpolatedValue.get_ArrayOfTransformFunction()[0].get_TransformMatrix().value();
shadow->SetShadowTransform(matrix);
break;

Просмотреть файл

@ -286,17 +286,9 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
? ea->mIterationCount : -1;
int direction = ea->mDirection;
// If this is a visibility animation, we should not actually add it.
// This will be fixed in bug 783893
Animation* animation = nullptr;
for (PRUint32 propIdx = 0; propIdx < ea->mProperties.Length(); propIdx++) {
if (aProperty == ea->mProperties[propIdx].mProperty) {
animation = aLayer->AddAnimation(startTime, duration,
iterations, direction,
aProperty, aData);
break;
}
}
Animation* animation = aLayer->AddAnimation(startTime, duration,
iterations, direction,
aProperty, aData);
for (PRUint32 propIdx = 0; propIdx < ea->mProperties.Length(); propIdx++) {
AnimationProperty* property = &ea->mProperties[propIdx];
@ -308,9 +300,8 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
for (PRUint32 segIdx = 0; segIdx < property->mSegments.Length(); segIdx++) {
AnimationPropertySegment* segment = &property->mSegments[segIdx];
AnimationSegment* animSegment;
AnimationSegment* animSegment = animation->segments().AppendElement();
if (aProperty == eCSSProperty_transform) {
animSegment = animation->segments().AppendElement();
animSegment->startState() = InfallibleTArray<TransformFunction>();
animSegment->endState() = InfallibleTArray<TransformFunction>();
@ -322,7 +313,6 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
AddTransformFunctions(list, styleContext, presContext, bounds, scale,
animSegment->endState().get_ArrayOfTransformFunction());
} else if (aProperty == eCSSProperty_opacity) {
animSegment = animation->segments().AppendElement();
animSegment->startState() = segment->mFromValue.GetFloatValue();
animSegment->endState() = segment->mToValue.GetFloatValue();
}
@ -357,7 +347,6 @@ AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayListBuilder* aBuilder
// animation.
if (!nsDisplayTransform::ShouldPrerenderTransformedContent(aBuilder, frame)) {
if (nsLayoutUtils::IsAnimationLoggingEnabled()) {
nsIContent* aContent = frame->GetContent();
printf_stderr("Performance warning: Async animation disabled because the frame for element '%s'",
nsAtomCString(aContent->Tag()).get());
nsIAtom* id = aContent->GetID();
@ -399,9 +388,10 @@ AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayListBuilder* aBuilder
if (et) {
for (PRUint32 tranIdx = 0; tranIdx < et->mPropertyTransitions.Length(); tranIdx++) {
ElementPropertyTransition* pt = &et->mPropertyTransitions[tranIdx];
if (!pt->CanPerformOnCompositor(et->mElement, currentTime)) {
continue;
}
if (pt->mProperty != aProperty ||
!pt->CanPerformOnCompositor(et->mElement, currentTime)) {
continue;
}
ElementAnimation anim;
anim.mIterationCount = 1;
@ -428,7 +418,8 @@ AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayListBuilder* aBuilder
if (ea) {
for (PRUint32 animIdx = 0; animIdx < ea->mAnimations.Length(); animIdx++) {
ElementAnimation* anim = &ea->mAnimations[animIdx];
if (!anim->CanPerformOnCompositor(ea->mElement, currentTime)) {
if (!(anim->HasAnimationOfProperty(aProperty) &&
anim->CanPerformOnCompositor(ea->mElement, currentTime))) {
continue;
}
AddAnimationsForProperty(frame, aProperty, anim,
@ -2387,7 +2378,6 @@ nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder,
container->SetOpacity(mFrame->GetStyleDisplay()->mOpacity);
AddAnimationsAndTransitionsToLayer(container, aBuilder,
this, eCSSProperty_opacity);
return container.forget();
}

Просмотреть файл

@ -287,17 +287,27 @@ ElementAnimation::CanPerformOnCompositor(mozilla::dom::Element* aElement,
(aTime - mStartTime) / mIterationDuration < mIterationCount;
}
bool
ElementAnimation::HasAnimationOfProperty(nsCSSProperty aProperty) const
{
for (PRUint32 propIdx = 0, propEnd = mProperties.Length();
propIdx != propEnd; ++propIdx) {
if (aProperty == mProperties[propIdx].mProperty) {
return true;
}
}
return false;
}
bool
ElementAnimations::HasAnimationOfProperty(nsCSSProperty aProperty) const
{
for (PRUint32 animIdx = mAnimations.Length(); animIdx-- != 0; ) {
const ElementAnimation &anim = mAnimations[animIdx];
for (PRUint32 propIdx = 0, propEnd = anim.mProperties.Length();
propIdx != propEnd; ++propIdx) {
const AnimationProperty &prop = anim.mProperties[propIdx];
if (aProperty == prop.mProperty) {
return true;
}
if (anim.HasAnimationOfProperty(aProperty)) {
return true;
}
}
return false;

Просмотреть файл

@ -89,6 +89,7 @@ struct ElementAnimation
return mPlayState == NS_STYLE_ANIMATION_PLAY_STATE_PAUSED;
}
bool HasAnimationOfProperty(nsCSSProperty aProperty) const;
bool CanPerformOnCompositor(mozilla::dom::Element* aElement,
mozilla::TimeStamp aTime) const;