Bug 1025709 part 3 - Move delay calculation to GetComputedTimingAt; r=heycam

Now that an animation's delay is part of AnimationTiming--the struct we pass to
GetComputedTimingAt--it makes sense to act on it in GetComputedTimingAt.

This also happens to bring the procedures here closer to the algorithm
definitions in Web Animations.

As part of this refactoring, this patch converts ElementAnimation::IsRunningAt
to use GetComputedTiming since the previous approach no longer works now that
GetLocalTimeAt (nee ElapsedDurationAt) no longer handles delays. This also
removes duplicated logic.

Also, previously ElapsedDurationAt would assert if called on a finished
transition since TimeDuration's - operator wouldn't like the null mStartTime.
This patch adds an assertion for this case to GetLocalTimeAt to ease debugging.
This commit is contained in:
Brian Birtles 2014-06-20 12:39:24 +09:00
parent 6607a15a60
commit 7c7ea66905
3 changed files with 26 additions and 27 deletions

View File

@ -370,24 +370,21 @@ const double ComputedTiming::kNullTimeFraction =
bool
ElementAnimation::IsRunningAt(TimeStamp aTime) const
{
if (IsPaused() || mTiming.mIterationDuration.ToMilliseconds() <= 0.0 ||
IsFinishedTransition()) {
if (IsPaused() || IsFinishedTransition()) {
return false;
}
double iterationsElapsed =
ElapsedDurationAt(aTime) / mTiming.mIterationDuration;
return 0.0 <= iterationsElapsed &&
iterationsElapsed < mTiming.mIterationCount;
ComputedTiming computedTiming =
GetComputedTimingAt(GetLocalTimeAt(aTime), mTiming);
return computedTiming.mPhase == ComputedTiming::AnimationPhase_Active;
}
bool
ElementAnimation::IsCurrentAt(TimeStamp aTime) const
{
if (!IsFinishedTransition()) {
TimeDuration elapsedDuration = ElapsedDurationAt(aTime);
ComputedTiming computedTiming =
ElementAnimation::GetComputedTimingAt(elapsedDuration, mTiming);
GetComputedTimingAt(GetLocalTimeAt(aTime), mTiming);
if (computedTiming.mPhase == ComputedTiming::AnimationPhase_Before ||
computedTiming.mPhase == ComputedTiming::AnimationPhase_Active) {
return true;
@ -410,7 +407,7 @@ ElementAnimation::HasAnimationOfProperty(nsCSSProperty aProperty) const
}
ComputedTiming
ElementAnimation::GetComputedTimingAt(TimeDuration aElapsedDuration,
ElementAnimation::GetComputedTimingAt(TimeDuration aLocalTime,
const AnimationTiming& aTiming)
{
// Always return the same object to benefit from return-value optimization.
@ -425,7 +422,7 @@ ElementAnimation::GetComputedTimingAt(TimeDuration aElapsedDuration,
// Get the normalized time within the active interval.
TimeDuration activeTime;
if (aElapsedDuration >= activeDuration) {
if (aLocalTime >= aTiming.mDelay + activeDuration) {
result.mPhase = ComputedTiming::AnimationPhase_After;
if (!aTiming.FillsForwards()) {
// The animation isn't active or filling at this time.
@ -438,7 +435,7 @@ ElementAnimation::GetComputedTimingAt(TimeDuration aElapsedDuration,
isEndOfFinalIteration =
aTiming.mIterationCount != 0.0 &&
aTiming.mIterationCount == floor(aTiming.mIterationCount);
} else if (aElapsedDuration < TimeDuration()) {
} else if (aLocalTime < aTiming.mDelay) {
result.mPhase = ComputedTiming::AnimationPhase_Before;
if (!aTiming.FillsBackwards()) {
// The animation isn't active or filling at this time.
@ -450,7 +447,7 @@ ElementAnimation::GetComputedTimingAt(TimeDuration aElapsedDuration,
MOZ_ASSERT(activeDuration != TimeDuration(),
"How can we be in the middle of a zero-duration interval?");
result.mPhase = ComputedTiming::AnimationPhase_Active;
activeTime = aElapsedDuration;
activeTime = aLocalTime - aTiming.mDelay;
}
// Get the position within the current iteration.

View File

@ -321,12 +321,14 @@ public:
bool IsRunningAt(mozilla::TimeStamp aTime) const;
bool IsCurrentAt(mozilla::TimeStamp aTime) const;
// Return the duration, at aTime (or, if paused, mPauseStart), since
// the *end* of the delay period. May be negative.
mozilla::TimeDuration ElapsedDurationAt(mozilla::TimeStamp aTime) const {
NS_ABORT_IF_FALSE(!IsPaused() || aTime >= mPauseStart,
"if paused, aTime must be at least mPauseStart");
return (IsPaused() ? mPauseStart : aTime) - mStartTime - mTiming.mDelay;
// Return the duration at aTime (or, if paused, mPauseStart) since
// the start of the delay period. May be negative.
mozilla::TimeDuration GetLocalTimeAt(mozilla::TimeStamp aTime) const {
MOZ_ASSERT(!IsPaused() || aTime >= mPauseStart,
"if paused, aTime must be at least mPauseStart");
MOZ_ASSERT(!IsFinishedTransition(),
"GetLocalTimeAt should not be called on a finished transition");
return (IsPaused() ? mPauseStart : aTime) - mStartTime;
}
// Return the duration of the active interval for the given timing parameters.
@ -357,7 +359,7 @@ public:
// This function returns ComputedTiming::kNullTimeFraction for the
// mTimeFraction member of the return value if the animation should not be
// run (because it is not currently active and is not filling at this time).
static ComputedTiming GetComputedTimingAt(TimeDuration aElapsedDuration,
static ComputedTiming GetComputedTimingAt(TimeDuration aLocalTime,
const AnimationTiming& aTiming);
nsString mName; // empty string for 'none'

View File

@ -73,11 +73,11 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
continue;
}
// The ElapsedDurationAt() call here handles pausing. But:
// The GetLocalTimeAt() call here handles pausing. But:
// FIXME: avoid recalculating every time when paused.
TimeDuration elapsedDuration = anim->ElapsedDurationAt(aRefreshTime);
TimeDuration localTime = anim->GetLocalTimeAt(aRefreshTime);
ComputedTiming computedTiming =
ElementAnimation::GetComputedTimingAt(elapsedDuration, anim->mTiming);
ElementAnimation::GetComputedTimingAt(localTime, anim->mTiming);
// XXX We shouldn't really be using mLastNotification as a general
// indicator that the animation has finished, it should be reserved for
@ -113,11 +113,11 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
ElementAnimation* anim = mAnimations[animIdx];
// The ElapsedDurationAt() call here handles pausing. But:
// The GetLocalTimeAt() call here handles pausing. But:
// FIXME: avoid recalculating every time when paused.
TimeDuration elapsedDuration = anim->ElapsedDurationAt(aRefreshTime);
TimeDuration localTime = anim->GetLocalTimeAt(aRefreshTime);
ComputedTiming computedTiming =
ElementAnimation::GetComputedTimingAt(elapsedDuration, anim->mTiming);
ElementAnimation::GetComputedTimingAt(localTime, anim->mTiming);
if ((computedTiming.mPhase == ComputedTiming::AnimationPhase_Before ||
computedTiming.mPhase == ComputedTiming::AnimationPhase_Active) &&
@ -213,9 +213,9 @@ ElementAnimations::GetEventsAt(TimeStamp aRefreshTime,
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
ElementAnimation* anim = mAnimations[animIdx];
TimeDuration elapsedDuration = anim->ElapsedDurationAt(aRefreshTime);
TimeDuration localTime = anim->GetLocalTimeAt(aRefreshTime);
ComputedTiming computedTiming =
ElementAnimation::GetComputedTimingAt(elapsedDuration, anim->mTiming);
ElementAnimation::GetComputedTimingAt(localTime, anim->mTiming);
switch (computedTiming.mPhase) {
case ComputedTiming::AnimationPhase_Before: