Bug 1436659 - Factor out static time calculation methods on Animation; r=hiro

We will re-use these methods to perform various calculations once we introduce
the pending playback rate.

MozReview-Commit-ID: 2HV44TTNxHg

--HG--
extra : rebase_source : dcc883fb6db897a799900d709ca9c182dc149764
This commit is contained in:
Brian Birtles 2018-02-13 15:04:18 +09:00
parent 31272ef315
commit 37e9e76ea5
3 changed files with 60 additions and 36 deletions

View File

@ -309,8 +309,8 @@ Animation::GetCurrentTime() const
if (mTimeline && !mStartTime.IsNull()) {
Nullable<TimeDuration> timelineTime = mTimeline->GetCurrentTime();
if (!timelineTime.IsNull()) {
result.SetValue((timelineTime.Value() - mStartTime.Value())
.MultDouble(mPlaybackRate));
result = CurrentTimeFromTimelineTime(
timelineTime.Value(), mStartTime.Value(), mPlaybackRate);
}
}
return result;
@ -478,8 +478,8 @@ Animation::Finish(ErrorResult& aRv)
if (mStartTime.IsNull() &&
mTimeline &&
!mTimeline->GetCurrentTime().IsNull()) {
mStartTime.SetValue(mTimeline->GetCurrentTime().Value() -
limit.MultDouble(1.0 / mPlaybackRate));
mStartTime = StartTimeFromTimelineTime(
mTimeline->GetCurrentTime().Value(), limit, mPlaybackRate);
didChange = true;
}
@ -687,22 +687,12 @@ Animation::GetCurrentOrPendingStartTime() const
}
// Calculate the equivalent start time from the pending ready time.
result = StartTimeFromReadyTime(mPendingReadyTime.Value());
result = StartTimeFromTimelineTime(
mPendingReadyTime.Value(), mHoldTime.Value(), mPlaybackRate);
return result;
}
TimeDuration
Animation::StartTimeFromReadyTime(const TimeDuration& aReadyTime) const
{
MOZ_ASSERT(!mHoldTime.IsNull(), "Hold time should be set in order to"
" convert a ready time to a start time");
if (mPlaybackRate == 0) {
return aReadyTime;
}
return aReadyTime - mHoldTime.Value().MultDouble(1 / mPlaybackRate);
}
TimeStamp
Animation::AnimationTimeToTimeStamp(const StickyTimeDuration& aTime) const
{
@ -733,7 +723,7 @@ Animation::AnimationTimeToTimeStamp(const StickyTimeDuration& aTime) const
}
// Invert the standard relation:
// animation time = (timeline time - start time) * playback rate
// current time = (timeline time - start time) * playback rate
TimeDuration timelineTime =
TimeDuration(aTime).MultDouble(1.0 / mPlaybackRate) + mStartTime.Value();
@ -765,8 +755,8 @@ Animation::SilentlySetCurrentTime(const TimeDuration& aSeekTime)
mStartTime.SetNull();
}
} else {
mStartTime.SetValue(mTimeline->GetCurrentTime().Value() -
(aSeekTime.MultDouble(1 / mPlaybackRate)));
mStartTime = StartTimeFromTimelineTime(
mTimeline->GetCurrentTime().Value(), aSeekTime, mPlaybackRate);
}
mPreviousCurrentTime.SetNull();
@ -1001,8 +991,8 @@ Animation::ComposeStyle(ComposeAnimationResult&& aComposeResult,
timeToUse = mTimeline->ToTimelineTime(TimeStamp::Now());
}
if (!timeToUse.IsNull()) {
mHoldTime.SetValue((timeToUse.Value() - mStartTime.Value())
.MultDouble(mPlaybackRate));
mHoldTime = CurrentTimeFromTimelineTime(
timeToUse.Value(), mStartTime.Value(), mPlaybackRate);
}
}
@ -1188,7 +1178,8 @@ Animation::ResumeAt(const TimeDuration& aReadyTime)
// If we aborted a pending pause operation we will already have a start time
// we should use. In all other cases, we resolve it from the ready time.
if (mStartTime.IsNull()) {
mStartTime = StartTimeFromReadyTime(aReadyTime);
mStartTime =
StartTimeFromTimelineTime(aReadyTime, mHoldTime.Value(), mPlaybackRate);
if (mPlaybackRate != 0) {
mHoldTime.SetNull();
}
@ -1209,8 +1200,8 @@ Animation::PauseAt(const TimeDuration& aReadyTime)
"Expected to pause a pause-pending animation");
if (!mStartTime.IsNull() && mHoldTime.IsNull()) {
mHoldTime.SetValue((aReadyTime - mStartTime.Value())
.MultDouble(mPlaybackRate));
mHoldTime = CurrentTimeFromTimelineTime(
aReadyTime, mStartTime.Value(), mPlaybackRate);
}
mStartTime.SetNull();
mPendingState = PendingState::NotPending;
@ -1271,8 +1262,10 @@ Animation::UpdateFinishedState(SeekFlag aSeekFlag,
mTimeline &&
!mTimeline->GetCurrentTime().IsNull()) {
if (aSeekFlag == SeekFlag::DidSeek && !mHoldTime.IsNull()) {
mStartTime.SetValue(mTimeline->GetCurrentTime().Value() -
(mHoldTime.Value().MultDouble(1 / mPlaybackRate)));
mStartTime =
StartTimeFromTimelineTime(mTimeline->GetCurrentTime().Value(),
mHoldTime.Value(),
mPlaybackRate);
}
mHoldTime.SetNull();
}

View File

@ -242,12 +242,46 @@ public:
*/
Nullable<TimeDuration> GetCurrentOrPendingStartTime() const;
/**
* Calculates the corresponding start time to use for an animation that is
* currently pending with current time |mHoldTime| but should behave
* as if it began or resumed playback at timeline time |aReadyTime|.
* The following relationship from the definition of the 'current time' is
* re-used in many algorithms so we extract it here into a static method that
* can be re-used:
*
* current time = (timeline time - start time) * playback rate
*
* As per https://drafts.csswg.org/web-animations-1/#current-time
*/
TimeDuration StartTimeFromReadyTime(const TimeDuration& aReadyTime) const;
static TimeDuration CurrentTimeFromTimelineTime(
const TimeDuration& aTimelineTime,
const TimeDuration& aStartTime,
float aPlaybackRate)
{
return (aTimelineTime - aStartTime).MultDouble(aPlaybackRate);
}
/**
* As with calculating the current time, we often need to calculate a start
* time from a current time. The following method simply inverts the current
* time relationship.
*
* In each case where this is used, the desired behavior for playbackRate ==
* 0 is to return the specified timeline time (often referred to as the ready
* time).
*/
static TimeDuration StartTimeFromTimelineTime(
const TimeDuration& aTimelineTime,
const TimeDuration& aCurrentTime,
float aPlaybackRate)
{
TimeDuration result = aTimelineTime;
if (aPlaybackRate == 0) {
return result;
}
result -= aCurrentTime.MultDouble(1.0 / aPlaybackRate);
return result;
}
/**
* Converts a time in the timescale of this Animation's currentTime, to a

View File

@ -7,6 +7,7 @@
#include "AnimationInfo.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/layers/AnimationHelper.h"
#include "mozilla/dom/Animation.h"
namespace mozilla {
namespace layers {
@ -104,16 +105,12 @@ AnimationInfo::StartPendingAnimations(const TimeStamp& aReadyTime)
Animation& anim = mAnimations[animIdx];
// If the animation is play-pending, resolve the start time.
// This mirrors the calculation in Animation::StartTimeFromReadyTime.
if (anim.startTime().type() == MaybeTimeDuration::Tnull_t &&
!anim.originTime().IsNull() &&
!anim.isNotPlaying()) {
TimeDuration readyTime = aReadyTime - anim.originTime();
anim.startTime() =
anim.playbackRate() == 0
? readyTime
: readyTime - anim.holdTime().MultDouble(1.0 /
anim.playbackRate());
anim.startTime() = dom::Animation::StartTimeFromTimelineTime(
readyTime, anim.holdTime(), anim.playbackRate());
updated = true;
}
}