From 047193a058a7c2e203cb2a75dbab36099220bf11 Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Wed, 28 Jan 2026 14:56:03 -0600 Subject: [PATCH] compositor: Add REPAINT_DEFERRED repaint_status Backends can end up in indeterminate/invalid state and be unable to process updates. Add a way for the backend to tell the core to stop scheduling repaints, and a way for the backend to schedule all the repaints that should have taken place during the invalid state period. Signed-off-by: Derek Foreman --- include/libweston/libweston.h | 4 ++++ libweston/backend.h | 6 ++++++ libweston/compositor.c | 39 ++++++++++++++++++++++++++++++++++ libweston/libweston-internal.h | 8 +++++++ 4 files changed, 57 insertions(+) diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index 5713a3e01..2c223c8f6 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -362,6 +362,10 @@ enum weston_repaint_status { REPAINT_BEGIN_FROM_IDLE, /**< start_repaint_loop scheduled */ REPAINT_SCHEDULED, /**< repaint is scheduled to occur */ REPAINT_AWAITING_COMPLETION, /**< last repaint not yet finished */ + /** Needs a repaint when the backend is ready. Backends must call + * weston_backend_clear_deferred() when ready. + */ + REPAINT_DEFERRED, }; /** Content producer for heads diff --git a/libweston/backend.h b/libweston/backend.h index 3c3194a8c..b9229ef81 100644 --- a/libweston/backend.h +++ b/libweston/backend.h @@ -134,6 +134,12 @@ struct weston_backend { * defined in weston_compositor_backend. */ enum weston_compositor_backend backend_type; + + /** The backend is incapable of painting right now, but will + * call weston_backend_clear_deferred() at some point to + * exit deferred state. + */ + bool deferred; }; /* weston_head */ diff --git a/libweston/compositor.c b/libweston/compositor.c index cbfb2cdac..159b8e602 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -4320,6 +4320,11 @@ weston_output_finish_frame(struct weston_output *output, else assert(presented_flags & WP_PRESENTATION_FEEDBACK_INVALID); + if (output->backend->deferred) { + output->repaint_status = REPAINT_DEFERRED; + return; + } + weston_compositor_read_presentation_clock(compositor, &now); /* If we haven't been supplied any timestamp at all, we don't have a @@ -4688,6 +4693,11 @@ weston_output_schedule_repaint(struct weston_output *output) if (output->repaint_status != REPAINT_NOT_SCHEDULED) return; + if (output->backend->deferred) { + output->repaint_status = REPAINT_DEFERRED; + return; + } + output->repaint_status = REPAINT_BEGIN_FROM_IDLE; assert(!output->idle_repaint_source); output->idle_repaint_source = wl_event_loop_add_idle(loop, idle_repaint, @@ -9412,6 +9422,8 @@ output_repaint_status_text(struct weston_output *output) return "repaint scheduled"; case REPAINT_AWAITING_COMPLETION: return "awaiting completion"; + case REPAINT_DEFERRED: + return "deferred"; } assert(!"output_repaint_status_text missing enum"); @@ -9750,6 +9762,8 @@ weston_compositor_print_scene_graph(struct weston_compositor *ec) fprintf(fp, "\tto be presented at: %" PRId64 ".%09ld\n", (int64_t)output->next_present.tv_sec, output->next_present.tv_nsec); + } else if (output->repaint_status == REPAINT_DEFERRED) { + fprintf(fp, "\tDeferred pending backend recovery\n"); } wl_list_for_each(head, &output->head_list, output_link) { fprintf(fp, "\tHead %d (%s): %sconnected\n", @@ -10920,3 +10934,28 @@ weston_output_set_ready(struct weston_output *output) weston_output_schedule_repaint(output); } } + +WL_EXPORT void +weston_backend_set_deferred(struct weston_backend *backend) +{ + backend->deferred = true; +} + +WL_EXPORT void +weston_backend_clear_deferred(struct weston_backend *backend, + struct weston_compositor *compositor) +{ + struct weston_output *output; + + backend->deferred = false; + + wl_list_for_each(output, &compositor->output_list, link) { + if (output->backend != backend) + continue; + if (output->repaint_status != REPAINT_DEFERRED) + continue; + + output->repaint_status = REPAINT_NOT_SCHEDULED; + weston_output_schedule_repaint(output); + } +} diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h index 7ff673a91..76aae065a 100644 --- a/libweston/libweston-internal.h +++ b/libweston/libweston-internal.h @@ -876,4 +876,12 @@ struct timespec weston_output_repaint_from_present(const struct weston_output *output, const struct timespec *now, const struct timespec *present_time); + +void +weston_backend_set_deferred(struct weston_backend *backend); + +void +weston_backend_clear_deferred(struct weston_backend *backend, + struct weston_compositor *compositor); + #endif