From 993ec8b7ba8b5b0b52f3f5e3d2a4e0970e795b0d Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sun, 28 Dec 2025 11:27:55 +0100 Subject: [PATCH] output: modeset on hdr/color changes fix the connector connecting modeset check to actually only modeset when no matching mode is found, and if no match use the fallback. move the hdr bits back behind modesetting because driver quirks and general bugs arises if a modeset isnt being done when hdr/colorspace changes. --- src/backend/drm/DRM.cpp | 22 ++++++++--------- src/backend/drm/impl/Atomic.cpp | 44 +++++++++++++-------------------- 2 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index 5c43d41..e8ce53f 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -1435,7 +1435,9 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) { backend->backend->log(AQ_LOG_DEBUG, "drm: Dumping detected modes:"); - auto currentModeInfo = getCurrentMode(); + auto currentModeInfo = getCurrentMode(); + auto state = output->state->state(); + Hyprutils::Memory::CWeakPointer matchedMode; for (int i = 0; i < connector->count_modes; ++i) { auto& drmMode = connector->modes[i]; @@ -1456,20 +1458,20 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) { output->modes.emplace_back(aqMode); - if (currentModeInfo && std::memcmp(&drmMode, currentModeInfo, sizeof(drmModeModeInfo)) != 0) { - output->state->setMode(aqMode); - - //uint64_t modeID = 0; - // getDRMProp(backend->gpu->fd, crtc->id, crtc->props.mode_id, &modeID); - } + if (currentModeInfo && std::memcmp(&drmMode, currentModeInfo, sizeof(drmModeModeInfo)) == 0) + matchedMode = aqMode; backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Mode {}: {}x{}@{:.2f}Hz {}", i, (int)aqMode->pixelSize.x, (int)aqMode->pixelSize.y, aqMode->refreshRate / 1000.0, aqMode->preferred ? " (preferred)" : "")); } - if (!currentModeInfo && fallbackMode) - output->state->setMode(fallbackMode); + if (matchedMode) { + state.mode = matchedMode; + } else if (!currentModeInfo && fallbackMode) { + state.mode = fallbackMode; + state.committed |= COutputState::AQ_OUTPUT_STATE_MODE; // flag needed for modeset in commit. + } output->physicalSize = {(double)connector->mmWidth, (double)connector->mmHeight}; @@ -1521,8 +1523,6 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) { recheckCRTCProps(); - auto state = output->state->state(); - auto recreateGammaBlob = [this](uint32_t prop) { auto* blob = drmModeGetPropertyBlob(backend->gpu->fd, prop); std::vector retVal; diff --git a/src/backend/drm/impl/Atomic.cpp b/src/backend/drm/impl/Atomic.cpp index 3a106b3..dd21e3a 100644 --- a/src/backend/drm/impl/Atomic.cpp +++ b/src/backend/drm/impl/Atomic.cpp @@ -136,21 +136,6 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint TRACE(backend->log(AQ_LOG_TRACE, std::format("atomic addConnector values: CRTC {}, mode {}", enable ? connector->crtc->id : 0, data.atomic.modeBlob))); conn = connector; - if (enable && data.modeset) { - // Setup HDR - if (connector->props.values.max_bpc && connector->maxBpcBounds.at(1)) - add(connector->id, connector->props.values.max_bpc, getMaxBPC(data.mainFB->buffer->dmabuf().format)); - - if (connector->props.values.Colorspace && STATE.committed & COutputState::AQ_OUTPUT_STATE_WCG) { - if (connector->colorspace.values.BT2020_RGB) - add(connector->id, connector->props.values.Colorspace, STATE.wideColorGamut ? connector->colorspace.values.BT2020_RGB : connector->colorspace.values.Default); - else - add(connector->id, connector->props.values.Colorspace, connector->colorspace.values.Default); - } - - if (connector->props.values.hdr_output_metadata && data.atomic.hdrd && STATE.committed & COutputState::AQ_OUTPUT_STATE_HDR) - add(connector->id, connector->props.values.hdr_output_metadata, data.atomic.hdrBlob); - } addConnectorModeset(connector, data); @@ -197,20 +182,25 @@ void Aquamarine::CDRMAtomicRequest::addConnectorModeset(Hyprutils::Memory::CShar const bool enable = STATE.enabled && data.mainFB; if (enable) { - drmModeModeInfo* currentMode = connector->getCurrentMode(); - bool modeDiffers = true; - if (currentMode) { - modeDiffers = memcmp(currentMode, &data.modeInfo, sizeof(drmModeModeInfo)) != 0; - free(currentMode); + // Setup HDR + if (connector->props.values.max_bpc && connector->maxBpcBounds.at(1)) + add(connector->id, connector->props.values.max_bpc, getMaxBPC(data.mainFB->buffer->dmabuf().format)); + + if (connector->props.values.Colorspace && STATE.committed & COutputState::AQ_OUTPUT_STATE_WCG) { + if (connector->colorspace.values.BT2020_RGB) + add(connector->id, connector->props.values.Colorspace, STATE.wideColorGamut ? connector->colorspace.values.BT2020_RGB : connector->colorspace.values.Default); + else + add(connector->id, connector->props.values.Colorspace, connector->colorspace.values.Default); } - if (modeDiffers) { - data.atomic.blobbed = true; - add(connector->crtc->id, connector->crtc->props.values.mode_id, data.atomic.modeBlob); - add(connector->crtc->id, connector->crtc->props.values.active, 1); - if (connector->props.values.link_status) - add(connector->id, connector->props.values.link_status, DRM_MODE_LINK_STATUS_GOOD); - } + if (connector->props.values.hdr_output_metadata && data.atomic.hdrd && STATE.committed & COutputState::AQ_OUTPUT_STATE_HDR) + add(connector->id, connector->props.values.hdr_output_metadata, data.atomic.hdrBlob); + + data.atomic.blobbed = true; + add(connector->crtc->id, connector->crtc->props.values.mode_id, data.atomic.modeBlob); + add(connector->crtc->id, connector->crtc->props.values.active, 1); + if (connector->props.values.link_status) + add(connector->id, connector->props.values.link_status, DRM_MODE_LINK_STATUS_GOOD); } else { add(connector->crtc->id, connector->crtc->props.values.mode_id, 0); add(connector->crtc->id, connector->crtc->props.values.active, 0);