diff --git a/gfx/layers/AnimationHelper.cpp b/gfx/layers/AnimationHelper.cpp index 45cca831fb7b..1a1af906da61 100644 --- a/gfx/layers/AnimationHelper.cpp +++ b/gfx/layers/AnimationHelper.cpp @@ -148,7 +148,8 @@ CompositorAnimationStorage::SetAnimations(uint64_t aId, const AnimationArray& aV AnimationHelper::SampleResult AnimationHelper::SampleAnimationForEachNode( - TimeStamp aTime, + TimeStamp aPreviousFrameTime, + TimeStamp aCurrentFrameTime, AnimationArray& aAnimations, InfallibleTArray& aAnimationData, RefPtr& aAnimationValue) @@ -175,13 +176,23 @@ AnimationHelper::SampleAnimationForEachNode( animation.isNotPlaying(), "If we are playing, we should have an origin time and a start" " time"); + + // Use a previous vsync time to make main thread animations and compositor + // more in sync with each other. + // On the initial frame we use the current frame time here so the timestamp + // on the second frame are the same as the initial frame, but it does not + // matter. + const TimeStamp& timeStamp = !aPreviousFrameTime.IsNull() + ? aPreviousFrameTime + : aCurrentFrameTime; + // If the animation is not currently playing, e.g. paused or // finished, then use the hold time to stay at the same position. TimeDuration elapsedDuration = animation.isNotPlaying() || animation.startTime().type() != MaybeTimeDuration::TTimeDuration ? animation.holdTime() - : (aTime - animation.originTime() - + : (timeStamp - animation.originTime() - animation.startTime().get_TimeDuration()) .MultDouble(animation.playbackRate()); @@ -571,7 +582,8 @@ AnimationHelper::GetNextCompositorAnimationsId() void AnimationHelper::SampleAnimations(CompositorAnimationStorage* aStorage, - TimeStamp aTime) + TimeStamp aPreviousFrameTime, + TimeStamp aCurrentFrameTime) { MOZ_ASSERT(aStorage); @@ -594,7 +606,8 @@ AnimationHelper::SampleAnimations(CompositorAnimationStorage* aStorage, animationData, animationValue); AnimationHelper::SampleResult sampleResult = - AnimationHelper::SampleAnimationForEachNode(aTime, + AnimationHelper::SampleAnimationForEachNode(aPreviousFrameTime, + aCurrentFrameTime, *animations, animationData, animationValue); diff --git a/gfx/layers/AnimationHelper.h b/gfx/layers/AnimationHelper.h index f5f410b60e37..6e57231ea0fd 100644 --- a/gfx/layers/AnimationHelper.h +++ b/gfx/layers/AnimationHelper.h @@ -214,6 +214,9 @@ public: /** * Sample animations based on a given time stamp for a element(layer) with * its animation data. + * Generally |aPreviousFrameTimeStamp| is used for the sampling if it's + * supplied to make the animation more in sync with other animations on the + * main-thread. * * Returns SampleResult::None if none of the animations are producing a result * (e.g. they are in the delay phase with no backwards fill), @@ -222,7 +225,8 @@ public: * SampleResult::Sampled if the animation output was updated. */ static SampleResult - SampleAnimationForEachNode(TimeStamp aTime, + SampleAnimationForEachNode(TimeStamp aPreviousFrameTime, + TimeStamp aCurrentFrameTime, AnimationArray& aAnimations, InfallibleTArray& aAnimationData, RefPtr& aAnimationValue); @@ -251,7 +255,8 @@ public: */ static void SampleAnimations(CompositorAnimationStorage* aStorage, - TimeStamp aTime); + TimeStamp aPreviousFrameTime, + TimeStamp aCurrentFrameTime); }; } // namespace layers diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index c54f2d304250..d0019ffcfe53 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -673,7 +673,8 @@ ApplyAnimatedValue(Layer* aLayer, static bool SampleAnimations(Layer* aLayer, CompositorAnimationStorage* aStorage, - TimeStamp aTime) + TimeStamp aPreviousFrameTime, + TimeStamp aCurrentFrameTime) { bool isAnimating = false; @@ -689,7 +690,8 @@ SampleAnimations(Layer* aLayer, RefPtr animationValue = layer->GetBaseAnimationStyle(); AnimationHelper::SampleResult sampleResult = - AnimationHelper::SampleAnimationForEachNode(aTime, + AnimationHelper::SampleAnimationForEachNode(aPreviousFrameTime, + aCurrentFrameTime, animations, layer->GetAnimationData(), animationValue); @@ -1259,15 +1261,11 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame, // First, compute and set the shadow transforms from OMT animations. // NB: we must sample animations *before* sampling pan/zoom // transforms. - // Use a previous vsync time to make main thread animations and compositor - // more in sync with each other. - // On the initial frame we use aVsyncTimestamp here so the timestamp on the - // second frame are the same as the initial frame, but it does not matter. bool wantNextFrame = SampleAnimations(root, storage, - !mPreviousFrameTimeStamp.IsNull() ? - mPreviousFrameTimeStamp : aCurrentFrame); + mPreviousFrameTimeStamp, + aCurrentFrame); if (!wantNextFrame) { // Clean up the CompositorAnimationStorage because diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index 0d592b758efb..1daabb1ce50a 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -1222,18 +1222,17 @@ WebRenderBridgeParent::AdvanceAnimations() // refresh mode, on the testing mode animations on the compositor are // synchronously composed, so we don't need to worry about the time gap // between the main thread and compositor thread. - AnimationHelper::SampleAnimations(mAnimStorage, *testingTimeStamp); + AnimationHelper::SampleAnimations(mAnimStorage, + *testingTimeStamp, + *testingTimeStamp); return; } } TimeStamp lastComposeTime = mCompositorScheduler->GetLastComposeTime(); - // if we have already mPreviousTimeStamp, use it since on the compositor the - // time in the previous tick is more closer to the main-thread tick time. AnimationHelper::SampleAnimations(mAnimStorage, - !mPreviousFrameTimeStamp.IsNull() - ? mPreviousFrameTimeStamp - : lastComposeTime); + mPreviousFrameTimeStamp, + lastComposeTime); // Reset the previous time stamp if we don't already have any running // animations to avoid using the time which is far behind for newly