From 5700736505557363f8574f5abcc6c0f489821466 Mon Sep 17 00:00:00 2001 From: Dominick DiMaggio Date: Thu, 11 Dec 2025 18:50:57 -0500 Subject: [PATCH] cm: handle CM for SDR content with cm=hdr, cm_sdr_eotf=2 (#12127) --- src/helpers/Monitor.cpp | 13 ++++++++----- src/render/OpenGL.cpp | 4 +++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index fa76a982..d01d2ac8 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -1799,8 +1799,8 @@ uint16_t CMonitor::isDSBlocked(bool full) { return reasons; } - if (needsCM() && *PNONSHADER != CM_NS_IGNORE && !canNoShaderCM() && (!inHDR() || (PSURFACE->m_colorManagement.valid() && PSURFACE->m_colorManagement->isWindowsScRGB())) && - *PPASS != 1) + const bool surfaceIsHDR = PSURFACE->m_colorManagement.valid() && (PSURFACE->m_colorManagement->isHDR() || PSURFACE->m_colorManagement->isWindowsScRGB()); + if (needsCM() && *PNONSHADER != CM_NS_IGNORE && !canNoShaderCM() && ((inHDR() && (*PPASS == 0 || !surfaceIsHDR)) || (!inHDR() && (*PPASS != 1 || surfaceIsHDR)))) reasons |= DS_BLOCK_CM; return reasons; @@ -2065,10 +2065,13 @@ bool CMonitor::canNoShaderCM() { if (SRC_DESC->icc.fd >= 0 || m_imageDescription.icc.fd >= 0) return false; // no ICC support + static auto PSDREOTF = CConfigValue("render:cm_sdr_eotf"); // only primaries differ - if (SRC_DESC->transferFunction == m_imageDescription.transferFunction && SRC_DESC->transferFunctionPower == m_imageDescription.transferFunctionPower && - (!inHDR() || SRC_DESC->luminances == m_imageDescription.luminances) && SRC_DESC->masteringLuminances == m_imageDescription.masteringLuminances && - SRC_DESC->maxCLL == m_imageDescription.maxCLL && SRC_DESC->maxFALL == m_imageDescription.maxFALL) + if ((SRC_DESC->transferFunction == m_imageDescription.transferFunction || + (*PSDREOTF == 2 && SRC_DESC->transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_SRGB && + m_imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22)) && + SRC_DESC->transferFunctionPower == m_imageDescription.transferFunctionPower && (!inHDR() || SRC_DESC->luminances == m_imageDescription.luminances) && + SRC_DESC->masteringLuminances == m_imageDescription.masteringLuminances && SRC_DESC->maxCLL == m_imageDescription.maxCLL && SRC_DESC->maxFALL == m_imageDescription.maxFALL) return true; return false; diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index ae01d2a1..6b5e35f1 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -1715,7 +1715,9 @@ void CHyprOpenGLImpl::renderTextureInternal(SP tex, const CBox& box, c const bool skipCM = !*PENABLECM || !m_cmSupported /* CM unsupported or disabled */ || m_renderData.pMonitor->doesNoShaderCM() /* no shader needed */ || (imageDescription == m_renderData.pMonitor->m_imageDescription && !data.cmBackToSRGB) /* Source and target have the same image description */ - || (((*PPASS && canPassHDRSurface) || (*PPASS == 1 && !isHDRSurface)) && m_renderData.pMonitor->inFullscreenMode()) /* Fullscreen window with pass cm enabled */; + || (((*PPASS && canPassHDRSurface) || + (*PPASS == 1 && !isHDRSurface && m_renderData.pMonitor->m_cmType != NCMType::CM_HDR && m_renderData.pMonitor->m_cmType != NCMType::CM_HDR_EDID)) && + m_renderData.pMonitor->inFullscreenMode()) /* Fullscreen window with pass cm enabled */; if (!skipCM && !usingFinalShader && (texType == TEXTURE_RGBA || texType == TEXTURE_RGBX)) shader = &m_shaders->m_shCM;