From b305a97e9d705526334ae11347503952ed3a4563 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 27 Jul 2022 16:08:40 +0000 Subject: [PATCH] drm: Don't re-zero connector CRTCs we already have zero-ed. Fixes an issue where we would use an invalid connector because the MST connector object got destroyed from our last CRTC set. This avoids just using it again. --- src/drm.cpp | 29 ++++++++++++++++++++++++++++- src/drm.hpp | 4 ++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/drm.cpp b/src/drm.cpp index 90e2531..980e608 100644 --- a/src/drm.cpp +++ b/src/drm.cpp @@ -491,6 +491,8 @@ static bool refresh_state( drm_t *drm ) conn->possible_crtcs = get_connector_possible_crtcs(drm, conn->connector); + conn->current.crtc_id = conn->initial_prop_values["CRTC_ID"]; + drm_log.debugf("found new connector '%s'", conn->name); } @@ -1052,6 +1054,11 @@ int drm_commit(struct drm_t *drm, const struct FrameInfo_t *frameInfo ) drm->crtcs[i].pending = drm->crtcs[i].current; } + for (auto &kv : drm->connectors) { + struct connector *conn = &kv.second; + conn->pending = conn->current; + } + // Undo refcount if the commit didn't actually work for ( uint32_t i = 0; i < drm->fbids_in_req.size(); i++ ) { @@ -1080,6 +1087,11 @@ int drm_commit(struct drm_t *drm, const struct FrameInfo_t *frameInfo ) drmModeDestroyPropertyBlob(drm->fd, drm->current.degamma_lut_id); drm->crtcs[i].current = drm->crtcs[i].pending; } + + for (auto &kv : drm->connectors) { + struct connector *conn = &kv.second; + conn->current = conn->pending; + } } // Update the draw time @@ -1621,6 +1633,11 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI for ( auto &kv : drm->connectors ) { struct connector *conn = &kv.second; + + if ( conn->current.crtc_id == 0 ) + continue; + + conn->pending.crtc_id = 0; int ret = add_connector_property( drm->req, conn, "CRTC_ID", 0 ); if (ret < 0) return ret; @@ -1662,7 +1679,12 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI // Then enable the one we've picked - int ret = add_connector_property(drm->req, drm->connector, "CRTC_ID", drm->crtc->id); + int ret = 0; + + // Always set our CRTC_ID for the modeset, especially + // as we zero-ed it above. + drm->connector->pending.crtc_id = drm->crtc->id; + ret = add_connector_property(drm->req, drm->connector, "CRTC_ID", drm->crtc->id); if (ret < 0) return ret; @@ -1750,6 +1772,11 @@ void drm_rollback( struct drm_t *drm ) { drm->crtcs[i].pending = drm->crtcs[i].current; } + + for (auto &kv : drm->connectors) { + struct connector *conn = &kv.second; + conn->pending = conn->current; + } } bool drm_poll_state( struct drm_t *drm ) diff --git a/src/drm.hpp b/src/drm.hpp index d954871..fabda88 100644 --- a/src/drm.hpp +++ b/src/drm.hpp @@ -86,6 +86,10 @@ struct connector { char make_pnp[4]; char *make; char *model; + + struct { + uint32_t crtc_id; + } current, pending; }; struct fb {