From c3743364e2814b1e309cf58e9c774a939031a23c Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 4 Mar 2024 14:07:12 +0100 Subject: [PATCH] backend/drm: ensure CRTC is set up in drm_connector_state_init() In [1] we discovered a bug where wlr_drm_connector_state.primary_fb would not be set up correctly because drm_connector_alloc_crtc() was called after drm_connector_state_init(). This is tricky to discover, so instead assert() that we have a usable CRTC by the time drm_connector_state_init() is called. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4569 --- backend/drm/drm.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 73dfb82f..3a71f393 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -544,22 +544,27 @@ static void drm_connector_state_init(struct wlr_drm_connector_state *state, state->mode.type = DRM_MODE_TYPE_USERDEF; } - if (conn->crtc != NULL) { + if (output_pending_enabled(&conn->output, base)) { + // The CRTC must be set up before this function is called + assert(conn->crtc != NULL); + struct wlr_drm_plane *primary = conn->crtc->primary; if (primary->queued_fb != NULL) { state->primary_fb = drm_fb_lock(primary->queued_fb); } else if (primary->current_fb != NULL) { state->primary_fb = drm_fb_lock(primary->current_fb); } - } - if (conn->crtc != NULL && conn->cursor_enabled) { - struct wlr_drm_plane *cursor = conn->crtc->cursor; - if (conn->cursor_pending_fb != NULL) { - state->cursor_fb = drm_fb_lock(conn->cursor_pending_fb); - } else if (cursor->queued_fb != NULL) { - state->cursor_fb = drm_fb_lock(cursor->queued_fb); - } else if (cursor->current_fb != NULL) { - state->cursor_fb = drm_fb_lock(cursor->current_fb); + + if (conn->cursor_enabled) { + struct wlr_drm_plane *cursor = conn->crtc->cursor; + assert(cursor != NULL); + if (conn->cursor_pending_fb != NULL) { + state->cursor_fb = drm_fb_lock(conn->cursor_pending_fb); + } else if (cursor->queued_fb != NULL) { + state->cursor_fb = drm_fb_lock(cursor->queued_fb); + } else if (cursor->current_fb != NULL) { + state->cursor_fb = drm_fb_lock(cursor->current_fb); + } } } }