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.
This commit is contained in:
Tom Englund 2025-12-28 11:27:55 +01:00
parent d5097ad0e3
commit 993ec8b7ba
2 changed files with 28 additions and 38 deletions

View file

@ -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<SOutputMode> 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<uint16_t> retVal;

View file

@ -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);