From 1b8a2e6d1c30f3c25df6df871801649af50e8553 Mon Sep 17 00:00:00 2001 From: "David Zbarsky ext:(%2C%20David%20Baron%20%3Cdbaron%40dbaron.org%3E%2C%20Chris%20Jones%20%3Cjones.chris.g%40gmail.com%3E)" Date: Thu, 22 Nov 2012 15:49:06 -0800 Subject: [PATCH] Bug 788409: When the compositor runs past the end of an animation, just fill forwards until the main thread catches up. r=dbaron a=blocking-basecamp --- gfx/layers/ipc/CompositorParent.cpp | 6 ---- layout/style/nsAnimationManager.cpp | 45 +++++++++++++++-------------- layout/style/nsAnimationManager.h | 4 ++- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 5623c48cc3a..f6c8698d2ec 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -720,12 +720,6 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint) numIterations, animation.direction()); - if (positionInIteration == -1) { - animations.RemoveElementAt(i); - animationData.RemoveElementAt(i); - continue; - } - NS_ABORT_IF_FALSE(0.0 <= positionInIteration && positionInIteration <= 1.0, "position should be in [0-1]"); diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index 7d45b82bfbe..a9110587ecb 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -54,29 +54,32 @@ ElementAnimations::GetPositionInIteration(TimeStamp aStartTime, TimeStamp aCurre currentTimeDuration / aDuration; bool dispatchStartOrIteration = false; if (currentIterationCount >= aIterationCount) { - if (!aAnimation) { - // We are on the compositor, so send a signal that the animation is over. - // The main thread will fire the animationend event. - return -1; - } - // Dispatch 'animationend' when needed. - if (aIsForElement && - aAnimation->mLastNotification != - ElementAnimation::LAST_NOTIFICATION_END) { - aAnimation->mLastNotification = ElementAnimation::LAST_NOTIFICATION_END; - // XXXdz: if this animation was done on the compositor, we should - // invalidate the frame and update style once we start throttling style - // updates. - AnimationEventInfo ei(aEa->mElement, aAnimation->mName, NS_ANIMATION_END, - currentTimeDuration); - aEventsToDispatch->AppendElement(ei); - } + if (aAnimation) { + // Dispatch 'animationend' when needed. + if (aIsForElement && + aAnimation->mLastNotification != + ElementAnimation::LAST_NOTIFICATION_END) { + aAnimation->mLastNotification = ElementAnimation::LAST_NOTIFICATION_END; + // XXXdz: if this animation was done on the compositor, we should + // invalidate the frame and update style once we start throttling style + // updates. + AnimationEventInfo ei(aEa->mElement, aAnimation->mName, NS_ANIMATION_END, + currentTimeDuration); + aEventsToDispatch->AppendElement(ei); + } - if (!aAnimation->FillsForwards()) { - // No animation data. - return -1; + if (!aAnimation->FillsForwards()) { + // No animation data. + return -1; + } + } else { + // If aAnimation is null, that means we're on the compositor + // thread. We want to just keep filling forwards until the main + // thread gets around to updating the compositor thread (which + // might take a little while). So just assume we fill fowards and + // move on. } - currentIterationCount = double(aAnimation->mIterationCount); + currentIterationCount = aIterationCount; } else { if (aAnimation && !aAnimation->IsPaused()) { aEa->mNeedsRefreshes = true; diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index 88da7215e77..330689d86dd 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -128,7 +128,9 @@ struct ElementAnimations : public mozilla::css::CommonElementAnimationData // from the main thread, we need the actual ElementAnimation* in order to // get correct animation-fill behavior and to fire animation events. // This function returns -1 for the position if the animation should not be - // run (because it is not currently active and has no fill behavior.) + // run (because it is not currently active and has no fill behavior), but + // only does so if aAnimation is non-null; with a null aAnimation it is an + // error to give aCurrentTime < aStartTime, and fill-forwards is assumed. static double GetPositionInIteration(TimeStamp aStartTime, TimeStamp aCurrentTime, TimeDuration aDuration,