From 6caeba699d883669e260a3781f56c29a9316d914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Molinari?= Date: Tue, 20 Feb 2024 15:44:07 +0100 Subject: [PATCH] backend-headless: Add support for custom refresh rates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Custom headless refresh rates can be useful to instrument clients matching different screen configurations. This commit adds support for that to the headless backend and exposes it to the frontend with the "--refresh-rate" CLI option. The default refresh value is still 60 Hz. Signed-off-by: Loïc Molinari --- frontend/main.c | 3 +++ include/libweston/backend-headless.h | 3 +++ libweston/backend-headless/headless.c | 19 +++++++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/frontend/main.c b/frontend/main.c index cd0628bbf..e5b425242 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -752,6 +752,7 @@ usage(int error_code) " --use-pixman\t\tUse the pixman (CPU) renderer (deprecated alias for --renderer=pixman)\n" " --use-gl\t\tUse the GL renderer (deprecated alias for --renderer=gl)\n" " --no-outputs\t\tDo not create any virtual outputs\n" + " --refresh-rate=RATE\tThe output refresh rate (in mHz)\n" "\n"); #endif @@ -3167,7 +3168,9 @@ load_headless_backend(struct weston_compositor *c, { WESTON_OPTION_BOOLEAN, "use-gl", 0, &force_gl }, { WESTON_OPTION_STRING, "transform", 0, &transform }, { WESTON_OPTION_BOOLEAN, "no-outputs", 0, &no_outputs }, + { WESTON_OPTION_INTEGER, "refresh-rate", 0, &config.refresh }, }; + config.refresh = -1; parse_options(options, ARRAY_LENGTH(options), argc, argv); diff --git a/include/libweston/backend-headless.h b/include/libweston/backend-headless.h index c84bd586d..5d4f03eb3 100644 --- a/include/libweston/backend-headless.h +++ b/include/libweston/backend-headless.h @@ -44,6 +44,9 @@ struct weston_headless_backend_config { /** Use output decorations, requires use_gl = true */ bool decorate; + + /** Output repaint refresh rate (in mHz). */ + int refresh; }; #ifdef __cplusplus diff --git a/libweston/backend-headless/headless.c b/libweston/backend-headless/headless.c index 4ca1e3c5d..2d74eea09 100644 --- a/libweston/backend-headless/headless.c +++ b/libweston/backend-headless/headless.c @@ -47,11 +47,14 @@ #include "shared/weston-egl-ext.h" #include "shared/cairo-util.h" #include "shared/xalloc.h" +#include "shared/timespec-util.h" #include "linux-dmabuf.h" #include "output-capture.h" #include "presentation-time-server-protocol.h" #include +#define DEFAULT_OUTPUT_REPAINT_REFRESH 60000 /* In mHz. */ + struct headless_backend { struct weston_backend base; struct weston_compositor *compositor; @@ -63,6 +66,8 @@ struct headless_backend { const struct pixel_format_info **formats; unsigned int formats_count; + + int refresh; }; struct headless_head { @@ -157,6 +162,7 @@ headless_output_repaint(struct weston_output *output_base) struct headless_output *output = to_headless_output(output_base); struct weston_compositor *ec; pixman_region32_t damage; + int delay_msec; assert(output); @@ -173,7 +179,8 @@ headless_output_repaint(struct weston_output *output_base) pixman_region32_fini(&damage); - wl_event_source_timer_update(output->finish_frame_timer, 16); + delay_msec = millihz_to_nsec(output->mode.refresh) / 1000000; + wl_event_source_timer_update(output->finish_frame_timer, delay_msec); return 0; } @@ -416,7 +423,7 @@ headless_output_set_size(struct weston_output *base, WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED; output->mode.width = output_width; output->mode.height = output_height; - output->mode.refresh = 60000; + output->mode.refresh = output->backend->refresh; wl_list_insert(&output->base.mode_list, &output->mode.link); output->base.current_mode = &output->mode; @@ -565,6 +572,13 @@ headless_backend_create(struct weston_compositor *compositor, b->formats_count = ARRAY_LENGTH(headless_formats); b->formats = pixel_format_get_array(headless_formats, b->formats_count); + /* Wayland event source's timeout has a granularity of the order of + * milliseconds so the highest supported rate is 1 kHz. */ + if (config->refresh > 0) + b->refresh = MIN(config->refresh, 1000000); + else + b->refresh = DEFAULT_OUTPUT_REPAINT_REFRESH; + if (!compositor->renderer) { switch (config->renderer) { case WESTON_RENDERER_GL: { @@ -639,6 +653,7 @@ err_free: static void config_init_to_defaults(struct weston_headless_backend_config *config) { + config->refresh = DEFAULT_OUTPUT_REPAINT_REFRESH; } WL_EXPORT int