summaryrefslogtreecommitdiff
path: root/src/helpers
diff options
context:
space:
mode:
authorUjinT34 <41110182+UjinT34@users.noreply.github.com>2026-02-26 15:01:59 +0300
committerGitHub <noreply@github.com>2026-02-26 12:01:59 +0000
commitc71fbd854dfdedaae011f4b8b1fdb81f8054b309 (patch)
tree89d600037ab206f800acca1b2567eb60af67c7e9 /src/helpers
parent0e9196867b4f602e1e5a599d4f3565faff615b3c (diff)
renderer: better sdr eotf settings (#12812)
Diffstat (limited to 'src/helpers')
-rw-r--r--src/helpers/Monitor.cpp41
-rw-r--r--src/helpers/Monitor.hpp8
-rw-r--r--src/helpers/TransferFunction.cpp35
-rw-r--r--src/helpers/TransferFunction.hpp19
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();
+}