Animation: update image active frame when update the rendering (#36286)

When no CSS animation exist, register timer for image animation, update
animated image active image frame as part of update_the_rendering, mark
node as dirty if the corresponding image need update. Added unit test to
test ImageAnimationState.

Part of https://github.com/servo/servo/issues/36057, the last step to
let the Animated Image "Move".

Testing: Introduced new WPT RefTest for animated image, but fail because
of https://github.com/servo/servo/issues/36931. New unit test for
`ImageAnimationState`.
Fixes: https://github.com/servo/servo/issues/22903
https://github.com/servo/servo/issues/36057

[Try](1472472966)

---------

Signed-off-by: rayguo17 <rayguo17@gmail.com>
This commit is contained in:
TIN TUN AUNG 2025-05-23 11:13:35 +08:00 committed by GitHub
parent 2353c0089f
commit 23ce7b31ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 313 additions and 8 deletions

View file

@ -5051,6 +5051,35 @@ impl Document {
self.image_animation_manager.borrow_mut()
}
pub(crate) fn update_animating_images(&self) {
let mut image_animation_manager = self.image_animation_manager.borrow_mut();
if !image_animation_manager.image_animations_present() {
return;
}
image_animation_manager
.update_active_frames(&self.window, self.current_animation_timeline_value());
if !self.animations().animations_present() {
let next_scheduled_time =
image_animation_manager.next_schedule_time(self.current_animation_timeline_value());
// TODO: Once we have refresh signal from the compositor,
// we should get rid of timer for animated image update.
if let Some(next_scheduled_time) = next_scheduled_time {
self.schedule_image_animation_update(next_scheduled_time);
}
}
}
fn schedule_image_animation_update(&self, next_scheduled_time: f64) {
let callback = ImageAnimationUpdateCallback {
document: Trusted::new(self),
};
self.global().schedule_callback(
OneshotTimerCallback::ImageAnimationUpdate(callback),
Duration::from_secs_f64(next_scheduled_time),
);
}
/// <https://html.spec.whatwg.org/multipage/#shared-declarative-refresh-steps>
pub(crate) fn shared_declarative_refresh_steps(&self, content: &[u8]) {
// 1. If document's will declaratively refresh is true, then return.
@ -6747,6 +6776,21 @@ impl FakeRequestAnimationFrameCallback {
}
}
/// This is a temporary workaround to update animated images,
/// we should get rid of this after we have refresh driver #3406
#[derive(JSTraceable, MallocSizeOf)]
pub(crate) struct ImageAnimationUpdateCallback {
/// The document.
#[ignore_malloc_size_of = "non-owning"]
document: Trusted<Document>,
}
impl ImageAnimationUpdateCallback {
pub(crate) fn invoke(self, can_gc: CanGc) {
with_script_thread(|script_thread| script_thread.update_the_rendering(true, can_gc))
}
}
#[derive(JSTraceable, MallocSizeOf)]
pub(crate) enum AnimationFrameCallback {
DevtoolsFramerateTick {