From 8e5f68833dd8af5faefc8c235732f6043da4112b Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sat, 30 May 2026 19:07:51 +0200 Subject: [PATCH] backend/drm: add support for PAGE_FLIP_EVENT property --- backend/drm/atomic.c | 4 ++++ backend/drm/drm.c | 41 +++++++++++++++++++++++++------- backend/drm/properties.c | 1 + include/backend/drm/drm.h | 1 + include/backend/drm/properties.h | 1 + 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index daa8ba9bf..c68e30670 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -582,6 +582,10 @@ static void atomic_connector_add(struct atomic *atom, if (crtc->props.vrr_enabled != 0) { atomic_add(atom, crtc->id, crtc->props.vrr_enabled, state->vrr_enabled); } + if (crtc->props.page_flip_event && state->page_flip_event) { + wlr_log(WLR_DEBUG, "YAAAY"); + atomic_add(atom, crtc->id, crtc->props.page_flip_event, 1); + } set_plane_props(atom, drm, crtc->primary, state->primary_fb, crtc->id, &state->primary_viewport.dst_box, &state->primary_viewport.src_box); diff --git a/backend/drm/drm.c b/backend/drm/drm.c index d2f75f71f..2bff00bf6 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -503,7 +503,7 @@ void drm_page_flip_destroy(struct wlr_drm_page_flip *page_flip) { } static struct wlr_drm_page_flip *drm_page_flip_create(struct wlr_drm_backend *drm, - const struct wlr_drm_device_state *state) { + const struct wlr_drm_device_state *state, uint32_t flags) { struct wlr_drm_page_flip *page_flip = calloc(1, sizeof(*page_flip)); if (page_flip == NULL) { return NULL; @@ -516,7 +516,11 @@ static struct wlr_drm_page_flip *drm_page_flip_create(struct wlr_drm_backend *dr return NULL; } for (size_t i = 0; i < state->connectors_len; i++) { - struct wlr_drm_connector *conn = state->connectors[i].connector; + const struct wlr_drm_connector_state *conn_state = &state->connectors[i]; + struct wlr_drm_connector *conn = conn_state->connector; + if (!(flags & DRM_MODE_PAGE_FLIP_EVENT) && !conn_state->page_flip_event) { + continue; + } page_flip->connectors[i] = (struct wlr_drm_page_flip_connector){ .connector = conn, .crtc_id = conn->crtc->id, @@ -632,6 +636,16 @@ static void drm_connector_rollback_commit(const struct wlr_drm_connector_state * } } +static bool device_state_has_conn_page_flip_event(const struct wlr_drm_device_state *state) { + for (size_t i = 0; i < state->connectors_len; i++) { + const struct wlr_drm_connector_state *conn_state = &state->connectors[i]; + if (conn_state->page_flip_event) { + return true; + } + } + return false; +} + static bool drm_commit(struct wlr_drm_backend *drm, const struct wlr_drm_device_state *state, uint32_t flags, bool test_only) { @@ -639,8 +653,8 @@ static bool drm_commit(struct wlr_drm_backend *drm, assert((flags & ~DRM_MODE_PAGE_FLIP_FLAGS) == 0); struct wlr_drm_page_flip *page_flip = NULL; - if (flags & DRM_MODE_PAGE_FLIP_EVENT) { - page_flip = drm_page_flip_create(drm, state); + if ((flags & DRM_MODE_PAGE_FLIP_EVENT) || device_state_has_conn_page_flip_event(state)) { + page_flip = drm_page_flip_create(drm, state, flags); if (page_flip == NULL) { return false; } @@ -998,7 +1012,11 @@ static bool drm_connector_commit_state(struct wlr_drm_connector *conn, uint32_t flags = 0; if (!test_only && pending.active) { - flags |= DRM_MODE_PAGE_FLIP_EVENT; + if (conn->crtc->props.page_flip_event) { + pending.page_flip_event = true; + } else { + flags |= DRM_MODE_PAGE_FLIP_EVENT; + } } if (pending.base->tearing_page_flip) { flags |= DRM_MODE_PAGE_FLIP_ASYNC; @@ -1943,6 +1961,7 @@ bool commit_drm_device(struct wlr_drm_backend *drm, bool ok = false; bool modeset = false; + uint32_t flags = 0; size_t conn_states_len = 0; for (size_t i = 0; i < output_states_len; i++) { const struct wlr_backend_output_state *output_state = &output_states[i]; @@ -1975,6 +1994,14 @@ bool commit_drm_device(struct wlr_drm_backend *drm, } modeset |= output_state->base.allow_reconfiguration; + + if (!test_only) { + if (conn->crtc->props.page_flip_event) { + conn_state->page_flip_event = true; + } else { + flags |= DRM_MODE_PAGE_FLIP_EVENT; + } + } } if (test_only && drm->mgpu_renderer.wlr_rend) { @@ -1984,10 +2011,6 @@ bool commit_drm_device(struct wlr_drm_backend *drm, goto out; } - uint32_t flags = 0; - if (!test_only) { - flags |= DRM_MODE_PAGE_FLIP_EVENT; - } struct wlr_drm_device_state dev_state = { .modeset = modeset, .connectors = conn_states, diff --git a/backend/drm/properties.c b/backend/drm/properties.c index 4c6bdcb36..4f6bda161 100644 --- a/backend/drm/properties.c +++ b/backend/drm/properties.c @@ -44,6 +44,7 @@ static const struct prop_info crtc_info[] = { { "GAMMA_LUT_SIZE", INDEX(gamma_lut_size) }, { "MODE_ID", INDEX(mode_id) }, { "OUT_FENCE_PTR", INDEX(out_fence_ptr) }, + { "PAGE_FLIP_EVENT", INDEX(page_flip_event) }, { "VRR_ENABLED", INDEX(vrr_enabled) }, #undef INDEX }; diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index a8c5e077a..16dd26cde 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -164,6 +164,7 @@ struct wlr_drm_connector_state { bool vrr_enabled; uint32_t colorspace; uint32_t hdr_output_metadata; + bool page_flip_event; }; /** diff --git a/include/backend/drm/properties.h b/include/backend/drm/properties.h index 20e0a5bff..f47b2695d 100644 --- a/include/backend/drm/properties.h +++ b/include/backend/drm/properties.h @@ -41,6 +41,7 @@ struct wlr_drm_crtc_props { uint32_t active; uint32_t mode_id; uint32_t out_fence_ptr; + uint32_t page_flip_event; }; struct wlr_drm_plane_props {