From 0d9ffef7747402734803441d312034926bff951e Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 21 Feb 2024 12:35:52 +0100 Subject: [PATCH] backend/drm: don't destroy previous DRM master blobs On startup, we fetch the previous MODE_ID blob ID so that compositors can keep using the previous mode if they want to. However, that blob doesn't belong to us, it belongs to the previous DRM master. As a result, we get an error when trying to destroy it. Fix this by tracking whether the blob belongs to us or not. Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3811 --- backend/drm/atomic.c | 4 ++++ backend/drm/drm.c | 3 ++- backend/drm/libliftoff.c | 4 ++++ include/backend/drm/drm.h | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index bbbd064e..c190a9fd 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -379,6 +379,10 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn, atomic_finish(&atom); if (ok && !test_only) { + if (!crtc->own_mode_id) { + crtc->mode_id = 0; // don't try to delete previous master's blobs + } + crtc->own_mode_id = true; commit_blob(drm, &crtc->mode_id, mode_id); commit_blob(drm, &crtc->gamma_lut, gamma_lut); diff --git a/backend/drm/drm.c b/backend/drm/drm.c index d92b41d3..fd6bf513 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -329,7 +329,7 @@ void finish_drm_resources(struct wlr_drm_backend *drm) { for (size_t i = 0; i < drm->num_crtcs; ++i) { struct wlr_drm_crtc *crtc = &drm->crtcs[i]; - if (crtc->mode_id) { + if (crtc->mode_id && crtc->own_mode_id) { drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id); } if (crtc->gamma_lut) { @@ -1483,6 +1483,7 @@ static bool connect_drm_connector(struct wlr_drm_connector *wlr_conn, get_drm_prop(drm->fd, wlr_conn->crtc->id, wlr_conn->crtc->props.mode_id, &mode_id); + wlr_conn->crtc->own_mode_id = false; wlr_conn->crtc->mode_id = mode_id; wlr_conn->refresh = calculate_refresh_rate(current_modeinfo); } diff --git a/backend/drm/libliftoff.c b/backend/drm/libliftoff.c index 334a660c..79f83954 100644 --- a/backend/drm/libliftoff.c +++ b/backend/drm/libliftoff.c @@ -475,6 +475,10 @@ out: drmModeAtomicFree(req); if (ok && !test_only) { + if (!crtc->own_mode_id) { + crtc->mode_id = 0; // don't try to delete previous master's blobs + } + crtc->own_mode_id = true; commit_blob(drm, &crtc->mode_id, mode_id); commit_blob(drm, &crtc->gamma_lut, gamma_lut); diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index e2c74a9f..cea53f44 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -61,6 +61,7 @@ struct wlr_drm_crtc { struct wl_list layers; // wlr_drm_layer.link // Atomic modesetting only + bool own_mode_id; uint32_t mode_id; uint32_t gamma_lut;