Bug 1004383 part 1 - Put StyleAnimation on the heap; r=dbaron

This patch takes StyleAnimation and makes it ref-counted heap object. This
should allow us to store StyleAnimation and its subclasses (transitions only
currently) in a consistent fashion (an array of base-class pointers).
Furthermore, this will be helpful if we want these things to be pointed to
from Javascript objects that may, for example, preserve their lifetime beyond
that of the element that currently owns them.

This patch also introduces a typedef for an array of refptrs to StyleAnimation
objects (and similarly for the subclass ElementPropertyTransition) to simplify
the code somewhat.
This commit is contained in:
Brian Birtles 2014-05-15 08:38:37 +09:00
parent 7b1d2c5343
commit e3859b3244
7 changed files with 133 additions and 122 deletions

View File

@ -377,7 +377,7 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
mozilla::TimeStamp currentTime =
aFrame->PresContext()->RefreshDriver()->MostRecentRefresh();
for (uint32_t animIdx = 0; animIdx < aAnimations.Length(); animIdx++) {
mozilla::StyleAnimation* anim = &aAnimations[animIdx];
mozilla::StyleAnimation* anim = aAnimations[animIdx];
if (!(anim->HasAnimationOfProperty(aProperty) &&
anim->IsRunningAt(currentTime))) {
continue;

View File

@ -391,9 +391,9 @@ nsLayoutUtils::ComputeSuitableScaleForAnimation(nsIContent* aContent)
(aContent, nsGkAtoms::animationsProperty, eCSSProperty_transform);
if (animations) {
for (uint32_t animIdx = animations->mAnimations.Length(); animIdx-- != 0; ) {
mozilla::StyleAnimation& anim = animations->mAnimations[animIdx];
for (uint32_t propIdx = anim.mProperties.Length(); propIdx-- != 0; ) {
AnimationProperty& prop = anim.mProperties[propIdx];
mozilla::StyleAnimation* anim = animations->mAnimations[animIdx];
for (uint32_t propIdx = anim->mProperties.Length(); propIdx-- != 0; ) {
AnimationProperty& prop = anim->mProperties[propIdx];
if (prop.mProperty == eCSSProperty_transform) {
for (uint32_t segIdx = prop.mSegments.Length(); segIdx-- != 0; ) {
AnimationPropertySegment& segment = prop.mSegments[segIdx];
@ -420,17 +420,17 @@ nsLayoutUtils::ComputeSuitableScaleForAnimation(nsIContent* aContent)
if (transitions) {
for (uint32_t i = 0, i_end = transitions->mPropertyTransitions.Length();
i < i_end; ++i){
ElementPropertyTransition &pt = transitions->mPropertyTransitions[i];
if (pt.IsRemovedSentinel()) {
ElementPropertyTransition* pt = transitions->mPropertyTransitions[i];
if (pt->IsRemovedSentinel()) {
continue;
}
MOZ_ASSERT(pt.mProperties.Length() == 1,
MOZ_ASSERT(pt->mProperties.Length() == 1,
"Should have one animation property for a transition");
MOZ_ASSERT(pt.mProperties[0].mSegments.Length() == 1,
MOZ_ASSERT(pt->mProperties[0].mSegments.Length() == 1,
"Animation property should have one segment for a transition");
const AnimationPropertySegment& segment = pt.mProperties[0].mSegments[0];
const AnimationPropertySegment& segment = pt->mProperties[0].mSegments[0];
if (pt.mProperties[0].mProperty == eCSSProperty_transform) {
if (pt->mProperties[0].mProperty == eCSSProperty_transform) {
gfxSize start = GetScaleForValue(segment.mFromValue,
aContent->GetPrimaryFrame());
maxScale.width = std::max<float>(maxScale.width, start.width);

View File

@ -278,8 +278,12 @@ struct StyleAnimation
uint32_t mLastNotification;
InfallibleTArray<AnimationProperty> mProperties;
NS_INLINE_DECL_REFCOUNTING(StyleAnimation)
};
typedef InfallibleTArray<nsRefPtr<StyleAnimation> > StyleAnimationPtrArray;
namespace css {
struct CommonElementAnimationData : public PRCList

View File

@ -179,22 +179,22 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
// the style recalculation if we find any.
if (aIsThrottled) {
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
StyleAnimation &anim = mAnimations[animIdx];
StyleAnimation* anim = mAnimations[animIdx];
if (anim.mProperties.Length() == 0 ||
anim.mIterationDuration.ToMilliseconds() <= 0.0) {
if (anim->mProperties.Length() == 0 ||
anim->mIterationDuration.ToMilliseconds() <= 0.0) {
continue;
}
uint32_t oldLastNotification = anim.mLastNotification;
uint32_t oldLastNotification = anim->mLastNotification;
// We need to call GetPositionInIteration here to populate
// aEventsToDispatch.
// The ElapsedDurationAt() call here handles pausing. But:
// FIXME: avoid recalculating every time when paused.
GetPositionInIteration(anim.ElapsedDurationAt(aRefreshTime),
anim.mIterationDuration, anim.mIterationCount,
anim.mDirection, &anim, this, &aEventsToDispatch);
GetPositionInIteration(anim->ElapsedDurationAt(aRefreshTime),
anim->mIterationDuration, anim->mIterationCount,
anim->mDirection, anim, this, &aEventsToDispatch);
// GetPositionInIteration just adjusted mLastNotification; check
// its new value against the value before we called
@ -203,9 +203,9 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
// indicator that the animation has finished, it should be reserved for
// events. If we use it differently in the future this use might need
// changing.
if (!anim.mIsRunningOnCompositor ||
(anim.mLastNotification != oldLastNotification &&
anim.mLastNotification == StyleAnimation::LAST_NOTIFICATION_END)) {
if (!anim->mIsRunningOnCompositor ||
(anim->mLastNotification != oldLastNotification &&
anim->mLastNotification == StyleAnimation::LAST_NOTIFICATION_END)) {
aIsThrottled = false;
break;
}
@ -230,10 +230,10 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
nsCSSPropertySet properties;
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
StyleAnimation &anim = mAnimations[animIdx];
StyleAnimation* anim = mAnimations[animIdx];
if (anim.mProperties.Length() == 0 ||
anim.mIterationDuration.ToMilliseconds() <= 0.0) {
if (anim->mProperties.Length() == 0 ||
anim->mIterationDuration.ToMilliseconds() <= 0.0) {
// No animation data.
continue;
}
@ -241,9 +241,9 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
// The ElapsedDurationAt() call here handles pausing. But:
// FIXME: avoid recalculating every time when paused.
double positionInIteration =
GetPositionInIteration(anim.ElapsedDurationAt(aRefreshTime),
anim.mIterationDuration, anim.mIterationCount,
anim.mDirection, &anim, this,
GetPositionInIteration(anim->ElapsedDurationAt(aRefreshTime),
anim->mIterationDuration, anim->mIterationCount,
anim->mDirection, anim, this,
&aEventsToDispatch);
// The position is -1 when we don't have fill data for the current time,
@ -255,10 +255,10 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
positionInIteration <= 1.0,
"position should be in [0-1]");
for (uint32_t propIdx = 0, propEnd = anim.mProperties.Length();
for (uint32_t propIdx = 0, propEnd = anim->mProperties.Length();
propIdx != propEnd; ++propIdx)
{
const AnimationProperty &prop = anim.mProperties[propIdx];
const AnimationProperty &prop = anim->mProperties[propIdx];
NS_ABORT_IF_FALSE(prop.mSegments[0].mFromKey == 0.0,
"incorrect first from key");
@ -330,8 +330,8 @@ bool
ElementAnimations::HasAnimationOfProperty(nsCSSProperty aProperty) const
{
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
const StyleAnimation &anim = mAnimations[animIdx];
if (anim.HasAnimationOfProperty(aProperty)) {
const StyleAnimation* anim = mAnimations[animIdx];
if (anim->HasAnimationOfProperty(aProperty)) {
return true;
}
}
@ -360,11 +360,11 @@ ElementAnimations::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const
TimeStamp now = frame->PresContext()->RefreshDriver()->MostRecentRefresh();
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
const StyleAnimation& anim = mAnimations[animIdx];
for (uint32_t propIdx = 0, propEnd = anim.mProperties.Length();
const StyleAnimation* anim = mAnimations[animIdx];
for (uint32_t propIdx = 0, propEnd = anim->mProperties.Length();
propIdx != propEnd; ++propIdx) {
if (IsGeometricProperty(anim.mProperties[propIdx].mProperty) &&
anim.IsRunningAt(now)) {
if (IsGeometricProperty(anim->mProperties[propIdx].mProperty) &&
anim->IsRunningAt(now)) {
aFlags = CanAnimateFlags(aFlags | CanAnimate_HasGeometricProperty);
break;
}
@ -374,14 +374,14 @@ ElementAnimations::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const
bool hasOpacity = false;
bool hasTransform = false;
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
const StyleAnimation& anim = mAnimations[animIdx];
if (!anim.IsRunningAt(now)) {
const StyleAnimation* anim = mAnimations[animIdx];
if (!anim->IsRunningAt(now)) {
continue;
}
for (uint32_t propIdx = 0, propEnd = anim.mProperties.Length();
for (uint32_t propIdx = 0, propEnd = anim->mProperties.Length();
propIdx != propEnd; ++propIdx) {
const AnimationProperty& prop = anim.mProperties[propIdx];
const AnimationProperty& prop = anim->mProperties[propIdx];
if (!CanAnimatePropertyOnCompositor(mElement,
prop.mProperty,
aFlags) ||
@ -547,7 +547,7 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
}
// build the animations list
InfallibleTArray<StyleAnimation> newAnimations;
StyleAnimationPtrArray newAnimations;
BuildAnimations(aStyleContext, newAnimations);
if (newAnimations.IsEmpty()) {
@ -577,7 +577,7 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
if (!ea->mAnimations.IsEmpty()) {
for (uint32_t newIdx = 0, newEnd = newAnimations.Length();
newIdx != newEnd; ++newIdx) {
StyleAnimation *newAnim = &newAnimations[newIdx];
nsRefPtr<StyleAnimation> newAnim = newAnimations[newIdx];
// Find the matching animation with this name in the old list
// of animations. Because of this code, they must all have
@ -587,9 +587,9 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
// different pause states, they, well, get what they deserve.
// We'll use the last one since it's more likely to be the one
// doing something.
const StyleAnimation *oldAnim = nullptr;
const StyleAnimation* oldAnim = nullptr;
for (uint32_t oldIdx = ea->mAnimations.Length(); oldIdx-- != 0; ) {
const StyleAnimation *a = &ea->mAnimations[oldIdx];
const StyleAnimation* a = ea->mAnimations[oldIdx];
if (a->mName == newAnim->mName) {
oldAnim = a;
break;
@ -717,8 +717,7 @@ ResolvedStyleCache::Get(nsPresContext *aPresContext,
void
nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
InfallibleTArray<StyleAnimation>&
aAnimations)
StyleAnimationPtrArray& aAnimations)
{
NS_ABORT_IF_FALSE(aAnimations.IsEmpty(), "expect empty array");
@ -728,27 +727,30 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh();
for (uint32_t animIdx = 0, animEnd = disp->mAnimationNameCount;
animIdx != animEnd; ++animIdx) {
const nsAnimation& aSrc = disp->mAnimations[animIdx];
StyleAnimation& aDest = *aAnimations.AppendElement();
const nsAnimation& src = disp->mAnimations[animIdx];
nsRefPtr<StyleAnimation> dest =
*aAnimations.AppendElement(new StyleAnimation());
aDest.mName = aSrc.GetName();
aDest.mIterationCount = aSrc.GetIterationCount();
aDest.mDirection = aSrc.GetDirection();
aDest.mFillMode = aSrc.GetFillMode();
aDest.mPlayState = aSrc.GetPlayState();
dest->mName = src.GetName();
dest->mIterationCount = src.GetIterationCount();
dest->mDirection = src.GetDirection();
dest->mFillMode = src.GetFillMode();
dest->mPlayState = src.GetPlayState();
aDest.mDelay = TimeDuration::FromMilliseconds(aSrc.GetDelay());
aDest.mStartTime = now;
if (aDest.IsPaused()) {
aDest.mPauseStart = now;
dest->mDelay = TimeDuration::FromMilliseconds(src.GetDelay());
dest->mStartTime = now;
if (dest->IsPaused()) {
dest->mPauseStart = now;
} else {
aDest.mPauseStart = TimeStamp();
dest->mPauseStart = TimeStamp();
}
aDest.mIterationDuration = TimeDuration::FromMilliseconds(aSrc.GetDuration());
dest->mIterationDuration =
TimeDuration::FromMilliseconds(src.GetDuration());
nsCSSKeyframesRule* rule =
mPresContext->StyleSet()->KeyframesRuleForName(mPresContext, aDest.mName);
mPresContext->StyleSet()->KeyframesRuleForName(mPresContext,
dest->mName);
if (!rule) {
// no segments
continue;
@ -841,7 +843,7 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
lastKey = kf.mKey;
}
AnimationProperty &propData = *aDest.mProperties.AppendElement();
AnimationProperty &propData = *dest->mProperties.AppendElement();
propData.mProperty = prop;
KeyframeData *fromKeyframe = nullptr;
@ -857,7 +859,7 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
if (fromKeyframe) {
interpolated = interpolated &&
BuildSegment(propData.mSegments, prop, aSrc,
BuildSegment(propData.mSegments, prop, src,
fromKeyframe->mKey, fromContext,
fromKeyframe->mRule->Declaration(),
toKeyframe.mKey, toContext);
@ -866,7 +868,7 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
// There's no data for this property at 0%, so use the
// cascaded value above us.
interpolated = interpolated &&
BuildSegment(propData.mSegments, prop, aSrc,
BuildSegment(propData.mSegments, prop, src,
0.0f, aStyleContext, nullptr,
toKeyframe.mKey, toContext);
}
@ -880,7 +882,7 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
// There's no data for this property at 100%, so use the
// cascaded value above us.
interpolated = interpolated &&
BuildSegment(propData.mSegments, prop, aSrc,
BuildSegment(propData.mSegments, prop, src,
fromKeyframe->mKey, fromContext,
fromKeyframe->mRule->Declaration(),
1.0f, aStyleContext);
@ -893,9 +895,11 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
// values (which?) or skip segments, so best to skip the whole
// thing for now.)
if (!interpolated) {
aDest.mProperties.RemoveElementAt(aDest.mProperties.Length() - 1);
dest->mProperties.RemoveElementAt(dest->mProperties.Length() - 1);
}
}
aAnimations.AppendElement(dest);
}
}

View File

@ -127,7 +127,7 @@ struct ElementAnimations MOZ_FINAL
// either completed or paused). May be invalidated by a style change.
bool mNeedsRefreshes;
InfallibleTArray<mozilla::StyleAnimation> mAnimations;
mozilla::StyleAnimationPtrArray mAnimations;
};
class nsAnimationManager MOZ_FINAL
@ -236,7 +236,7 @@ protected:
private:
void BuildAnimations(nsStyleContext* aStyleContext,
InfallibleTArray<mozilla::StyleAnimation>& aAnimations);
mozilla::StyleAnimationPtrArray& aAnimations);
bool BuildSegment(InfallibleTArray<mozilla::AnimationPropertySegment>&
aSegments,
nsCSSProperty aProperty, const nsAnimation& aAnimation,

View File

@ -105,18 +105,18 @@ ElementTransitions::EnsureStyleRuleFor(TimeStamp aRefreshTime)
for (uint32_t i = 0, i_end = mPropertyTransitions.Length(); i < i_end; ++i)
{
ElementPropertyTransition &pt = mPropertyTransitions[i];
if (pt.IsRemovedSentinel()) {
ElementPropertyTransition* pt = mPropertyTransitions[i];
if (pt->IsRemovedSentinel()) {
continue;
}
MOZ_ASSERT(pt.mProperties.Length() == 1,
MOZ_ASSERT(pt->mProperties.Length() == 1,
"Should have one animation property for a transition");
const AnimationProperty &prop = pt.mProperties[0];
const AnimationProperty &prop = pt->mProperties[0];
nsStyleAnimation::Value *val = mStyleRule->AddEmptyValue(prop.mProperty);
double valuePortion = pt.ValuePortionFor(aRefreshTime);
double valuePortion = pt->ValuePortionFor(aRefreshTime);
MOZ_ASSERT(prop.mSegments.Length() == 1,
"Animation property should have one segment for a transition");
@ -136,8 +136,8 @@ bool
ElementTransitions::HasAnimationOfProperty(nsCSSProperty aProperty) const
{
for (uint32_t tranIdx = mPropertyTransitions.Length(); tranIdx-- != 0; ) {
const ElementPropertyTransition& pt = mPropertyTransitions[tranIdx];
if (pt.HasAnimationOfProperty(aProperty) && !pt.IsRemovedSentinel()) {
const ElementPropertyTransition* pt = mPropertyTransitions[tranIdx];
if (pt->HasAnimationOfProperty(aProperty) && !pt->IsRemovedSentinel()) {
return true;
}
}
@ -164,11 +164,11 @@ ElementTransitions::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const
TimeStamp now = frame->PresContext()->RefreshDriver()->MostRecentRefresh();
for (uint32_t i = 0, i_end = mPropertyTransitions.Length(); i < i_end; ++i) {
const ElementPropertyTransition& pt = mPropertyTransitions[i];
MOZ_ASSERT(pt.mProperties.Length() == 1,
const ElementPropertyTransition* pt = mPropertyTransitions[i];
MOZ_ASSERT(pt->mProperties.Length() == 1,
"Should have one animation property for a transition");
if (css::IsGeometricProperty(pt.mProperties[0].mProperty) &&
pt.IsRunningAt(now)) {
if (css::IsGeometricProperty(pt->mProperties[0].mProperty) &&
pt->IsRunningAt(now)) {
aFlags = CanAnimateFlags(aFlags | CanAnimate_HasGeometricProperty);
break;
}
@ -178,16 +178,16 @@ ElementTransitions::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const
bool hasTransform = false;
bool existsProperty = false;
for (uint32_t i = 0, i_end = mPropertyTransitions.Length(); i < i_end; ++i) {
const ElementPropertyTransition& pt = mPropertyTransitions[i];
if (!pt.IsRunningAt(now)) {
const ElementPropertyTransition* pt = mPropertyTransitions[i];
if (!pt->IsRunningAt(now)) {
continue;
}
existsProperty = true;
MOZ_ASSERT(pt.mProperties.Length() == 1,
MOZ_ASSERT(pt->mProperties.Length() == 1,
"Should have one animation property for a transition");
const AnimationProperty& prop = pt.mProperties[0];
const AnimationProperty& prop = pt->mProperties[0];
if (!css::CommonElementAnimationData::CanAnimatePropertyOnCompositor(
mElement, prop.mProperty, aFlags) ||
@ -449,18 +449,18 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
}
}
nsTArray<ElementPropertyTransition> &pts = et->mPropertyTransitions;
ElementTransitions::TransitionPtrArray &pts = et->mPropertyTransitions;
uint32_t i = pts.Length();
NS_ABORT_IF_FALSE(i != 0, "empty transitions list?");
nsStyleAnimation::Value currentValue;
do {
--i;
ElementPropertyTransition &pt = pts[i];
MOZ_ASSERT(pt.mProperties.Length() == 1,
ElementPropertyTransition* pt = pts[i];
MOZ_ASSERT(pt->mProperties.Length() == 1,
"Should have one animation property for a transition");
MOZ_ASSERT(pt.mProperties[0].mSegments.Length() == 1,
MOZ_ASSERT(pt->mProperties[0].mSegments.Length() == 1,
"Animation property should have one segment for a transition");
const AnimationProperty& prop = pt.mProperties[0];
const AnimationProperty& prop = pt->mProperties[0];
const AnimationPropertySegment& segment = prop.mSegments[0];
// properties no longer in 'transition-property'
if ((checkProperties &&
@ -506,14 +506,14 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
nsRefPtr<css::AnimValuesStyleRule> coverRule = new css::AnimValuesStyleRule;
nsTArray<ElementPropertyTransition> &pts = et->mPropertyTransitions;
ElementTransitions::TransitionPtrArray &pts = et->mPropertyTransitions;
for (uint32_t i = 0, i_end = pts.Length(); i < i_end; ++i) {
ElementPropertyTransition &pt = pts[i];
MOZ_ASSERT(pt.mProperties.Length() == 1,
ElementPropertyTransition* pt = pts[i];
MOZ_ASSERT(pt->mProperties.Length() == 1,
"Should have one animation property for a transition");
MOZ_ASSERT(pt.mProperties[0].mSegments.Length() == 1,
MOZ_ASSERT(pt->mProperties[0].mSegments.Length() == 1,
"Animation property should have one segment for a transition");
AnimationProperty& prop = pt.mProperties[0];
AnimationProperty& prop = pt->mProperties[0];
AnimationPropertySegment& segment = prop.mSegments[0];
if (whichStarted.HasProperty(prop.mProperty)) {
coverRule->AddValue(prop.mProperty, segment.mFromValue);
@ -553,7 +553,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
return;
}
ElementPropertyTransition pt;
nsRefPtr<ElementPropertyTransition> pt = new ElementPropertyTransition();
nsStyleAnimation::Value startValue, endValue, dummyValue;
bool haveValues =
@ -577,15 +577,15 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
size_t currentIndex = nsTArray<ElementPropertyTransition>::NoIndex;
const ElementPropertyTransition *oldPT = nullptr;
if (aElementTransitions) {
nsTArray<ElementPropertyTransition> &pts =
ElementTransitions::TransitionPtrArray &pts =
aElementTransitions->mPropertyTransitions;
for (size_t i = 0, i_end = pts.Length(); i < i_end; ++i) {
MOZ_ASSERT(pts[i].mProperties.Length() == 1,
MOZ_ASSERT(pts[i]->mProperties.Length() == 1,
"Should have one animation property for a transition");
if (pts[i].mProperties[0].mProperty == aProperty) {
if (pts[i]->mProperties[0].mProperty == aProperty) {
haveCurrentTransition = true;
currentIndex = i;
oldPT = &aElementTransitions->mPropertyTransitions[currentIndex];
oldPT = aElementTransitions->mPropertyTransitions[currentIndex];
break;
}
}
@ -618,7 +618,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
// in-progress value (which is particularly easy to cause when we're
// currently in the 'transition-delay'). It also might happen because we
// just got a style change to a value that can't be interpolated.
nsTArray<ElementPropertyTransition> &pts =
ElementTransitions::TransitionPtrArray &pts =
aElementTransitions->mPropertyTransitions;
pts.RemoveElementAt(currentIndex);
aElementTransitions->UpdateAnimationGeneration(mPresContext);
@ -643,8 +643,8 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
// The spec says a negative duration is treated as zero.
duration = 0.0;
}
pt.mStartForReversingTest = startValue;
pt.mReversePortion = 1.0;
pt->mStartForReversingTest = startValue;
pt->mReversePortion = 1.0;
// If the new transition reverses an existing one, we'll need to
// handle the timing differently.
@ -681,11 +681,11 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
duration *= valuePortion;
pt.mStartForReversingTest = oldPT->mProperties[0].mSegments[0].mToValue;
pt.mReversePortion = valuePortion;
pt->mStartForReversingTest = oldPT->mProperties[0].mSegments[0].mToValue;
pt->mReversePortion = valuePortion;
}
AnimationProperty& prop = *pt.mProperties.AppendElement();
AnimationProperty& prop = *pt->mProperties.AppendElement();
prop.mProperty = aProperty;
AnimationPropertySegment& segment = *prop.mSegments.AppendElement();
@ -695,14 +695,14 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
segment.mToKey = 1;
segment.mTimingFunction.Init(tf);
pt.mStartTime = mostRecentRefresh;
pt.mDelay = TimeDuration::FromMilliseconds(delay);
pt.mIterationDuration = TimeDuration::FromMilliseconds(duration);
pt.mIterationCount = 1;
pt.mDirection = NS_STYLE_ANIMATION_DIRECTION_NORMAL;
pt.mFillMode = NS_STYLE_ANIMATION_FILL_MODE_BACKWARDS;
pt.mPlayState = NS_STYLE_ANIMATION_PLAY_STATE_RUNNING;
pt.mPauseStart = TimeStamp();
pt->mStartTime = mostRecentRefresh;
pt->mDelay = TimeDuration::FromMilliseconds(delay);
pt->mIterationDuration = TimeDuration::FromMilliseconds(duration);
pt->mIterationCount = 1;
pt->mDirection = NS_STYLE_ANIMATION_DIRECTION_NORMAL;
pt->mFillMode = NS_STYLE_ANIMATION_FILL_MODE_BACKWARDS;
pt->mPlayState = NS_STYLE_ANIMATION_PLAY_STATE_RUNNING;
pt->mPauseStart = TimeStamp();
if (!aElementTransitions) {
aElementTransitions =
@ -714,14 +714,14 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
}
}
nsTArray<ElementPropertyTransition> &pts =
ElementTransitions::TransitionPtrArray &pts =
aElementTransitions->mPropertyTransitions;
#ifdef DEBUG
for (uint32_t i = 0, i_end = pts.Length(); i < i_end; ++i) {
NS_ABORT_IF_FALSE(pts[i].mProperties.Length() == 1,
NS_ABORT_IF_FALSE(pts[i]->mProperties.Length() == 1,
"Should have one animation property for a transition");
NS_ABORT_IF_FALSE(i == currentIndex ||
pts[i].mProperties[0].mProperty != aProperty,
pts[i]->mProperties[0].mProperty != aProperty,
"duplicate transitions for property");
}
#endif
@ -955,8 +955,8 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
bool transitionStartedOrEnded = false;
do {
--i;
ElementPropertyTransition &pt = et->mPropertyTransitions[i];
if (pt.IsRemovedSentinel()) {
ElementPropertyTransition* pt = et->mPropertyTransitions[i];
if (pt->IsRemovedSentinel()) {
// Actually remove transitions one throttle-able cycle after their
// completion. We only clear on a throttle-able cycle because that
// means it is a regular restyle tick and thus it is safe to discard
@ -965,10 +965,11 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
if (aFlags == Can_Throttle) {
et->mPropertyTransitions.RemoveElementAt(i);
}
} else if (pt.mStartTime + pt.mDelay + pt.mIterationDuration <= now) {
MOZ_ASSERT(pt.mProperties.Length() == 1,
} else if (pt->mStartTime + pt->mDelay + pt->mIterationDuration <=
now) {
MOZ_ASSERT(pt->mProperties.Length() == 1,
"Should have one animation property for a transition");
nsCSSProperty prop = pt.mProperties[0].mProperty;
nsCSSProperty prop = pt->mProperties[0].mProperty;
if (nsCSSProps::PropHasFlags(prop, CSS_PROPERTY_REPORT_OTHER_NAME))
{
prop = nsCSSProps::OtherNameFor(prop);
@ -977,7 +978,7 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
NS_NAMED_LITERAL_STRING(before, "::before");
NS_NAMED_LITERAL_STRING(after, "::after");
events.AppendElement(
TransitionEventInfo(et->mElement, prop, pt.mIterationDuration,
TransitionEventInfo(et->mElement, prop, pt->mIterationDuration,
ep == nsGkAtoms::transitionsProperty ?
EmptyString() :
ep == nsGkAtoms::transitionsOfBeforeProperty ?
@ -991,11 +992,11 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
// a non-animation style change that would affect it, we need
// to know not to start a new transition for the transition
// from the almost-completed value to the final value.
pt.SetRemovedSentinel();
pt->SetRemovedSentinel();
et->UpdateAnimationGeneration(mPresContext);
transitionStartedOrEnded = true;
} else if (pt.mStartTime + pt.mDelay <= now && canThrottleTick &&
!pt.mIsRunningOnCompositor) {
} else if (pt->mStartTime + pt->mDelay <= now && canThrottleTick &&
!pt->mIsRunningOnCompositor) {
// Start a transition with a delay where we should start the
// transition proper.
et->UpdateAnimationGeneration(mPresContext);

View File

@ -87,8 +87,10 @@ struct ElementTransitions MOZ_FINAL
// should probably move to the relevant callers.
virtual bool CanPerformOnCompositorThread(CanAnimateFlags aFlags) const MOZ_OVERRIDE;
typedef InfallibleTArray<nsRefPtr<ElementPropertyTransition> >
TransitionPtrArray;
// Either zero or one for each CSS property:
nsTArray<ElementPropertyTransition> mPropertyTransitions;
TransitionPtrArray mPropertyTransitions;
};