Created attachment 421811 [details] Test I am filing this bug based on a report made in the Apple Developer Forums at https://developer.apple.com/forums/thread/674449. The post has a test which is attached to this bug. I have managed to regress this to r272004.
<rdar://problem/74865413>
Created attachment 421827 [details] Test
The new test shows the issue is that the scale that is applied during the initial transition is applied as an additional translate while the second transition is in its delay phase, which is made extremely long.
The CADebug output shows we have two animations during the second transition's delay phase: (keyframe-animation (beginTime 108545.905575) (duration 2.000000) (fillMode both) (repeatCount 1.000000) (additive true) (removedOnCompletion false) (keyPath transform) (calculationMode linear) (values (array (vector 3 0 0 0 0 3 0 0 0 0 1 0 0 0 0 1) (vector 0.6000000238 0 0 0 0 0.6000000238 0 0 0 0 1 0 -1232.400024 0 0 1))) (keyTimes (vector 0 1)) (timingFunctions (vector 0.25 0.1000000015 0.25 1))) (basic-animation (beginTime 8545.905575) (duration 100000.000000) (additive true) (keyPath transform) (from (vector 3 0 0 0 0 3 0 0 0 0 1 0 0 0 0 1)) (to (vector 3 0 0 0 0 3 0 0 0 0 1 0 0 0 0 1))))))))))))))))))))))))))))) CA additive animations are applied in reverse order, so the keyframe-animation is the second transition, and since it has fillMode = "both" it applies on top of the basic-animation. In this case we shouldn't have the basic-animation at all since the transitions has explicit keyframes.
I think the fix here is to not generate a non-interpolating "base" animation if the first interpolating animation in the stack for this transform-related property fills backwards.
Created attachment 421834 [details] Patch
Committed r273656 (234696@main): <https://commits.webkit.org/234696@main>
Comment on attachment 421834 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=421834&action=review > Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp:3134 > + // If we have an animation with an explicit begin time that does not fill backwards and starts with a delay, > + // we must create a non-interpolating animation to set the current value for this transform-related property > + // until that animation begins. > + if (earliestAnimation) { > + auto fillMode = earliestAnimation->m_animation->fillMode(); > + if (fillMode != PlatformCAAnimation::Backwards && fillMode != PlatformCAAnimation::Both) { > + Seconds earliestBeginTime = *earliestAnimation->computedBeginTime() + animationGroupBeginTime; > + if (earliestBeginTime > currentTime) { > + if (auto* baseValueTransformAnimation = makeBaseValueTransformAnimation(property, TransformationMatrixSource::AskClient, earliestBeginTime)) { > + prepareAnimationForAddition(*baseValueTransformAnimation); > + caAnimations.append(baseValueTransformAnimation->m_animation); > + } > + } If this is identical to the block above you should share it.
(In reply to Simon Fraser (smfr) from comment #8) > Comment on attachment 421834 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=421834&action=review > > > Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp:3134 > > + // If we have an animation with an explicit begin time that does not fill backwards and starts with a delay, > > + // we must create a non-interpolating animation to set the current value for this transform-related property > > + // until that animation begins. > > + if (earliestAnimation) { > > + auto fillMode = earliestAnimation->m_animation->fillMode(); > > + if (fillMode != PlatformCAAnimation::Backwards && fillMode != PlatformCAAnimation::Both) { > > + Seconds earliestBeginTime = *earliestAnimation->computedBeginTime() + animationGroupBeginTime; > > + if (earliestBeginTime > currentTime) { > > + if (auto* baseValueTransformAnimation = makeBaseValueTransformAnimation(property, TransformationMatrixSource::AskClient, earliestBeginTime)) { > > + prepareAnimationForAddition(*baseValueTransformAnimation); > > + caAnimations.append(baseValueTransformAnimation->m_animation); > > + } > > + } > > If this is identical to the block above you should share it. That whole IFDEF is going away Real Soon Now, so I didn't really bother too much.