From f870d63badcb011350d467d836f845a3c6103c40 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sat, 23 Nov 2024 15:29:44 +0100 Subject: [PATCH] backend/drm: fix drmModePageFlip() when disabling CRTC on legacy uAPI drmModePageFlip() will fail with EBUSY on a disabled CRTC. We can't fix this by clearing the DRM_MODE_PAGE_FLIP_EVENT when performing a commit which disables CRTCs, because some device-wide commits might also page-flip other enabled CRTCs (and skipping the page-flip event would mess up our buffer tracking). Fix this by immediately completing page-flips which disable a CRTC on the legacy uAPI. Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3918 (cherry picked from commit 3e651b4642de779f208094831d2ae7d9f419b417) --- backend/drm/drm.c | 10 ++++++++++ backend/drm/legacy.c | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index c9e028a4e..ea23f1741 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -577,6 +577,16 @@ static void drm_connector_apply_commit(const struct wlr_drm_connector_state *sta conn->cursor_enabled = false; conn->crtc = NULL; + + // Legacy uAPI doesn't support requesting page-flip events when + // turning off a CRTC + if (page_flip != NULL && conn->backend->iface == &legacy_iface) { + drm_page_flip_pop(page_flip, crtc->id); + conn->pending_page_flip = NULL; + if (page_flip->connectors_len == 0) { + drm_page_flip_destroy(page_flip); + } + } } } diff --git a/backend/drm/legacy.c b/backend/drm/legacy.c index 0c591f4dd..502c09247 100644 --- a/backend/drm/legacy.c +++ b/backend/drm/legacy.c @@ -128,7 +128,7 @@ static bool legacy_crtc_commit(const struct wlr_drm_connector_state *state, state->base->adaptive_sync_enabled ? "enabled" : "disabled"); } - if (cursor != NULL && drm_connector_is_cursor_visible(conn)) { + if (cursor != NULL && state->active && drm_connector_is_cursor_visible(conn)) { struct wlr_drm_fb *cursor_fb = state->cursor_fb; if (cursor_fb == NULL) { wlr_drm_conn_log(conn, WLR_DEBUG, "Failed to acquire cursor FB"); @@ -170,7 +170,9 @@ static bool legacy_crtc_commit(const struct wlr_drm_connector_state *state, } } - if (flags & DRM_MODE_PAGE_FLIP_EVENT) { + // Legacy uAPI doesn't support requesting page-flip events when + // turning off a CRTC + if (state->active && (flags & DRM_MODE_PAGE_FLIP_EVENT)) { if (drmModePageFlip(drm->fd, crtc->id, fb_id, flags, page_flip)) { wlr_drm_conn_log_errno(conn, WLR_ERROR, "drmModePageFlip failed"); return false;