diff options
| author | UjinT34 <41110182+UjinT34@users.noreply.github.com> | 2026-05-08 00:28:34 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-07 22:28:34 +0100 |
| commit | 39af3901b389f792a55176041dec9211c82ed1c9 (patch) | |
| tree | cfe9a9b84e56d2553934aa1600ffe5789aaa667b /src/helpers/Monitor.cpp | |
| parent | c18186a519d188a3ae8caf9947a5420a25590b82 (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.cpp | 88 |
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); |
