diff --git a/libweston/backend-pipewire/pipewire.c b/libweston/backend-pipewire/pipewire.c index 01a9a1de..61e98516 100644 --- a/libweston/backend-pipewire/pipewire.c +++ b/libweston/backend-pipewire/pipewire.c @@ -739,24 +739,6 @@ pipewire_submit_buffer(struct pipewire_output *output, output->seq++; } -static void -pipewire_output_arm_timer(struct pipewire_output *output) -{ - struct weston_compositor *ec = output->base.compositor; - struct timespec now; - struct timespec target; - int refresh_nsec = millihz_to_nsec(output->base.current_mode->refresh); - int64_t delay_nsec; - - weston_compositor_read_presentation_clock(ec, &now); - timespec_add_nsec(&target, &output->base.frame_time, refresh_nsec); - - delay_nsec = CLIP(timespec_sub_to_nsec(&target, &now), 1, refresh_nsec); - - wl_event_source_timer_update(output->finish_frame_timer, - DIV_ROUND_UP(delay_nsec, 1000000)); -} - static int pipewire_output_repaint(struct weston_output *base, pixman_region32_t *damage) { @@ -787,7 +769,7 @@ pipewire_output_repaint(struct weston_output *base, pixman_region32_t *damage) out: - pipewire_output_arm_timer(output); + weston_output_arm_frame_timer(base, output->finish_frame_timer); return 0; } diff --git a/libweston/backend.h b/libweston/backend.h index 4bb430b6..da295b1c 100644 --- a/libweston/backend.h +++ b/libweston/backend.h @@ -194,6 +194,10 @@ weston_region_global_to_output(pixman_region32_t *dst, const struct weston_hdr_metadata_type1 * weston_output_get_hdr_metadata_type1(const struct weston_output *output); +void +weston_output_arm_frame_timer(struct weston_output *output, + struct wl_event_source *frame_timer); + /* weston_seat */ void diff --git a/libweston/compositor.c b/libweston/compositor.c index 5f60251b..81466a11 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -9736,3 +9736,31 @@ weston_renderer_resize_output(struct weston_output *output, output->name); } } + +/** Queue a frame timer callback + * + * \param output The output to queue a frame timer callback for. + * \param frame_timer The timer that calls weston_output_finish_frame(). + * + * This function calculates the time when the current frame should be completed + * such that frames are spaced out evenly by the specified refresh rate. + */ +WL_EXPORT void +weston_output_arm_frame_timer(struct weston_output *output, + struct wl_event_source *frame_timer) +{ + struct weston_compositor *ec = output->compositor; + struct timespec now; + struct timespec target; + int refresh_nsec = millihz_to_nsec(output->current_mode->refresh); + int64_t delay_nsec; + + weston_compositor_read_presentation_clock(ec, &now); + timespec_add_nsec(&target, &output->frame_time, refresh_nsec); + + delay_nsec = CLIP(timespec_sub_to_nsec(&target, &now), 1, refresh_nsec); + + /* The libwayland event source timer API only has msec precision. */ + wl_event_source_timer_update(frame_timer, + DIV_ROUND_UP(delay_nsec, 1000000)); +}