diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index f76808606d7..c2b2a87d240 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -433,8 +433,7 @@ ElementAnimation::CurrentTime() const // have a *local* time. However, since we have a 1:1 correspondence between // AnimationPlayers and Animations, and since the startTime of *Animations* // (but not AnimationPlayers) is always 0, these are currently identical. - Nullable currentTime = - GetLocalTimeAt(mTimeline->GetCurrentTimeStamp()); + Nullable currentTime = GetLocalTime(); // The current time is currently only going to be null when don't have a // refresh driver (e.g. because we are in a display:none iframe). @@ -461,8 +460,7 @@ ElementAnimation::IsRunningAt(TimeStamp aTime) const return false; } - ComputedTiming computedTiming = - GetComputedTimingAt(GetLocalTimeAt(aTime), mTiming); + ComputedTiming computedTiming = GetComputedTimingAt(GetLocalTime(), mTiming); return computedTiming.mPhase == ComputedTiming::AnimationPhase_Active; } @@ -473,8 +471,7 @@ ElementAnimation::IsCurrentAt(TimeStamp aTime) const return false; } - ComputedTiming computedTiming = - GetComputedTimingAt(GetLocalTimeAt(aTime), mTiming); + ComputedTiming computedTiming = GetComputedTimingAt(GetLocalTime(), mTiming); return computedTiming.mPhase == ComputedTiming::AnimationPhase_Before || computedTiming.mPhase == ComputedTiming::AnimationPhase_Active; } @@ -847,9 +844,9 @@ ElementAnimationCollection::EnsureStyleRuleFor(TimeStamp aRefreshTime, continue; } - // The GetLocalTimeAt() call here handles pausing. But: + // The GetLocalTime() call here handles pausing. But: // FIXME: avoid recalculating every time when paused. - Nullable localTime = anim->GetLocalTimeAt(aRefreshTime); + Nullable localTime = anim->GetLocalTime(); ComputedTiming computedTiming = ElementAnimation::GetComputedTimingAt(localTime, anim->mTiming); @@ -891,9 +888,9 @@ ElementAnimationCollection::EnsureStyleRuleFor(TimeStamp aRefreshTime, continue; } - // The GetLocalTimeAt() call here handles pausing. But: + // The GetLocalTime() call here handles pausing. But: // FIXME: avoid recalculating every time when paused. - Nullable localTime = anim->GetLocalTimeAt(aRefreshTime); + Nullable localTime = anim->GetLocalTime(); ComputedTiming computedTiming = ElementAnimation::GetComputedTimingAt(localTime, anim->mTiming); diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index 68e9a31fb1a..e7a7c3c5937 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -363,17 +363,23 @@ public: bool IsRunningAt(mozilla::TimeStamp aTime) const; bool IsCurrentAt(mozilla::TimeStamp aTime) const; - // Return the duration at aTime (or, if paused, mPauseStart) since - // the start of the delay period. May be negative. - // Returns a null value if and only if the passed-in TimeStamp IsNull(). - Nullable - GetLocalTimeAt(mozilla::TimeStamp aTime) const { - MOZ_ASSERT(aTime.IsNull() || !IsPaused() || aTime >= mPauseStart, + // Return the duration since the start of the delay period, taking into + // account the pause state. May be negative. + // Returns a null value if the timeline associated with this object has a + // current timestamp that is null or if the start time of this object is + // null. + Nullable GetLocalTime() const { + const mozilla::TimeStamp& timelineTime = mTimeline->GetCurrentTimeStamp(); + // FIXME: In order to support arbitrary timelines we will need to fix + // the pause logic to handle the timeline time going backwards. + MOZ_ASSERT(timelineTime.IsNull() || !IsPaused() || + timelineTime >= mPauseStart, "if paused, any non-null value of aTime must be at least" " mPauseStart"); + Nullable result; // Initializes to null - if (!aTime.IsNull()) { - result.SetValue((IsPaused() ? mPauseStart : aTime) - mStartTime); + if (!timelineTime.IsNull() && !mStartTime.IsNull()) { + result.SetValue((IsPaused() ? mPauseStart : timelineTime) - mStartTime); } return result; } diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index d25cbaed33b..6c0038908b0 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -31,21 +31,21 @@ nsAnimationManager::UpdateStyleAndEvents(ElementAnimationCollection* EnsureStyleRuleFlags aFlags) { aCollection->EnsureStyleRuleFor(aRefreshTime, aFlags); - GetEventsAt(aCollection, aRefreshTime, mPendingEvents); + GetEventsForCurrentTime(aCollection, mPendingEvents); CheckNeedsRefresh(); } void -nsAnimationManager::GetEventsAt(ElementAnimationCollection* aCollection, - TimeStamp aRefreshTime, - EventArray& aEventsToDispatch) +nsAnimationManager::GetEventsForCurrentTime(ElementAnimationCollection* + aCollection, + EventArray& aEventsToDispatch) { for (uint32_t animIdx = aCollection->mAnimations.Length(); animIdx-- != 0; ) { ElementAnimation* anim = aCollection->mAnimations[animIdx]; - Nullable localTime = anim->GetLocalTimeAt(aRefreshTime); ComputedTiming computedTiming = - ElementAnimation::GetComputedTimingAt(localTime, anim->mTiming); + ElementAnimation::GetComputedTimingAt(anim->GetLocalTime(), + anim->mTiming); switch (computedTiming.mPhase) { case ComputedTiming::AnimationPhase_Null: @@ -253,8 +253,6 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext, return nullptr; } - TimeStamp refreshTime = mPresContext->RefreshDriver()->MostRecentRefresh(); - if (collection) { collection->mStyleRule = nullptr; collection->mStyleRuleRefreshTime = TimeStamp(); @@ -306,7 +304,13 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext, } else { // Handle change in pause state by adjusting start // time to unpause. - newAnim->mStartTime += refreshTime - oldAnim->mPauseStart; + const TimeStamp& now = timeline->GetCurrentTimeStamp(); + if (!now.IsNull()) { + // FIXME: Once we store the start time and pause start as + // offsets (not timestamps) we should be able to update the + // start time to something more appropriate when now IsNull. + newAnim->mStartTime += now - oldAnim->mPauseStart; + } } } } @@ -318,6 +322,7 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext, collection->mAnimations.SwapElements(newAnimations); collection->mNeedsRefreshes = true; + TimeStamp refreshTime = mPresContext->RefreshDriver()->MostRecentRefresh(); UpdateStyleAndEvents(collection, refreshTime, EnsureStyleRule_IsNotThrottled); // We don't actually dispatch the mPendingEvents now. We'll either @@ -393,7 +398,8 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext, ResolvedStyleCache resolvedStyles; const nsStyleDisplay *disp = aStyleContext->StyleDisplay(); - TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh(); + TimeStamp now = aTimeline->GetCurrentTimeStamp(); + for (uint32_t animIdx = 0, animEnd = disp->mAnimationNameCount; animIdx != animEnd; ++animIdx) { const StyleAnimation& src = disp->mAnimations[animIdx]; diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index 7db0394d4d3..5a21b9095a2 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -79,9 +79,8 @@ public: void UpdateStyleAndEvents(mozilla::ElementAnimationCollection* aEA, mozilla::TimeStamp aRefreshTime, mozilla::EnsureStyleRuleFlags aFlags); - void GetEventsAt(mozilla::ElementAnimationCollection* aEA, - mozilla::TimeStamp aRefreshTime, - EventArray &aEventsToDispatch); + void GetEventsForCurrentTime(mozilla::ElementAnimationCollection* aEA, + EventArray &aEventsToDispatch); // nsIStyleRuleProcessor (parts) virtual void RulesMatching(ElementRuleProcessorData* aData) MOZ_OVERRIDE; diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index 8a292d7b8ea..c34ef50b1ba 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -37,7 +37,7 @@ using namespace mozilla::layers; using namespace mozilla::css; double -ElementPropertyTransition::ValuePortionFor(TimeStamp aRefreshTime) const +ElementPropertyTransition::CurrentValuePortion() const { // It would be easy enough to handle finished transitions by using a time // fraction of 1 but currently we should not be called for finished @@ -45,7 +45,7 @@ ElementPropertyTransition::ValuePortionFor(TimeStamp aRefreshTime) const MOZ_ASSERT(!IsFinishedTransition(), "Getting the value portion of a finished transition"); - Nullable localTime = GetLocalTimeAt(aRefreshTime); + Nullable localTime = GetLocalTime(); MOZ_ASSERT(!localTime.IsNull(), "Getting the value portion of an animation that's not being " "sampled"); @@ -491,9 +491,6 @@ nsTransitionManager::ConsiderStartingTransition( return; } - TimeStamp mostRecentRefresh = - presContext->RefreshDriver()->MostRecentRefresh(); - const nsTimingFunction &tf = aTransition.GetTimingFunction(); float delay = aTransition.GetDelay(); float duration = aTransition.GetDuration(); @@ -512,7 +509,7 @@ nsTransitionManager::ConsiderStartingTransition( // Compute the appropriate negative transition-delay such that right // now we'd end up at the current position. double valuePortion = - oldPT->ValuePortionFor(mostRecentRefresh) * oldPT->mReversePortion + + oldPT->CurrentValuePortion() * oldPT->mReversePortion + (1.0 - oldPT->mReversePortion); // A timing function with negative y1 (or y2!) might make // valuePortion negative. In this case, we still want to apply our @@ -553,7 +550,7 @@ nsTransitionManager::ConsiderStartingTransition( segment.mToKey = 1; segment.mTimingFunction.Init(tf); - pt->mStartTime = mostRecentRefresh; + pt->mStartTime = timeline->GetCurrentTimeStamp(); pt->mTiming.mIterationDuration = TimeDuration::FromMilliseconds(duration); pt->mTiming.mDelay = TimeDuration::FromMilliseconds(delay); pt->mTiming.mIterationCount = 1; @@ -823,7 +820,7 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags) collection->mAnimations.RemoveElementAt(i); } } else { - Nullable localTime = anim->GetLocalTimeAt(now); + Nullable localTime = anim->GetLocalTime(); ComputedTiming computedTiming = ElementAnimation::GetComputedTimingAt(localTime, anim->mTiming); if (computedTiming.mPhase == ComputedTiming::AnimationPhase_After) { diff --git a/layout/style/nsTransitionManager.h b/layout/style/nsTransitionManager.h index 2f37fc7f9c9..d66d4c9aa7d 100644 --- a/layout/style/nsTransitionManager.h +++ b/layout/style/nsTransitionManager.h @@ -54,9 +54,9 @@ struct ElementPropertyTransition : public mozilla::ElementAnimation double mReversePortion; // Compute the portion of the *value* space that we should be through - // at the given time. (The input to the transition timing function + // at the current time. (The input to the transition timing function // has time units, the output has value units.) - double ValuePortionFor(mozilla::TimeStamp aRefreshTime) const; + double CurrentValuePortion() const; }; } // namespace mozilla