mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Bug 1029370 part 1 - Move active duration calculation to GetComputedTimingAt; r=dholbert
This patch makes the active duration a property of the ComputedTiming struct and returns this as part of calculating GetComputedTimingAt. GetComputedTimingAt was already calling the method to calculate the ActiveDuration and the only other callers of ActiveDuration() were also calling GetComputedTimingAt so this doesn't make us do any unnecessary calculation. I've left ActiveDuration as a public method on ElementAnimation for now since it's a struct and just about everything there is public. At some point in the future we'll probably make this more class-like to hide some details but that can happen as a separate step. This patch does, however, move the definition of ActiveDuration inside the .cpp file. In tidying up GetComputedTimingAt we also replace all the references to TimeDuration() and TimeDuration(0) with a single local variable representing zero duration. This should be easier to read and possibly a little faster. We don't use a function static variable since this method is called from different threads and the initialization of function statics is not guaranteed to be thread-safe until C++0x.
This commit is contained in:
parent
51cf0526d8
commit
c5a2510c5f
@ -447,18 +447,20 @@ ComputedTiming
|
||||
ElementAnimation::GetComputedTimingAt(TimeDuration aLocalTime,
|
||||
const AnimationTiming& aTiming)
|
||||
{
|
||||
const TimeDuration zeroDuration;
|
||||
|
||||
// Currently we expect negative durations to be picked up during CSS
|
||||
// parsing but when we start receiving timing parameters from other sources
|
||||
// we will need to clamp negative durations here.
|
||||
// For now, if we're hitting this it probably means we've overflowing
|
||||
// integer arithmetic in mozilla::TimeStamp.
|
||||
MOZ_ASSERT(aTiming.mIterationDuration >= TimeDuration(0),
|
||||
MOZ_ASSERT(aTiming.mIterationDuration >= zeroDuration,
|
||||
"Expecting iteration duration >= 0");
|
||||
|
||||
// Always return the same object to benefit from return-value optimization.
|
||||
ComputedTiming result;
|
||||
|
||||
TimeDuration activeDuration = ActiveDuration(aTiming);
|
||||
result.mActiveDuration = ActiveDuration(aTiming);
|
||||
|
||||
// When we finish exactly at the end of an iteration we need to report
|
||||
// the end of the final iteration and not the start of the next iteration
|
||||
@ -467,14 +469,14 @@ ElementAnimation::GetComputedTimingAt(TimeDuration aLocalTime,
|
||||
|
||||
// Get the normalized time within the active interval.
|
||||
TimeDuration activeTime;
|
||||
if (aLocalTime >= aTiming.mDelay + activeDuration) {
|
||||
if (aLocalTime >= aTiming.mDelay + result.mActiveDuration) {
|
||||
result.mPhase = ComputedTiming::AnimationPhase_After;
|
||||
if (!aTiming.FillsForwards()) {
|
||||
// The animation isn't active or filling at this time.
|
||||
result.mTimeFraction = ComputedTiming::kNullTimeFraction;
|
||||
return result;
|
||||
}
|
||||
activeTime = activeDuration;
|
||||
activeTime = result.mActiveDuration;
|
||||
// Note that infinity == floor(infinity) so this will also be true when we
|
||||
// have finished an infinitely repeating animation of zero duration.
|
||||
isEndOfFinalIteration =
|
||||
@ -489,7 +491,7 @@ ElementAnimation::GetComputedTimingAt(TimeDuration aLocalTime,
|
||||
}
|
||||
// activeTime is zero
|
||||
} else {
|
||||
MOZ_ASSERT(activeDuration != TimeDuration(),
|
||||
MOZ_ASSERT(result.mActiveDuration != zeroDuration,
|
||||
"How can we be in the middle of a zero-duration interval?");
|
||||
result.mPhase = ComputedTiming::AnimationPhase_Active;
|
||||
activeTime = aLocalTime - aTiming.mDelay;
|
||||
@ -497,7 +499,7 @@ ElementAnimation::GetComputedTimingAt(TimeDuration aLocalTime,
|
||||
|
||||
// Get the position within the current iteration.
|
||||
TimeDuration iterationTime;
|
||||
if (aTiming.mIterationDuration != TimeDuration()) {
|
||||
if (aTiming.mIterationDuration != zeroDuration) {
|
||||
iterationTime = isEndOfFinalIteration
|
||||
? aTiming.mIterationDuration
|
||||
: activeTime % aTiming.mIterationDuration;
|
||||
@ -510,7 +512,7 @@ ElementAnimation::GetComputedTimingAt(TimeDuration aLocalTime,
|
||||
? UINT64_MAX // FIXME: When we return this via the API we'll need
|
||||
// to make sure it ends up being infinity.
|
||||
: static_cast<uint64_t>(aTiming.mIterationCount) - 1;
|
||||
} else if (activeTime == TimeDuration(0)) {
|
||||
} else if (activeTime == zeroDuration) {
|
||||
// If the active time is zero we're either in the first iteration
|
||||
// (including filling backwards) or we have finished an animation with an
|
||||
// iteration duration of zero that is filling forwards (but we're not at
|
||||
@ -533,7 +535,7 @@ ElementAnimation::GetComputedTimingAt(TimeDuration aLocalTime,
|
||||
: fmod(aTiming.mIterationCount, 1.0f);
|
||||
} else {
|
||||
// We are in the active phase so the iteration duration can't be zero.
|
||||
MOZ_ASSERT(aTiming.mIterationDuration != TimeDuration(0),
|
||||
MOZ_ASSERT(aTiming.mIterationDuration != zeroDuration,
|
||||
"In the active phase of a zero-duration animation?");
|
||||
result.mTimeFraction =
|
||||
aTiming.mIterationDuration == TimeDuration::Forever()
|
||||
@ -563,6 +565,21 @@ ElementAnimation::GetComputedTimingAt(TimeDuration aLocalTime,
|
||||
return result;
|
||||
}
|
||||
|
||||
TimeDuration
|
||||
ElementAnimation::ActiveDuration(const AnimationTiming& aTiming)
|
||||
{
|
||||
if (aTiming.mIterationCount == mozilla::PositiveInfinity<float>()) {
|
||||
// An animation that repeats forever has an infinite active duration
|
||||
// unless its iteration duration is zero, in which case it has a zero
|
||||
// active duration.
|
||||
const TimeDuration zeroDuration;
|
||||
return aTiming.mIterationDuration == zeroDuration
|
||||
? zeroDuration
|
||||
: TimeDuration::Forever();
|
||||
}
|
||||
return aTiming.mIterationDuration.MultDouble(aTiming.mIterationCount);
|
||||
}
|
||||
|
||||
namespace css {
|
||||
|
||||
bool
|
||||
|
@ -273,6 +273,10 @@ struct ComputedTiming
|
||||
|
||||
static const double kNullTimeFraction;
|
||||
|
||||
// The total duration of the animation including all iterations.
|
||||
// Will equal TimeDuration::Forever() if the animation repeats indefinitely.
|
||||
TimeDuration mActiveDuration;
|
||||
|
||||
// Will be kNullTimeFraction if the animation is neither animating nor
|
||||
// filling at the sampled time.
|
||||
double mTimeFraction;
|
||||
@ -345,20 +349,6 @@ public:
|
||||
return (IsPaused() ? mPauseStart : aTime) - mStartTime;
|
||||
}
|
||||
|
||||
// Return the duration of the active interval for the given timing parameters.
|
||||
static mozilla::TimeDuration ActiveDuration(const AnimationTiming& aTiming) {
|
||||
if (aTiming.mIterationCount == mozilla::PositiveInfinity<float>()) {
|
||||
// An animation that repeats forever has an infinite active duration
|
||||
// unless its iteration duration is zero, in which case it has a zero
|
||||
// active duration.
|
||||
const TimeDuration zeroDuration;
|
||||
return aTiming.mIterationDuration == zeroDuration
|
||||
? zeroDuration
|
||||
: mozilla::TimeDuration::Forever();
|
||||
}
|
||||
return aTiming.mIterationDuration.MultDouble(aTiming.mIterationCount);
|
||||
}
|
||||
|
||||
// Return the duration from the start the active interval to the point where
|
||||
// the animation begins playback. This is zero unless the animation has
|
||||
// a negative delay in which case it is the absolute value of the delay.
|
||||
@ -376,6 +366,9 @@ public:
|
||||
static ComputedTiming GetComputedTimingAt(TimeDuration aLocalTime,
|
||||
const AnimationTiming& aTiming);
|
||||
|
||||
// Return the duration of the active interval for the given timing parameters.
|
||||
static mozilla::TimeDuration ActiveDuration(const AnimationTiming& aTiming);
|
||||
|
||||
nsString mName; // empty string for 'none'
|
||||
AnimationTiming mTiming;
|
||||
// The beginning of the delay period. This is also set to a null
|
||||
|
@ -77,8 +77,6 @@ nsAnimationManager::GetEventsAt(CommonElementAnimationData* aEA,
|
||||
break;
|
||||
|
||||
case ComputedTiming::AnimationPhase_After:
|
||||
TimeDuration activeDuration =
|
||||
ElementAnimation::ActiveDuration(anim->mTiming);
|
||||
// If we skipped the animation interval entirely, dispatch
|
||||
// 'animationstart' first
|
||||
if (anim->mLastNotification ==
|
||||
@ -88,7 +86,7 @@ nsAnimationManager::GetEventsAt(CommonElementAnimationData* aEA,
|
||||
// internal consistency.)
|
||||
anim->mLastNotification = 0;
|
||||
TimeDuration elapsedTime =
|
||||
std::min(anim->InitialAdvance(), activeDuration);
|
||||
std::min(anim->InitialAdvance(), computedTiming.mActiveDuration);
|
||||
AnimationEventInfo ei(aEA->mElement, anim->mName, NS_ANIMATION_START,
|
||||
elapsedTime, aEA->PseudoElement());
|
||||
aEventsToDispatch.AppendElement(ei);
|
||||
@ -98,7 +96,8 @@ nsAnimationManager::GetEventsAt(CommonElementAnimationData* aEA,
|
||||
ElementAnimation::LAST_NOTIFICATION_END) {
|
||||
anim->mLastNotification = ElementAnimation::LAST_NOTIFICATION_END;
|
||||
AnimationEventInfo ei(aEA->mElement, anim->mName, NS_ANIMATION_END,
|
||||
activeDuration, aEA->PseudoElement());
|
||||
computedTiming.mActiveDuration,
|
||||
aEA->PseudoElement());
|
||||
aEventsToDispatch.AppendElement(ei);
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user