diff options
| author | UjinT34 <41110182+UjinT34@users.noreply.github.com> | 2026-02-26 15:01:59 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-26 12:01:59 +0000 |
| commit | c71fbd854dfdedaae011f4b8b1fdb81f8054b309 (patch) | |
| tree | 89d600037ab206f800acca1b2567eb60af67c7e9 /src/helpers | |
| parent | 0e9196867b4f602e1e5a599d4f3565faff615b3c (diff) | |
renderer: better sdr eotf settings (#12812)
Diffstat (limited to 'src/helpers')
| -rw-r--r-- | src/helpers/Monitor.cpp | 41 | ||||
| -rw-r--r-- | src/helpers/Monitor.hpp | 8 | ||||
| -rw-r--r-- | src/helpers/TransferFunction.cpp | 35 | ||||
| -rw-r--r-- | src/helpers/TransferFunction.hpp | 19 |
4 files changed, 91 insertions, 12 deletions
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index a29edc91..f287bff3 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -2,6 +2,7 @@ #include "MiscFunctions.hpp" #include "../macros.hpp" #include "SharedDefs.hpp" +#include "../helpers/TransferFunction.hpp" #include "math/Math.hpp" #include "../protocols/ColorManagement.hpp" #include "../Compositor.hpp" @@ -29,6 +30,7 @@ #include "../hyprerror/HyprError.hpp" #include "../layout/LayoutManager.hpp" #include "../i18n/Engine.hpp" +#include "../protocols/types/ColorManagement.hpp" #include "sync/SyncTimeline.hpp" #include "time/Time.hpp" #include "../desktop/view/LayerSurface.hpp" @@ -480,20 +482,41 @@ void CMonitor::onDisconnect(bool destroy) { std::erase_if(g_pCompositor->m_monitors, [&](PHLMONITOR& el) { return el.get() == this; }); } -void CMonitor::applyCMType(NCMType::eCMType cmType, int cmSdrEotf) { - auto oldImageDescription = m_imageDescription; - static auto PSDREOTF = CConfigValue<Hyprlang::INT>("render:cm_sdr_eotf"); - auto chosenSdrEotf = cmSdrEotf == 0 ? (*PSDREOTF != 3 ? NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22 : NColorManagement::CM_TRANSFER_FUNCTION_SRGB) : - (cmSdrEotf == 1 ? NColorManagement::CM_TRANSFER_FUNCTION_SRGB : NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22); +static NColorManagement::eTransferFunction chooseTF(NTransferFunction::eTF tf) { + const auto sdrEOTF = NTransferFunction::fromConfig(); - const auto masteringPrimaries = getMasteringPrimaries(); + switch (tf) { + case NTransferFunction::TF_DEFAULT: + case NTransferFunction::TF_GAMMA22: + case NTransferFunction::TF_FORCED_GAMMA22: return NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22; + case NTransferFunction::TF_SRGB: return NColorManagement::CM_TRANSFER_FUNCTION_SRGB; + + case NTransferFunction::TF_AUTO: // use global setting + switch (sdrEOTF) { + case NTransferFunction::TF_AUTO: return NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22; + default: return chooseTF(sdrEOTF); + } + + default: UNREACHABLE(); + } +} + +void CMonitor::applyCMType(NCMType::eCMType cmType, NTransferFunction::eTF cmSdrEotf) { + auto oldImageDescription = m_imageDescription; + const auto chosenSdrEotf = chooseTF(cmSdrEotf); + + const auto masteringPrimaries = getMasteringPrimaries(); const NColorManagement::SImageDescription::SPCMasteringLuminances masteringLuminances = getMasteringLuminances(); const auto maxFALL = this->maxFALL(); const auto maxCLL = this->maxCLL(); switch (cmType) { - case NCMType::CM_SRGB: m_imageDescription = CImageDescription::from({.transferFunction = chosenSdrEotf}); break; // assumes SImageDescription defaults to sRGB + case NCMType::CM_SRGB: + m_imageDescription = CImageDescription::from({.transferFunction = chosenSdrEotf, + .primariesNamed = NColorManagement::CM_PRIMARIES_SRGB, + .primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_SRGB)}); + break; // assumes SImageDescription defaults to sRGB case NCMType::CM_WIDE: m_imageDescription = CImageDescription::from({.transferFunction = chosenSdrEotf, .primariesNameSet = true, @@ -2152,11 +2175,11 @@ bool CMonitor::canNoShaderCM() { if (SRC_DESC_VALUE.icc.fd >= 0 || m_imageDescription->value().icc.fd >= 0) return false; // no ICC support - static auto PSDREOTF = CConfigValue<Hyprlang::INT>("render:cm_sdr_eotf"); + const auto sdrEOTF = NTransferFunction::fromConfig(); // only primaries differ return ( (SRC_DESC_VALUE.transferFunction == m_imageDescription->value().transferFunction || - (*PSDREOTF == 2 && SRC_DESC_VALUE.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_SRGB && + (sdrEOTF == NTransferFunction::TF_FORCED_GAMMA22 && SRC_DESC_VALUE.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_SRGB && m_imageDescription->value().transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22)) && SRC_DESC_VALUE.transferFunctionPower == m_imageDescription->value().transferFunctionPower && (!inHDR() || SRC_DESC_VALUE.luminances == m_imageDescription->value().luminances) diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 37f3f16a..72e0cf66 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -23,6 +23,8 @@ #include <aquamarine/allocator/Swapchain.hpp> #include <hyprutils/os/FileDescriptor.hpp> +#include "../helpers/TransferFunction.hpp" + class CMonitorFrameScheduler; // Enum for the different types of auto directions, e.g. auto-left, auto-up. @@ -50,7 +52,7 @@ struct SMonitorRule { std::string mirrorOf = ""; bool enable10bit = false; NCMType::eCMType cmType = NCMType::CM_SRGB; - int sdrEotf = 0; + NTransferFunction::eTF sdrEotf = NTransferFunction::TF_DEFAULT; float sdrSaturation = 1.0f; // SDR -> HDR float sdrBrightness = 1.0f; // SDR -> HDR Desktop::CReservedArea reservedArea; @@ -137,7 +139,7 @@ class CMonitor { bool m_vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it. bool m_enabled10bit = false; // as above, this can be TRUE even if 10 bit failed. NCMType::eCMType m_cmType = NCMType::CM_SRGB; - int m_sdrEotf = 0; + NTransferFunction::eTF m_sdrEotf = NTransferFunction::TF_DEFAULT; float m_sdrSaturation = 1.0f; float m_sdrBrightness = 1.0f; float m_sdrMinLuminance = 0.2f; @@ -284,7 +286,7 @@ class CMonitor { // methods void onConnect(bool noRule); void onDisconnect(bool destroy = false); - void applyCMType(NCMType::eCMType cmType, int cmSdrEotf); + void applyCMType(NCMType::eCMType cmType, NTransferFunction::eTF cmSdrEotf); bool applyMonitorRule(SMonitorRule* pMonitorRule, bool force = false); void addDamage(const pixman_region32_t* rg); void addDamage(const CRegion& rg); diff --git a/src/helpers/TransferFunction.cpp b/src/helpers/TransferFunction.cpp new file mode 100644 index 00000000..935f77fe --- /dev/null +++ b/src/helpers/TransferFunction.cpp @@ -0,0 +1,35 @@ +#include "TransferFunction.hpp" +#include "../config/ConfigValue.hpp" +#include "../event/EventBus.hpp" +#include <string> +#include <unordered_map> +#include <hyprlang.hpp> + +using namespace NTransferFunction; + +static std::unordered_map<std::string, eTF> const table = {{"default", TF_DEFAULT}, {"0", TF_DEFAULT}, {"auto", TF_AUTO}, {"srgb", TF_SRGB}, + {"3", TF_SRGB}, {"gamma22", TF_GAMMA22}, {"1", TF_GAMMA22}, {"gamma22force", TF_FORCED_GAMMA22}, + {"2", TF_FORCED_GAMMA22}}; + +eTF NTransferFunction::fromString(const std::string tfName) { + auto it = table.find(tfName); + if (it == table.end()) + return TF_DEFAULT; + return it->second; +} + +std::string NTransferFunction::toString(eTF tf) { + for (const auto& [key, value] : table) { + if (value == tf) + return key; + } + return ""; +} + +eTF NTransferFunction::fromConfig() { + static auto PSDREOTF = CConfigValue<Hyprlang::STRING>("render:cm_sdr_eotf"); + static auto sdrEOTF = NTransferFunction::fromString(*PSDREOTF); + static auto P = Event::bus()->m_events.config.reloaded.listen([]() { sdrEOTF = NTransferFunction::fromString(*PSDREOTF); }); + + return sdrEOTF; +} diff --git a/src/helpers/TransferFunction.hpp b/src/helpers/TransferFunction.hpp new file mode 100644 index 00000000..cbf35f37 --- /dev/null +++ b/src/helpers/TransferFunction.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include <cstdint> +#include <string> + +namespace NTransferFunction { + enum eTF : uint8_t { + TF_DEFAULT = 0, + TF_AUTO = 1, + TF_SRGB = 2, + TF_GAMMA22 = 3, + TF_FORCED_GAMMA22 = 4, + }; + + eTF fromString(const std::string tfName); + std::string toString(eTF tf); + + eTF fromConfig(); +} |
