Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 483c60c629b8394400c134b686ec549c1cf2c0f5
https://github.com/WebKit/WebKit/commit/483c60c629b8394400c134b686ec549c1cf2c0f5
Author: Antoine Quint <[email protected]>
Date: 2025-04-23 (Wed, 23 Apr 2025)
Changed paths:
M LayoutTests/TestExpectations
M LayoutTests/compositing/backing/backface-visibility-flip-expected.txt
M LayoutTests/compositing/backing/backface-visibility-flip.html
M
LayoutTests/compositing/backing/backing-store-attachment-empty-keyframe.html
M LayoutTests/compositing/backing/transition-extent-expected.txt
M LayoutTests/compositing/backing/transition-extent.html
M LayoutTests/compositing/layer-creation/overlap-animation-clipping.html
M LayoutTests/compositing/layer-creation/overlap-animation-container.html
M LayoutTests/compositing/layer-creation/overlap-animation-expected.txt
M LayoutTests/compositing/layer-creation/overlap-animation.html
M
LayoutTests/imported/w3c/web-platform-tests/web-animations/timing-model/animations/setting-the-start-time-of-an-animation-expected.txt
M
LayoutTests/imported/w3c/web-platform-tests/web-animations/timing-model/animations/setting-the-start-time-of-an-animation.html
M
LayoutTests/platform/ios/compositing/backing/transition-extent-expected.txt
M
LayoutTests/platform/mac/compositing/visible-rect/animated-from-none-expected.txt
M
LayoutTests/webanimations/css-transition-retargeting-to-same-value-upon-completion-with-timeout.html
M LayoutTests/webanimations/custom-effect/custom-effect.html
M LayoutTests/webanimations/offset-anchor-animation-yields-compositing.html
M
LayoutTests/webanimations/offset-distance-animation-yields-compositing.html
M Source/WebCore/animation/AnimationTimeline.cpp
M Source/WebCore/animation/AnimationTimelinesController.cpp
M Source/WebCore/animation/AnimationTimelinesController.h
M Source/WebCore/animation/DocumentTimeline.cpp
M Source/WebCore/animation/WebAnimation.cpp
M Source/WebCore/animation/WebAnimation.h
Log Message:
-----------
[web-animations] start time of animations created during a page rendering
update should match that update's timeline time
https://bugs.webkit.org/show_bug.cgi?id=290993
rdar://138844796
Reviewed by Dean Jackson.
WebKit differs from Chrome and Firefox when setting the start time of animations
created during a page rendering update.
In WebKit, we mark any animation that is pending as ready when we run the
"update
animations and send events" [0] step, which means that all animations pending at
this point will share the same start time and will also have a current time of 0
when the ready promise is resolved.
In Chrome and Firefox, animations created during a page rendering update will
have
their start time set to the timeline time of that same update, even though their
ready promise may be resolved at a later time, for instance during the next page
rendering update. This means that the current time of animations will likely not
be 0 when the ready promise is resolved.
This is particularly visible for CSS-originated animations which may be created
during a page rendering update as styles are recalculated and layout is updated
a few steps after animations are updated. As such, WebKit typically is one
rendering
frame behind Chrome and Firefox when dealing with CSS Transitions and CSS
Animations.
This behavior is not actually a spec violation since the start time and time
where
the ready promise is resolved is left as implementation-dependent [1].
However, this is proving to be a web compatibility issue since we found that
captions
may flicker on YouTube for instance, and this is due to the behavior described
above.
In fact, for CSS Transitions, we introduced some ad-hoc current time
computation code
in 226359@main and 226577@main to deal with some compatibility issues (which we
will
remove in a followup to this patch).
In light of this further web compatibility issue, we change how we determine
the start
time of animations to align with Chrome and Firefox.
When we cache the current time during a page rendering update, we enqueue a
task in
`AnimationTimelinesController::cacheCurrentTime()` to run once page rendering
update
is done. Any animation that is created in this interval is added to a list of
pending
animations, and when our queued that task is performed we set the "pending
start time"
of those pending animations.
Then during the next page rendering update, as `WebAnimation::tick()` is
called, we
check whether we have a "pending start time" and use that time to be the
animation's
committed start time.
This now means that any animation created during a page rendering update,
including
`requestAnimationFrame()` callbacks and code responding to animation events,
will
have its pending start time set to the timeline time used for that page
rendering
update. During the _next_ page rendering update, those animations will be
marked as
"ready" and their start time will be set to the recorded pending start time.
If an animation was created any time after the page rendering update steps had
completed, for instance in a `setTimeout()` call within a
`requestAnimationFrame()`
callback, that animation will have its start time set to match the next page
rendering
update and will be marked as ready during the following page rendering update.
This behavior is now tested with an additional subtest in the existing WPT test
`web-animations/timing-model/animations/setting-the-start-time-of-an-animation.html`.
While that behavior isn't technically normative, as noted above, it seems like
important
enough for Web compatibility that it should be part of the WPT suite.
The subtle changes in timing required some adaptation of WebKit-specific tests.
For the
compositing tests, because animations and transitions start a frame sooner, we
had to update
those tests to have an animation transform in the output and to make sure the
animations were
longer to yield a stable animated first frame in the output.
[0] https://drafts.csswg.org/web-animations-1/#update-animations-and-send-events
[1] https://drafts.csswg.org/web-animations-1/#waiting-for-the-associated-effect
* LayoutTests/compositing/backing/backface-visibility-flip-expected.txt:
* LayoutTests/compositing/backing/backface-visibility-flip.html:
* LayoutTests/compositing/backing/backing-store-attachment-empty-keyframe.html:
* LayoutTests/compositing/backing/transition-extent-expected.txt:
* LayoutTests/compositing/backing/transition-extent.html:
* LayoutTests/compositing/layer-creation/overlap-animation-clipping.html:
* LayoutTests/compositing/layer-creation/overlap-animation-container.html:
* LayoutTests/compositing/layer-creation/overlap-animation-expected.txt:
* LayoutTests/compositing/layer-creation/overlap-animation.html:
*
LayoutTests/imported/w3c/web-platform-tests/web-animations/timing-model/animations/setting-the-start-time-of-an-animation-expected.txt:
*
LayoutTests/imported/w3c/web-platform-tests/web-animations/timing-model/animations/setting-the-start-time-of-an-animation.html:
* LayoutTests/platform/ios/compositing/backing/transition-extent-expected.txt:
*
LayoutTests/platform/mac/compositing/visible-rect/animated-from-none-expected.txt:
*
LayoutTests/webanimations/css-transition-retargeting-to-same-value-upon-completion-with-timeout.html:
* LayoutTests/webanimations/custom-effect/custom-effect.html:
* LayoutTests/webanimations/offset-anchor-animation-yields-compositing.html:
* LayoutTests/webanimations/offset-distance-animation-yields-compositing.html:
* Source/WebCore/animation/AnimationTimeline.cpp:
(WebCore::AnimationTimeline::animationTimingDidChange):
* Source/WebCore/animation/AnimationTimelinesController.cpp:
(WebCore::AnimationTimelinesController::detachFromDocument):
(WebCore::AnimationTimelinesController::addPendingAnimation):
(WebCore::AnimationTimelinesController::cacheCurrentTime):
(WebCore::AnimationTimelinesController::processPendingAnimations):
(WebCore::AnimationTimelinesController::maybeClearCachedCurrentTime): Deleted.
* Source/WebCore/animation/AnimationTimelinesController.h:
* Source/WebCore/animation/DocumentTimeline.cpp:
(WebCore::DocumentTimeline::removeReplacedAnimations): Use the live current
time instead
of the cached current time so that we can guarantee that "remove" events are
dispatched
after "finish" events for the same animation.
* Source/WebCore/animation/WebAnimation.cpp:
(WebCore::WebAnimation::runPendingPlayTask): use the "pending start time" if
set.
(WebCore::WebAnimation::runPendingPauseTask): use the "pending start time" if
set.
(WebCore::WebAnimation::tick):
(WebCore::WebAnimation::maybeMarkAsReady): move "ready" logic into a dedicated
method.
* Source/WebCore/animation/WebAnimation.h:
(WebCore::WebAnimation::setPendingStartTime):
Canonical link: https://commits.webkit.org/294049@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes