summaryrefslogtreecommitdiff
path: root/src/helpers/Monitor.cpp
diff options
context:
space:
mode:
authorUjinT34 <41110182+UjinT34@users.noreply.github.com>2025-08-29 14:31:07 +0300
committerGitHub <noreply@github.com>2025-08-29 13:31:07 +0200
commit05a1c0aa7395d19213e587c83089ecbd7b92085c (patch)
tree32a26c919feddafaf9e91c1c6274515622be39d3 /src/helpers/Monitor.cpp
parent790e544689e7f7a906ee291a6715bc6833b15606 (diff)
renderer: Fix CM for DS and SDR passthrough (#11503)
Diffstat (limited to 'src/helpers/Monitor.cpp')
-rw-r--r--src/helpers/Monitor.cpp74
1 files changed, 65 insertions, 9 deletions
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp
index a2a6ff0d..e5b60597 100644
--- a/src/helpers/Monitor.cpp
+++ b/src/helpers/Monitor.cpp
@@ -988,8 +988,8 @@ bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
static auto PMINRR = CConfigValue<Hyprlang::INT>("cursor:min_refresh_rate");
// skip scheduling extra frames for fullsreen apps with vrr
- const bool shouldSkip = m_activeWorkspace && m_activeWorkspace->m_hasFullscreenWindow && m_activeWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN &&
- (*PNOBREAK == 1 || (*PNOBREAK == 2 && m_activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) && m_output->state->state().adaptiveSync;
+ const bool shouldSkip = inFullscreenMode() && (*PNOBREAK == 1 || (*PNOBREAK == 2 && m_activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) &&
+ m_output->state->state().adaptiveSync;
// keep requested minimum refresh rate
if (shouldSkip && *PMINRR && m_lastPresentationTimer.getMillis() > 1000.0f / *PMINRR) {
@@ -1631,24 +1631,27 @@ uint8_t CMonitor::isTearingBlocked(bool full) {
}
if (!*PTEARINGENABLED) {
- Debug::log(WARN, "Tearing commit requested but the master switch general:allow_tearing is off, ignoring");
reasons |= TC_USER;
- if (!full)
+ if (!full) {
+ Debug::log(WARN, "Tearing commit requested but the master switch general:allow_tearing is off, ignoring");
return reasons;
+ }
}
if (g_pHyprOpenGL->m_renderData.mouseZoomFactor != 1.0) {
- Debug::log(WARN, "Tearing commit requested but scale factor is not 1, ignoring");
reasons |= TC_ZOOM;
- if (!full)
+ if (!full) {
+ Debug::log(WARN, "Tearing commit requested but scale factor is not 1, ignoring");
return reasons;
+ }
}
if (!m_tearingState.canTear) {
- Debug::log(WARN, "Tearing commit requested but monitor doesn't support it, ignoring");
reasons |= TC_SUPPORT;
- if (!full)
+ if (!full) {
+ Debug::log(WARN, "Tearing commit requested but monitor doesn't support it, ignoring");
return reasons;
+ }
}
if (m_solitaryClient.expired()) {
@@ -1671,6 +1674,7 @@ bool CMonitor::updateTearing() {
uint16_t CMonitor::isDSBlocked(bool full) {
uint16_t reasons = 0;
static auto PDIRECTSCANOUT = CConfigValue<Hyprlang::INT>("render:direct_scanout");
+ static auto PPASS = CConfigValue<Hyprlang::INT>("render:cm_fs_passthrough");
if (*PDIRECTSCANOUT == 0) {
reasons |= DS_BLOCK_USER;
@@ -1734,8 +1738,14 @@ uint16_t CMonitor::isDSBlocked(bool full) {
// we can't scanout shm buffers.
const auto params = PSURFACE->m_current.buffer->dmabuf();
- if (!params.success || !PSURFACE->m_current.texture->m_eglImage /* dmabuf */)
+ if (!params.success || !PSURFACE->m_current.texture->m_eglImage /* dmabuf */) {
reasons |= DS_BLOCK_DMA;
+ if (!full)
+ return reasons;
+ }
+
+ if (!canNoShaderCM() && (!inHDR() || (PSURFACE->m_colorManagement.valid() && PSURFACE->m_colorManagement->isWindowsScRGB())) && *PPASS != 1)
+ reasons |= DS_BLOCK_CM;
return reasons;
}
@@ -1935,6 +1945,52 @@ bool CMonitor::inHDR() {
return m_output->state->state().hdrMetadata.hdmi_metadata_type1.eotf == 2;
}
+bool CMonitor::inFullscreenMode() {
+ return m_activeWorkspace && m_activeWorkspace->m_hasFullscreenWindow && m_activeWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN;
+}
+
+std::optional<NColorManagement::SImageDescription> CMonitor::getFSImageDescription() {
+ if (!inFullscreenMode())
+ return {};
+
+ const auto FS_WINDOW = m_activeWorkspace->getFullscreenWindow();
+ if (!FS_WINDOW)
+ return {}; // should be unreachable
+
+ const auto ROOT_SURF = FS_WINDOW->m_wlSurface->resource();
+ const auto SURF = ROOT_SURF->findWithCM();
+ return SURF ? SURF->m_colorManagement->imageDescription() : SImageDescription{};
+}
+
+bool CMonitor::needsCM() {
+ return getFSImageDescription() != m_imageDescription;
+}
+
+// TODO support more drm properties
+bool CMonitor::canNoShaderCM() {
+ const auto SRC_DESC = getFSImageDescription();
+ if (!SRC_DESC.has_value())
+ return false;
+
+ if (SRC_DESC.value() == m_imageDescription)
+ return true; // no CM needed
+
+ if (SRC_DESC->icc.fd >= 0 || m_imageDescription.icc.fd >= 0)
+ return false; // no ICC support
+
+ // only primaries differ
+ if (SRC_DESC->transferFunction == m_imageDescription.transferFunction && SRC_DESC->transferFunctionPower == m_imageDescription.transferFunctionPower &&
+ 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;
+}
+
+bool CMonitor::doesNoShaderCM() {
+ return m_noShaderCTM;
+}
+
CMonitorState::CMonitorState(CMonitor* owner) : m_owner(owner) {
;
}