Skip to content

Commit

Permalink
LibWeb: Generate correct timestamp values when updating animations
Browse files Browse the repository at this point in the history
Previously, we were generating timestamps relative to the current time
of the monotonic clock. We now generate timestamps relative to the
event loop's last render opportunity time, per the spec.
  • Loading branch information
tcl3 authored and Lubrsi committed Jan 28, 2025
1 parent 5372d07 commit 8b5a25e
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 7 deletions.
8 changes: 4 additions & 4 deletions Libraries/LibWeb/Animations/DocumentTimeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/HighResolutionTime/Performance.h>
#include <LibWeb/HighResolutionTime/TimeOrigin.h>
#include <LibWeb/WebIDL/ExceptionOr.h>

namespace Web::Animations {
Expand All @@ -22,10 +23,9 @@ GC::Ref<DocumentTimeline> DocumentTimeline::create(JS::Realm& realm, DOM::Docume
auto timeline = realm.create<DocumentTimeline>(realm, document, origin_time);
auto current_time = document.last_animation_frame_timestamp();
if (!current_time.has_value()) {
// The document hasn't processed an animation frame yet, so just use the exact current time
auto* window_or_worker = dynamic_cast<HTML::WindowOrWorkerGlobalScopeMixin*>(&realm.global_object());
VERIFY(window_or_worker);
current_time = window_or_worker->performance()->now();
// The document hasn't processed an animation frame yet, we use the navigation start time, which is either the time
// that the previous document started to be unloaded or the creation time of the current document.
current_time = HighResolutionTime::relative_high_resolution_time(document.load_timing_info().navigation_start_time, realm.global_object());
}
timeline->set_current_time(current_time);
return timeline;
Expand Down
8 changes: 5 additions & 3 deletions Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ void EventLoop::update_the_rendering()
m_is_running_rendering_task = false;
};

// FIXME: 1. Let frameTimestamp be eventLoop's last render opportunity time.
// 1. Let frameTimestamp be eventLoop's last render opportunity time.
auto frame_timestamp = m_last_render_opportunity_time;

// FIXME: 2. Let docs be all fully active Document objects whose relevant agent's event loop is eventLoop, sorted arbitrarily except that the following conditions must be met:
// 3. Filter non-renderable documents: Remove from docs any Document object doc for which any of the following are true:
Expand Down Expand Up @@ -313,16 +314,16 @@ void EventLoop::update_the_rendering()

// 11. For each doc of docs, update animations and send events for doc, passing in relative high resolution time given frameTimestamp and doc's relevant global object as the timestamp [WEBANIMATIONS]
for (auto& document : docs) {
document->update_animations_and_send_events(document->window()->performance()->now());
document->update_animations_and_send_events(HighResolutionTime::relative_high_resolution_time(frame_timestamp, relevant_global_object(*document)));
};

// FIXME: 12. For each doc of docs, run the fullscreen steps for doc. [FULLSCREEN]

// FIXME: 13. For each doc of docs, if the user agent detects that the backing storage associated with a CanvasRenderingContext2D or an OffscreenCanvasRenderingContext2D, context, has been lost, then it must run the context lost steps for each such context:

// 14. For each doc of docs, run the animation frame callbacks for doc, passing in the relative high resolution time given frameTimestamp and doc's relevant global object as the timestamp.
auto now = HighResolutionTime::unsafe_shared_current_time();
for (auto& document : docs) {
auto now = HighResolutionTime::relative_high_resolution_time(frame_timestamp, relevant_global_object(*document));
run_animation_frame_callbacks(*document, now);
}

Expand Down Expand Up @@ -398,6 +399,7 @@ void EventLoop::update_the_rendering()

// 19. For each doc of docs, run the update intersection observations steps for doc, passing in the relative high resolution time given now and doc's relevant global object as the timestamp. [INTERSECTIONOBSERVER]
for (auto& document : docs) {
auto now = HighResolutionTime::relative_high_resolution_time(frame_timestamp, relevant_global_object(*document));
document->run_the_update_intersection_observations_steps(now);
}

Expand Down

0 comments on commit 8b5a25e

Please sign in to comment.