diff --git a/compositor/main.c b/compositor/main.c index b3cb6842..66927e97 100644 --- a/compositor/main.c +++ b/compositor/main.c @@ -4141,6 +4141,9 @@ wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_data) goto out; } + if (weston_compositor_backends_loaded(wet.compositor) < 0) + goto out; + if (test_data && !check_compositor_capabilities(wet.compositor, test_data->test_quirks.required_capabilities)) { ret = WET_MAIN_RET_MISSING_CAPS; diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index 626a5bee..4eff82ac 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -2665,6 +2665,9 @@ weston_compositor_add_screenshot_authority(struct weston_compositor *compositor, void (*auth)(struct wl_listener *l, struct weston_output_capture_attempt *att)); +int +weston_compositor_backends_loaded(struct weston_compositor *compositor); + #ifdef __cplusplus } #endif diff --git a/libweston/backend-drm/kms.c b/libweston/backend-drm/kms.c index e57b4ab9..ba1c1696 100644 --- a/libweston/backend-drm/kms.c +++ b/libweston/backend-drm/kms.c @@ -1787,7 +1787,6 @@ int init_kms_caps(struct drm_device *device) { struct drm_backend *b = device->backend; - struct weston_compositor *compositor = b->compositor; uint64_t cap; int ret; @@ -1799,10 +1798,7 @@ init_kms_caps(struct drm_device *device) return -1; } - if (weston_compositor_set_presentation_clock(compositor, CLOCK_MONOTONIC) < 0) { - weston_log("Error: failed to set presentation clock to CLOCK_MONOTONIC.\n"); - return -1; - } + b->base.supported_presentation_clocks = 1 << CLOCK_MONOTONIC; ret = drmGetCap(device->drm.fd, DRM_CAP_CURSOR_WIDTH, &cap); if (ret == 0) diff --git a/libweston/backend-headless/headless.c b/libweston/backend-headless/headless.c index 20644cc8..92fe26a5 100644 --- a/libweston/backend-headless/headless.c +++ b/libweston/backend-headless/headless.c @@ -539,8 +539,8 @@ headless_backend_create(struct weston_compositor *compositor, b->compositor = compositor; compositor->backend = &b->base; - if (weston_compositor_set_presentation_clock_software(compositor) < 0) - goto err_free; + b->base.supported_presentation_clocks = + WESTON_PRESENTATION_CLOCKS_SOFTWARE; b->base.destroy = headless_destroy; b->base.create_output = headless_output_create; diff --git a/libweston/backend-pipewire/pipewire.c b/libweston/backend-pipewire/pipewire.c index b5e95c42..dc2fe10c 100644 --- a/libweston/backend-pipewire/pipewire.c +++ b/libweston/backend-pipewire/pipewire.c @@ -1041,8 +1041,8 @@ pipewire_backend_create(struct weston_compositor *compositor, backend->formats = pixel_format_get_array(pipewire_formats, backend->formats_count); - if (weston_compositor_set_presentation_clock_software(compositor) < 0) - goto err_compositor; + backend->base.supported_presentation_clocks = + WESTON_PRESENTATION_CLOCKS_SOFTWARE; switch (config->renderer) { case WESTON_RENDERER_AUTO: diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index 14dc62ad..79eee839 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -1891,8 +1891,8 @@ rdp_backend_create(struct weston_compositor *compositor, wl_list_init(&b->peers); - if (weston_compositor_set_presentation_clock_software(compositor) < 0) - goto err_compositor; + b->base.supported_presentation_clocks = + WESTON_PRESENTATION_CLOCKS_SOFTWARE; b->formats_count = ARRAY_LENGTH(rdp_formats); b->formats = pixel_format_get_array(rdp_formats, b->formats_count); diff --git a/libweston/backend-vnc/vnc.c b/libweston/backend-vnc/vnc.c index 96d2bc1e..f8b496f2 100644 --- a/libweston/backend-vnc/vnc.c +++ b/libweston/backend-vnc/vnc.c @@ -1188,8 +1188,8 @@ vnc_backend_create(struct weston_compositor *compositor, compositor->backend = &backend->base; - if (weston_compositor_set_presentation_clock_software(compositor) < 0) - goto err_compositor; + backend->base.supported_presentation_clocks = + WESTON_PRESENTATION_CLOCKS_SOFTWARE; backend->formats_count = ARRAY_LENGTH(vnc_formats); backend->formats = pixel_format_get_array(vnc_formats, diff --git a/libweston/backend-wayland/wayland.c b/libweston/backend-wayland/wayland.c index affeee8d..89442d05 100644 --- a/libweston/backend-wayland/wayland.c +++ b/libweston/backend-wayland/wayland.c @@ -2882,8 +2882,8 @@ wayland_backend_create(struct weston_compositor *compositor, b->compositor = compositor; compositor->backend = &b->base; - if (weston_compositor_set_presentation_clock_software(compositor) < 0) - goto err_compositor; + b->base.supported_presentation_clocks = + WESTON_PRESENTATION_CLOCKS_SOFTWARE; b->parent.wl_display = wl_display_connect(new_config->display_name); if (b->parent.wl_display == NULL) { diff --git a/libweston/backend-x11/x11.c b/libweston/backend-x11/x11.c index d9df40f7..b345e310 100644 --- a/libweston/backend-x11/x11.c +++ b/libweston/backend-x11/x11.c @@ -1884,8 +1884,8 @@ x11_backend_create(struct weston_compositor *compositor, compositor->backend = &b->base; - if (weston_compositor_set_presentation_clock_software(compositor) < 0) - goto err_free; + b->base.supported_presentation_clocks = + WESTON_PRESENTATION_CLOCKS_SOFTWARE; b->dpy = XOpenDisplay(NULL); if (b->dpy == NULL) diff --git a/libweston/backend.h b/libweston/backend.h index ad60786d..4bb430b6 100644 --- a/libweston/backend.h +++ b/libweston/backend.h @@ -32,9 +32,20 @@ #ifndef LIBWESTON_BACKEND_INTERNAL_H #define LIBWESTON_BACKEND_INTERNAL_H +#define WESTON_PRESENTATION_CLOCKS_SOFTWARE \ + ((1 << CLOCK_MONOTONIC) | \ + (1 << CLOCK_MONOTONIC_RAW) | \ + (1 << CLOCK_MONOTONIC_COARSE)) + struct weston_hdr_metadata_type1; struct weston_backend { + /** Bitfield of supported presentation clocks + * + * Bit positions correspond to system clock IDs. + */ + unsigned int supported_presentation_clocks; + /** Prepare for compositor shutdown (optional) * * This will be called before weston_compositor_shutdown() diff --git a/libweston/compositor.c b/libweston/compositor.c index 68120939..239dd2b6 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -8841,6 +8841,9 @@ weston_compositor_create(struct wl_display *display, if (test_data) ec->test_data = *test_data; + /* No backend supports CLOCK_REALTIME, use it to mean 'uninitialized' */ + ec->presentation_clock = CLOCK_REALTIME; + ec->weston_log_ctx = log_ctx; ec->wl_display = display; ec->user_data = user_data; @@ -9046,10 +9049,7 @@ weston_compositor_set_default_pointer_grab(struct weston_compositor *ec, } } -/** weston_compositor_set_presentation_clock - * \ingroup compositor - */ -WL_EXPORT int +static int weston_compositor_set_presentation_clock(struct weston_compositor *compositor, clockid_t clk_id) { @@ -9063,15 +9063,19 @@ weston_compositor_set_presentation_clock(struct weston_compositor *compositor, return 0; } -/** For choosing the software clock, when the display hardware or API - * does not expose a compatible presentation timestamp. +/** To be called by the compositor after the last backend is loaded. + * + * \param compositor A compositor that has all backends loaded. + * + * \return 0 on success, or -1 on error. * * \ingroup compositor */ WL_EXPORT int -weston_compositor_set_presentation_clock_software( - struct weston_compositor *compositor) +weston_compositor_backends_loaded(struct weston_compositor *compositor) { + struct weston_backend *backend = compositor->backend; + uint32_t supported_clocks = backend->supported_presentation_clocks; /* In order of preference */ static const clockid_t clocks[] = { CLOCK_MONOTONIC_RAW, /* no jumps, no crawling */ @@ -9080,10 +9084,17 @@ weston_compositor_set_presentation_clock_software( }; unsigned i; - for (i = 0; i < ARRAY_LENGTH(clocks); i++) + for (i = 0; i < ARRAY_LENGTH(clocks); i++) { + clockid_t clk_id = clocks[i]; + bool supported = (supported_clocks >> clocks[i]) & 1; + + if (!supported) + continue; + if (weston_compositor_set_presentation_clock(compositor, - clocks[i]) == 0) + clk_id) == 0) return 0; + } weston_log("Error: no suitable presentation clock available.\n"); @@ -9111,6 +9122,12 @@ weston_compositor_read_presentation_clock( { int ret; + /* + * Make sure weston_compositor_backends_loaded() was called. + * We use CLOCK_REALTIME to mean 'uninitialized'. + */ + assert(compositor->presentation_clock != CLOCK_REALTIME); + ret = clock_gettime(compositor->presentation_clock, ts); if (ret < 0) { ts->tv_sec = 0; diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h index c153a72e..0cb98dc5 100644 --- a/libweston/libweston-internal.h +++ b/libweston/libweston-internal.h @@ -238,13 +238,6 @@ weston_compositor_set_touch_mode_normal(struct weston_compositor *compositor); void weston_compositor_set_touch_mode_calib(struct weston_compositor *compositor); -int -weston_compositor_set_presentation_clock(struct weston_compositor *compositor, - clockid_t clk_id); -int -weston_compositor_set_presentation_clock_software( - struct weston_compositor *compositor); - void weston_compositor_xkb_destroy(struct weston_compositor *ec);