зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1223658 - Part 2: Pass delay property to compositor. r=birtles
The check of negative elapsedDuration is basically no longer valid since animation delay is not factored into start time any more. But still we have somtimes met negative elapsedDuration sice we use a previous vsync time stamp for async animations to make the animations more sync. This is not a problem in most cases but makes two reftests intermitent failure because both of them used steps(1, start), the steps(1, start) composed different results in the before phase and in the active phase. To avoid this difference this patch replace the steps(1, start) with steps(1, end). Once we incorpolate playbackRate into GetCurrentOrPendingStartTime, we don't need to call AnimationTimeToTimeStamp for deviding delay by playbackRate since the time passed to AnimationTimeToTimeStamp does not contain delay any more. MozReview-Commit-ID: IVE2IFfNgm0 --HG-- extra : rebase_source : 7cb42e57067c21451706bd89284016d996dc8b12
This commit is contained in:
Родитель
ac47637175
Коммит
d8ec730df8
|
@ -664,12 +664,22 @@ Animation::GetCurrentOrPendingStartTime() const
|
|||
}
|
||||
|
||||
// Calculate the equivalent start time from the pending ready time.
|
||||
// This is the same as the calculation performed in ResumeAt and will
|
||||
// need to incorporate the playbackRate when implemented (bug 1127380).
|
||||
result.SetValue(mPendingReadyTime.Value() - mHoldTime.Value());
|
||||
result = StartTimeFromReadyTime(mPendingReadyTime.Value());
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -1066,12 +1076,9 @@ 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);
|
||||
if (mPlaybackRate != 0) {
|
||||
mStartTime.SetValue(aReadyTime -
|
||||
(mHoldTime.Value().MultDouble(1 / mPlaybackRate)));
|
||||
mHoldTime.SetNull();
|
||||
} else {
|
||||
mStartTime.SetValue(aReadyTime);
|
||||
}
|
||||
}
|
||||
mPendingState = PendingState::NotPending;
|
||||
|
|
|
@ -239,6 +239,13 @@ 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|.
|
||||
*/
|
||||
TimeDuration StartTimeFromReadyTime(const TimeDuration& aReadyTime) const;
|
||||
|
||||
/**
|
||||
* Converts a time in the timescale of this Animation's currentTime, to a
|
||||
* TimeStamp. Returns a null TimeStamp if the conversion cannot be performed
|
||||
|
|
|
@ -673,24 +673,9 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint)
|
|||
"Failed to resolve start time of pending animations");
|
||||
TimeDuration elapsedDuration =
|
||||
(aPoint - animation.startTime()).MultDouble(animation.playbackRate());
|
||||
// Skip animations that are yet to start.
|
||||
//
|
||||
// Currently, this should only happen when the refresh driver is under test
|
||||
// control and is made to produce a time in the past or is restored from
|
||||
// test control causing it to jump backwards in time.
|
||||
//
|
||||
// Since activeAnimations is true, this could mean we keep compositing
|
||||
// unnecessarily during the delay, but so long as this only happens while
|
||||
// the refresh driver is under test control that should be ok.
|
||||
if (elapsedDuration.ToSeconds() < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TimingParams timing;
|
||||
timing.mDuration.emplace(animation.duration());
|
||||
// Currently animations run on the compositor have their delay factored
|
||||
// into their start time, hence the delay is effectively zero.
|
||||
timing.mDelay = TimeDuration(0);
|
||||
timing.mDelay = animation.delay();
|
||||
timing.mIterations = animation.iterations();
|
||||
timing.mIterationStart = animation.iterationStart();
|
||||
timing.mDirection =
|
||||
|
@ -709,8 +694,9 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint)
|
|||
Nullable<TimeDuration>(elapsedDuration), timing,
|
||||
animation.playbackRate());
|
||||
|
||||
MOZ_ASSERT(!computedTiming.mProgress.IsNull(),
|
||||
"iteration progress should not be null");
|
||||
if (computedTiming.mProgress.IsNull()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t segmentIndex = 0;
|
||||
size_t segmentSize = animation.segments().Length();
|
||||
|
|
|
@ -178,10 +178,8 @@ union AnimationData {
|
|||
};
|
||||
|
||||
struct Animation {
|
||||
// Unlike in nsAnimationManager, this start time is at the end of the
|
||||
// delay. If the delay is changed dynamically, the layer's data will
|
||||
// be updated.
|
||||
TimeStamp startTime;
|
||||
TimeDuration delay;
|
||||
// The value of the animation's current time at the moment it was created.
|
||||
// For animations that are waiting to start, their startTime will be null.
|
||||
// Once the animation is ready to start, we calculate an appropriate value
|
||||
|
|
|
@ -422,10 +422,11 @@ AddAnimationForProperty(nsIFrame* aFrame, const AnimationProperty& aProperty,
|
|||
Nullable<TimeDuration> startTime = aAnimation->GetCurrentOrPendingStartTime();
|
||||
animation->startTime() = startTime.IsNull()
|
||||
? TimeStamp()
|
||||
: aAnimation->AnimationTimeToTimeStamp(
|
||||
StickyTimeDuration(timing.mDelay));
|
||||
: aAnimation->GetTimeline()->
|
||||
ToTimeStamp(startTime.Value());
|
||||
animation->initialCurrentTime() = aAnimation->GetCurrentTime().Value()
|
||||
- timing.mDelay;
|
||||
animation->delay() = timing.mDelay;
|
||||
animation->duration() = computedTiming.mDuration;
|
||||
animation->iterations() = computedTiming.mIterations;
|
||||
animation->iterationStart() = computedTiming.mIterationStart;
|
||||
|
|
|
@ -14,8 +14,15 @@ span {
|
|||
#test {
|
||||
width: 100px; height: 100px;
|
||||
background: blue;
|
||||
transition: opacity 100s steps(1, start);
|
||||
opacity: 0 ! important;
|
||||
/*
|
||||
* On the compositor we use a previous vsync time stamp rather than the
|
||||
* current time stamp, as a result sometimes transition may be still in
|
||||
* before phase after waiting a frame. To compose the same opacity value
|
||||
* regardless of whether the transition is in before or active phase, we use
|
||||
* steps(1, end) here.
|
||||
*/
|
||||
transition: opacity 100s steps(1, end);
|
||||
opacity: 1 ! important;
|
||||
}
|
||||
</style>
|
||||
<span></span>
|
||||
|
@ -25,7 +32,7 @@ window.addEventListener("load", () => {
|
|||
var target = document.getElementById("test");
|
||||
getComputedStyle(target).opacity;
|
||||
|
||||
target.style.setProperty("opacity", "1", "important");
|
||||
target.style.setProperty("opacity", "0", "important");
|
||||
getComputedStyle(target).opacity;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
|
|
|
@ -14,8 +14,15 @@ span {
|
|||
#test {
|
||||
width: 100px; height: 100px;
|
||||
background: blue;
|
||||
transition: transform 100s steps(1, start);
|
||||
transform: translateX(200px) ! important;
|
||||
/*
|
||||
* On the compositor we use a previous vsync time stamp rather than the
|
||||
* current time stamp, as a result sometimes transition may be still in
|
||||
* before phase after waiting a frame. To compose the same transform value
|
||||
* regardless of whether the transition is in before or active phase, we use
|
||||
* steps(1, end) here.
|
||||
*/
|
||||
transition: transform 100s steps(1, end);
|
||||
transform: none ! important;
|
||||
}
|
||||
</style>
|
||||
<span></span>
|
||||
|
@ -25,7 +32,7 @@ window.addEventListener("load", () => {
|
|||
var target = document.getElementById("test");
|
||||
getComputedStyle(target).transform;
|
||||
|
||||
target.style.setProperty("transform", "none", "important");
|
||||
target.style.setProperty("transform", "translateX(200px)", "important");
|
||||
getComputedStyle(target).transform;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче