Skip to content

REGRESSION(294049@main): document.timeline.currentTime never advances #47359

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

graouts
Copy link
Contributor

@graouts graouts commented Jun 29, 2025

135c739

REGRESSION(294049@main): `document.timeline.currentTime` never advances
https://bugs.webkit.org/show_bug.cgi?id=295177
rdar://problem/154607696

Reviewed by NOBODY (OOPS!).

Prior to 294049@main, when the current time would be requested from `AnimationTimelinesController`,
most likely through `DocumentTimeline::currentTime()`, we would either use the cached current time,
if available, or compute a new one. In the case where we would compute a new one, we would also
enqueue a task (using `EventLoop::queueTask()`) to clear it after the current run loop had completed,
ensuring that any code ran within that loop would use the same current time.

That changed in 294049@main where we made it so that the document timeline's current time was cached
throughout the duration of the animation frame, matching the behavior of Chrome and Firefox. In effect,
this meant that that current time was updated every 16ms or so (assuming a display update cadence of 60Hz).

However, we neglected to preserve the mechanism to clear that cached current time, instead relying on
the fact that animations would cause animations to be updated and for that current time to be cached
as the page rendering updated at 60Hz.

When we cache the current time, we now clear it after a delay matching the page's preferred rendering
update interval.

We also add a test which checks that the document timeline's current time is correctly updated
after 20ms even with no page rendering updates scheduled. This test would have reliably failed
prior to this patch.

* LayoutTests/webanimations/document-timeline-current-time-updates-without-running-animations-expected.txt: Added.
* LayoutTests/webanimations/document-timeline-current-time-updates-without-running-animations.html: Added.
* Source/WebCore/animation/AnimationTimelinesController.cpp:
(WebCore::AnimationTimelinesController::AnimationTimelinesController):
(WebCore::AnimationTimelinesController::suspendAnimations):
(WebCore::AnimationTimelinesController::resumeAnimations):
(WebCore::AnimationTimelinesController::cacheCurrentTime):
(WebCore::AnimationTimelinesController::clearCachedCurrentTime):
* Source/WebCore/animation/AnimationTimelinesController.h:

135c739

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ⏳ 🧪 win-tests
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe
✅ 🧪 ios-wk2-wpt ✅ 🧪 mac-wk1 ✅ 🛠 wpe-cairo
✅ 🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk
✅ 🛠 vision ✅ 🧪 mac-AS-debug-wk2 ✅ 🧪 gtk-wk2
✅ 🛠 vision-sim ✅ 🧪 mac-wk2-stress ✅ 🧪 api-gtk
✅ 🧪 vision-wk2 ✅ 🧪 mac-intel-wk2 ✅ 🛠 playstation
✅ 🛠 tv ✅ 🛠 mac-safer-cpp
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

https://bugs.webkit.org/show_bug.cgi?id=295177
rdar://problem/154607696

Reviewed by NOBODY (OOPS!).

Prior to 294049@main, when the current time would be requested from `AnimationTimelinesController`,
most likely through `DocumentTimeline::currentTime()`, we would either use the cached current time,
if available, or compute a new one. In the case where we would compute a new one, we would also
enqueue a task (using `EventLoop::queueTask()`) to clear it after the current run loop had completed,
ensuring that any code ran within that loop would use the same current time.

That changed in 294049@main where we made it so that the document timeline's current time was cached
throughout the duration of the animation frame, matching the behavior of Chrome and Firefox. In effect,
this meant that that current time was updated every 16ms or so (assuming a display update cadence of 60Hz).

However, we neglected to preserve the mechanism to clear that cached current time, instead relying on
the fact that animations would cause animations to be updated and for that current time to be cached
as the page rendering updated at 60Hz.

When we cache the current time, we now clear it after a delay matching the page's preferred rendering
update interval.

We also add a test which checks that the document timeline's current time is correctly updated
after 20ms even with no page rendering updates scheduled. This test would have reliably failed
prior to this patch.

* LayoutTests/webanimations/document-timeline-current-time-updates-without-running-animations-expected.txt: Added.
* LayoutTests/webanimations/document-timeline-current-time-updates-without-running-animations.html: Added.
* Source/WebCore/animation/AnimationTimelinesController.cpp:
(WebCore::AnimationTimelinesController::AnimationTimelinesController):
(WebCore::AnimationTimelinesController::suspendAnimations):
(WebCore::AnimationTimelinesController::resumeAnimations):
(WebCore::AnimationTimelinesController::cacheCurrentTime):
(WebCore::AnimationTimelinesController::clearCachedCurrentTime):
* Source/WebCore/animation/AnimationTimelinesController.h:
@graouts graouts self-assigned this Jun 29, 2025
@graouts graouts added the Animations Bugs related to CSS + SVG animations and transitions label Jun 29, 2025
@graouts graouts requested review from smfr, heycam and alanbaradlay June 29, 2025 23:41
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jun 30, 2025
@Ahmad-S792 Ahmad-S792 removed the merging-blocked Applied to prevent a change from being merged label Jun 30, 2025

// Now wait longer than it should take for a page rendering update to last
// and check that the current time has changed to a larger value.
await timeout(20);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think might be flakey on loaded machines. Do you have to wait but explicitly not run Page::updateRendering? There's normally a flurry of those around page load that are hard to avoid, so if you really want to wait for idle, you may need to wait for 4-5 updateRenderings before starting the test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test reliably fails for me prior to this patch. I also expect setTimeout(…, 20) to always run after a WebCore Timer set for 16_ms if both are generally started in the same run loop.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, running this test with -f -1 produces some failures across 5000 runs. It's not happening with just -f with WK2.

// In order to not have a stale cached current time, we schedule a timer to reset it
// in the time it would take an animation frame to run under normal circumstances.
ASSERT(m_document->page());
m_cachedCurrentTimeClearanceTimer.startOneShot(RefPtr { m_document->page() }->preferredRenderingUpdateInterval());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to explicitly clear the cached time in Page::doAfterUpdateRendering()? This seems like it could be flaky.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the cached current time must remain cached until the next page rendering update.

@graouts graouts requested a review from smfr June 30, 2025 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Animations Bugs related to CSS + SVG animations and transitions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants