libweston: Set the presentation clock in the compositor

Let backends declare the presentation clocks they can use with a
new bitfield weston_backend::supported_presentation_clocks and set
presentation clock after loading the backend in the compositor.

Make weston_compositor_set_presentation_clock() internal and replace
weston_compositor_set_presentation_clock_software() with an exported
weston_compositor_backends_loaded(), which is called by the compositor
after the backend is loaded.

In the future, this can be extended to determine the subset of clocks
supported by all backends.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
Philipp Zabel 2023-07-19 10:18:43 +02:00 committed by Marius Vlad
parent 51d23a409a
commit 1d59530e4b
12 changed files with 57 additions and 34 deletions

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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:

View File

@ -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);

View File

@ -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,

View File

@ -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) {

View File

@ -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)

View File

@ -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()

View File

@ -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;

View File

@ -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);