void AnimationPlayer::DoPlay() { // FIXME: When we implement finishing behavior (bug 1074630) we will // need to pass a flag so that when we start playing due to a change in // animation-play-state we *don't* trigger finishing behavior. Nullable<TimeDuration> currentTime = GetCurrentTime(); if (currentTime.IsNull()) { mHoldTime.SetValue(TimeDuration(0)); } else if (mHoldTime.IsNull()) { // If the hold time is null, we are already playing normally return; } // Clear ready promise. We'll create a new one lazily. mReady = nullptr; mIsPending = true; nsIDocument* doc = GetRenderedDocument(); if (!doc) { StartOnNextTick(Nullable<TimeDuration>()); return; } PendingPlayerTracker* tracker = doc->GetOrCreatePendingPlayerTracker(); tracker->AddPlayPending(*this); // We may have updated the current time when we set the hold time above // so notify source content. UpdateSourceContent(); }
void AnimationPlayer::Tick() { // FIXME (bug 1112969): Check if we are pending but have lost access to the // pending player tracker. If that's the case we should probably trigger the // animation now. UpdateSourceContent(); }
void AnimationPlayer::ResumeAt(const TimeDuration& aResumeTime) { // This method is only expected to be called for a player that is // waiting to play. We can easily adapt it to handle other states // but it's currently not necessary. MOZ_ASSERT(PlayState() == AnimationPlayState::Pending, "Expected to resume a pending player"); MOZ_ASSERT(!mHoldTime.IsNull(), "A player in the pending state should have a resolved hold time"); mStartTime.SetValue(aResumeTime - mHoldTime.Value()); mHoldTime.SetNull(); mIsPending = false; UpdateSourceContent(); if (mReady) { mReady->MaybeResolve(this); } }
void AnimationPlayer::DoPlay() { // FIXME: When we implement finishing behavior (bug 1074630) we will // need to pass a flag so that when we start playing due to a change in // animation-play-state we *don't* trigger finishing behavior. Nullable<TimeDuration> currentTime = GetCurrentTime(); if (currentTime.IsNull()) { mHoldTime.SetValue(TimeDuration(0)); } else if (mHoldTime.IsNull()) { // If the hold time is null, we are already playing normally return; } // Clear ready promise. We'll create a new one lazily. mReady = nullptr; mIsPending = true; nsIDocument* doc = GetRenderedDocument(); if (!doc) { // If we have no rendered document (e.g. because the source content's // target element is orphaned), then treat the animation as ready and // start it immediately. It is probably preferable to make playing // *always* asynchronous (e.g. by setting some additional state that // marks this player as pending and queueing a runnable to resolve the // start time). That situation, however, is currently rare enough that // we don't bother for now. StartNow(); return; } PendingPlayerTracker* tracker = doc->GetOrCreatePendingPlayerTracker(); tracker->AddPlayPending(*this); // We may have updated the current time when we set the hold time above // so notify source content. UpdateSourceContent(); }
void AnimationPlayer::Tick() { // Since we are not guaranteed to get only one call per refresh driver tick, // it's possible that mPendingReadyTime is set to a time in the future. // In that case, we should wait until the next refresh driver tick before // resuming. if (mIsPending && !mPendingReadyTime.IsNull() && mPendingReadyTime.Value() <= mTimeline->GetCurrentTime().Value()) { ResumeAt(mPendingReadyTime.Value()); mPendingReadyTime.SetNull(); } if (IsPossiblyOrphanedPendingPlayer()) { MOZ_ASSERT(mTimeline && !mTimeline->GetCurrentTime().IsNull(), "Orphaned pending players should have an active timeline"); ResumeAt(mTimeline->GetCurrentTime().Value()); } UpdateSourceContent(); }
void AnimationPlayer::StartNow() { // This method is only expected to be called for an animation that is // waiting to play. We can easily adapt it to handle other states // but it's currently not necessary. MOZ_ASSERT(PlayState() == AnimationPlayState::Pending, "Expected to start a pending player"); MOZ_ASSERT(!mHoldTime.IsNull(), "A player in the pending state should have a resolved hold time"); Nullable<TimeDuration> readyTime = mTimeline->GetCurrentTime(); // FIXME (bug 1096776): If readyTime.IsNull(), we should return early here. // This will leave mIsPending = true but the caller will remove us from the // PendingPlayerTracker if we were added there. // Then, in Tick(), if we have: // - a resolved timeline, and // - mIsPending = true, and // - *no* document or we are *not* in the PendingPlayerTracker // then we should call StartNow. // // For now, however, we don't support inactive/missing timelines so // |readyTime| should be resolved. MOZ_ASSERT(!readyTime.IsNull(), "Missing or inactive timeline"); mStartTime.SetValue(readyTime.Value() - mHoldTime.Value()); mHoldTime.SetNull(); mIsPending = false; UpdateSourceContent(); PostUpdate(); if (mReady) { mReady->MaybeResolve(this); } }
void AnimationPlayer::Tick() { UpdateSourceContent(); }