From b44cf1b6af65bf238c3250fe3f09c5733b4db75a Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Mon, 24 Nov 2025 12:29:15 -0600 Subject: [PATCH] animation: Change how we seed the initial time With the addition of the weston_output_set_ready() call, the shell fade animation is now started during the very first repaint. The first repaint doesn't have an accurate frame_time for the previous repaint, as none has occurred yet. Since we set the time base for an animation based on the output's frame time the second time the animation is run, we end up setting the shell fade start time to 0, and the first real repaint advances the timer to the real time, generating a warning and truncating the animation. Instead of tracking the number of animation frames, let's just continue to reset the time base until we finally get a non-zero time. Signed-off-by: Derek Foreman --- include/libweston/libweston.h | 1 - libweston/animation.c | 15 +++++++++++++-- libweston/compositor.c | 4 +--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index 111d5ccab..b73397ee5 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -160,7 +160,6 @@ struct weston_animation { void (*frame)(struct weston_animation *animation, struct weston_output *output, const struct timespec *time); - int frame_counter; struct wl_list link; }; diff --git a/libweston/animation.c b/libweston/animation.c index 3d8cc7a20..020bb6fa8 100644 --- a/libweston/animation.c +++ b/libweston/animation.c @@ -199,7 +199,19 @@ weston_view_animation_frame(struct weston_animation *base, struct weston_compositor *compositor = animation->view->surface->compositor; - if (base->frame_counter <= 1) + /* Animations are created with timestamp 0, so we need to set a + * real time base on the first repaint. + * + * In some cases, such as when the repaint loop has just started + * for a new display, the time we're given could be 0 for our + * second call - but this is ok because weston_spring_update() will + * do nothing as long as spring.timestamp == time. + * + * We can safely just keep updating the timestamp until we get + * something non-zero, and the spring will start updating after + * that. + */ + if (!timespec_to_msec(&animation->spring.timestamp)) animation->spring.timestamp = *time; weston_spring_update(&animation->spring, time); @@ -275,7 +287,6 @@ weston_view_animation_run(struct weston_view_animation *animation) { struct timespec zero_time = { 0 }; - animation->animation.frame_counter = 0; weston_view_animation_frame(&animation->animation, NULL, &zero_time); } diff --git a/libweston/compositor.c b/libweston/compositor.c index b193a5650..9d99f8804 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -3737,10 +3737,8 @@ weston_output_repaint(struct weston_output *output) wl_resource_destroy(cb); } - wl_list_for_each_safe(animation, next, &output->animation_list, link) { - animation->frame_counter++; + wl_list_for_each_safe(animation, next, &output->animation_list, link) animation->frame(animation, output, &output->frame_time); - } weston_output_capture_info_repaint_done(output->capture_info);