summaryrefslogtreecommitdiff
path: root/src/helpers/Monitor.cpp
diff options
context:
space:
mode:
authorUjinT34 <41110182+UjinT34@users.noreply.github.com>2026-05-08 00:28:34 +0300
committerGitHub <noreply@github.com>2026-05-07 22:28:34 +0100
commit39af3901b389f792a55176041dec9211c82ed1c9 (patch)
treecfe9a9b84e56d2553934aa1600ffe5789aaa667b /src/helpers/Monitor.cpp
parentc18186a519d188a3ae8caf9947a5420a25590b82 (diff)
renderer: more FP16 fixes (#14070)
* fix fp16 blur with invalidation * restore tonemap code * fix fade outs * add sdr compat for unaware surfaces * use a better work space, not linear, only for sdr * fix hl tf -> wp tf * cache workbuffer descriptions * linear not normalised WIP * clear offload fb * CM math * fix includes * use precalculated cm for shadows * inner glow cm * quad cm * fix unmodified copy * codegen * cache color CM * mark blur dirty when CM/DS changes * avoid icc workbuffer * fp16 blur finish hack * fix output hdr luminances * use srgb for mirroring/sharing with fp16 * defaults people --------- Co-authored-by: Vaxry <vaxry@vaxry.net>
Diffstat (limited to 'src/helpers/Monitor.cpp')
-rw-r--r--src/helpers/Monitor.cpp88
1 files changed, 80 insertions, 8 deletions
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp
index 958c8480..eebc2daa 100644
--- a/src/helpers/Monitor.cpp
+++ b/src/helpers/Monitor.cpp
@@ -591,7 +591,19 @@ void CMonitor::applyCMType(NCMType::eCMType cmType, NTransferFunction::eTF cmSdr
.maxCLL = maxCLL,
.maxFALL = maxFALL});
break;
- case NCMType::CM_HDR: m_imageDescription = DEFAULT_HDR_IMAGE_DESCRIPTION; break;
+ case NCMType::CM_HDR:
+ m_imageDescription = CImageDescription::from({.transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ,
+ .primariesNameSet = true,
+ .primariesNamed = NColorManagement::CM_PRIMARIES_BT2020,
+ .primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_BT2020),
+ .masteringPrimaries = masteringPrimaries,
+ .luminances = {.min = DEFAULT_HDR_IMAGE_DESCRIPTION->value().getTFMinLuminance(),
+ .max = DEFAULT_HDR_IMAGE_DESCRIPTION->value().getTFMaxLuminance(),
+ .reference = DEFAULT_HDR_IMAGE_DESCRIPTION->value().getTFRefLuminance()},
+ .masteringLuminances = masteringLuminances,
+ .maxCLL = maxCLL,
+ .maxFALL = maxFALL});
+ break;
case NCMType::CM_HDR_EDID:
m_imageDescription = CImageDescription::from(
{.transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ,
@@ -609,16 +621,17 @@ void CMonitor::applyCMType(NCMType::eCMType cmType, NTransferFunction::eTF cmSdr
break;
default: UNREACHABLE();
}
- if ((m_minLuminance >= 0 || m_maxLuminance >= 0 || m_maxAvgLuminance >= 0) && (cmType == NCMType::CM_HDR || cmType == NCMType::CM_HDR_EDID))
+ if ((minLuminance() >= 0 || maxLuminance() > 0) && (cmType == NCMType::CM_HDR || cmType == NCMType::CM_HDR_EDID))
m_imageDescription = m_imageDescription->with({
- .min = m_minLuminance >= 0 ? m_minLuminance : m_imageDescription->value().luminances.min, //
- .max = m_maxLuminance >= 0 ? m_maxLuminance : m_imageDescription->value().luminances.max, //
+ .min = minLuminance() >= 0 ? minLuminance() : m_imageDescription->value().luminances.min, //
+ .max = maxLuminance() > 0 ? maxLuminance() : m_imageDescription->value().luminances.max, //
.reference = m_imageDescription->value().luminances.reference //
});
if (oldImageDescription != m_imageDescription) {
if (PROTO::colorManagement)
PROTO::colorManagement->onMonitorImageDescriptionChanged(m_self);
+ m_blurFBDirty = true;
}
}
@@ -2066,6 +2079,20 @@ bool CMonitor::attemptDirectScanout() {
return true;
}
+void CMonitor::handleDSleave() {
+ Log::logger->log(Log::DEBUG, "Left a direct scanout.");
+ m_lastScanout.reset();
+ m_previousFSWindow.reset(); // recalc fs settings
+ m_directScanoutIsActive = false;
+
+ // reset DRM format, but only if needed since it might modeset
+ if (m_output->state->state().drmFormat != m_prevDrmFormat)
+ m_output->state->setFormat(m_prevDrmFormat);
+
+ m_drmFormat = m_prevDrmFormat;
+ m_blurFBDirty = true;
+}
+
bool CMonitor::canAttemptDirectScanoutFast() const {
return !m_solitaryClient.expired() || !m_lastScanout.expired() || m_directScanoutIsActive;
}
@@ -2559,9 +2586,21 @@ bool CMonitor::needsUnmodifiedCopy() {
}
bool CMonitor::useFP16() {
- static const auto PFP16 = CConfigValue<Hyprlang::INT>("render:use_fp16");
- bool shouldUse = *PFP16 == 1 || (*PFP16 == 2 && m_imageDescription->value().transferFunction == CM_TRANSFER_FUNCTION_ST2084_PQ);
- static bool usedBefore = shouldUse;
+ static const auto PFP16 = CConfigValue<Hyprlang::INT>("render:use_fp16");
+
+ auto isSRGB = [this] {
+ if (m_imageDescription->value().transferFunction != CM_TRANSFER_FUNCTION_SRGB && m_imageDescription->value().transferFunction != CM_TRANSFER_FUNCTION_GAMMA22)
+ return false;
+
+ if (m_imageDescription->value().primariesNamed != CM_PRIMARIES_SRGB)
+ return false;
+
+ return true;
+ };
+
+ // Auto: use FP16 if the monitor is not sRGB
+ bool shouldUse = *PFP16 == 1 || (*PFP16 == 2 && !isSRGB());
+ static bool usedBefore = shouldUse;
if (usedBefore != shouldUse) {
usedBefore = shouldUse;
m_blurFBDirty = true;
@@ -2569,9 +2608,42 @@ bool CMonitor::useFP16() {
return shouldUse;
}
+PImageDescription CMonitor::workBufferImageDescription() {
+ static const auto PFP16TF = CConfigValue<Hyprlang::INT>("render:fp16_sdr_tf");
+
+ if (!useFP16() && !m_imageDescription->value().icc.present)
+ return m_imageDescription;
+
+ const auto& value = m_imageDescription->value();
+
+ const bool isHDRLikeTF =
+ value.transferFunction == CM_TRANSFER_FUNCTION_ST2084_PQ || value.transferFunction == CM_TRANSFER_FUNCTION_HLG || value.transferFunction == CM_TRANSFER_FUNCTION_EXT_LINEAR;
+
+ const auto& cached = m_cachedInternalDescription->value();
+
+ // HDR
+ if (isHDRLikeTF || value.windowsScRGB || *PFP16TF != 0) {
+ if (cached.transferFunction != LINEAR_IMAGE_DESCRIPTION->value().transferFunction || cached.luminances != value.luminances)
+ m_cachedInternalDescription = LINEAR_IMAGE_DESCRIPTION->with(value.luminances);
+ return m_cachedInternalDescription;
+ }
+
+ // SDR
+ if (cached.transferFunction != chooseTF(m_sdrEotf))
+ m_cachedInternalDescription = CImageDescription::from(SImageDescription{
+ .transferFunction = chooseTF(m_sdrEotf),
+ .primariesNameSet = true,
+ // render:keep_unmodified_copy and other conditions that trigger MRT for screen sharing expect a work buffer with sRGB primaries
+ .primariesNamed = NColorManagement::CM_PRIMARIES_SRGB,
+ .primaries = NColorPrimaries::BT709,
+ });
+
+ return m_cachedInternalDescription;
+}
+
WP<CMonitorResources> CMonitor::resources() {
const auto DRM_FORMAT = useFP16() ? DRM_FORMAT_ABGR16161616F : m_output->state->state().drmFormat;
- const auto DESC = useFP16() ? LINEAR_IMAGE_DESCRIPTION : m_imageDescription;
+ const auto DESC = workBufferImageDescription();
if (!m_resources || m_resources->m_drmFormat != DRM_FORMAT || m_resources->m_size != m_pixelSize)
m_resources = makeUnique<CMonitorResources>(m_self, DRM_FORMAT, m_pixelSize, DESC);