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

Reply via email to