backend: add timeline feature flag

The output feature flag has a flaw: it's not possible to check
whether the backend supports timelines during compositor
initialization when we need to figure out whether we want to enable
the linux-drm-syncobj-v1 protocol.

Introduce a backend-wide feature flag to indicate support for
timelines to address this defect.

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3904
This commit is contained in:
Simon Ser 2024-10-10 16:23:49 +02:00 committed by Alexander Orzechowski
parent 8d8d5f5e94
commit 514c4b4cce
4 changed files with 25 additions and 0 deletions

View File

@ -126,6 +126,12 @@ bool check_drm_features(struct wlr_drm_backend *drm) {
drm->supports_tearing_page_flips = drmGetCap(drm->fd, DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP, &cap) == 0 && cap == 1; drm->supports_tearing_page_flips = drmGetCap(drm->fd, DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP, &cap) == 0 && cap == 1;
} }
drm->backend.features.timeline = drm->iface != &legacy_iface;
if (drm->parent) {
drm->backend.features.timeline = drm->backend.features.timeline &&
drm->mgpu_renderer.wlr_rend->features.timeline;
}
if (env_parse_bool("WLR_DRM_NO_MODIFIERS")) { if (env_parse_bool("WLR_DRM_NO_MODIFIERS")) {
wlr_log(WLR_DEBUG, "WLR_DRM_NO_MODIFIERS set, disabling modifiers"); wlr_log(WLR_DEBUG, "WLR_DRM_NO_MODIFIERS set, disabling modifiers");
} else { } else {

View File

@ -80,6 +80,8 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_event_loop *loop) {
backend->event_loop_destroy.notify = handle_event_loop_destroy; backend->event_loop_destroy.notify = handle_event_loop_destroy;
wl_event_loop_add_destroy_listener(loop, &backend->event_loop_destroy); wl_event_loop_add_destroy_listener(loop, &backend->event_loop_destroy);
backend->backend.features.timeline = true;
return &backend->backend; return &backend->backend;
} }

View File

@ -225,6 +225,16 @@ static struct subbackend_state *multi_backend_get_subbackend(struct wlr_multi_ba
return NULL; return NULL;
} }
static void multi_backend_refresh_features(struct wlr_multi_backend *multi) {
multi->backend.features.timeline = true;
struct subbackend_state *sub = NULL;
wl_list_for_each(sub, &multi->backends, link) {
multi->backend.features.timeline = multi->backend.features.timeline &&
sub->backend->features.timeline;
}
}
bool wlr_multi_backend_add(struct wlr_backend *_multi, bool wlr_multi_backend_add(struct wlr_backend *_multi,
struct wlr_backend *backend) { struct wlr_backend *backend) {
assert(_multi && backend); assert(_multi && backend);
@ -256,6 +266,7 @@ bool wlr_multi_backend_add(struct wlr_backend *_multi,
wl_signal_add(&backend->events.new_output, &sub->new_output); wl_signal_add(&backend->events.new_output, &sub->new_output);
sub->new_output.notify = new_output_reemit; sub->new_output.notify = new_output_reemit;
multi_backend_refresh_features(multi);
wl_signal_emit_mutable(&multi->events.backend_add, backend); wl_signal_emit_mutable(&multi->events.backend_add, backend);
return true; return true;
} }
@ -270,6 +281,7 @@ void wlr_multi_backend_remove(struct wlr_backend *_multi,
if (sub) { if (sub) {
wl_signal_emit_mutable(&multi->events.backend_remove, backend); wl_signal_emit_mutable(&multi->events.backend_remove, backend);
subbackend_state_destroy(sub); subbackend_state_destroy(sub);
multi_backend_refresh_features(multi);
} }
} }

View File

@ -29,6 +29,11 @@ struct wlr_backend_output_state {
struct wlr_backend { struct wlr_backend {
const struct wlr_backend_impl *impl; const struct wlr_backend_impl *impl;
struct {
// Whether wait/signal timelines are supported in output commits
bool timeline;
} features;
struct { struct {
/** Raised when destroyed */ /** Raised when destroyed */
struct wl_signal destroy; struct wl_signal destroy;