summaryrefslogtreecommitdiff
path: root/src/helpers
diff options
context:
space:
mode:
authorUjinT34 <41110182+UjinT34@users.noreply.github.com>2025-06-15 13:15:18 +0300
committerGitHub <noreply@github.com>2025-06-15 12:15:18 +0200
commitc3894d9288e99500df4fc4704bcc614ea8d520ec (patch)
tree083ac23210b978f554e3a42aa6fc618e4a861d9e /src/helpers
parent3db3baa19e55a039c1a64a29c8e9aaadea4e5f01 (diff)
config/monitor: Add monitor v2 HDR rules (#10623)
Diffstat (limited to 'src/helpers')
-rw-r--r--src/helpers/Monitor.cpp46
-rw-r--r--src/helpers/Monitor.hpp29
2 files changed, 68 insertions, 7 deletions
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp
index c2f1ab5b..df9c4a8e 100644
--- a/src/helpers/Monitor.cpp
+++ b/src/helpers/Monitor.cpp
@@ -464,7 +464,9 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
&& ((DELTALESSTHAN(m_position.x, RULE->offset.x, 1) && DELTALESSTHAN(m_position.y, RULE->offset.y, 1)) || RULE->offset == Vector2D(-INT32_MAX, -INT32_MAX))
/* other properties hadnt changed */
&& m_transform == RULE->transform && RULE->enable10bit == m_enabled10bit && RULE->cmType == m_cmType && RULE->sdrSaturation == m_sdrSaturation &&
- RULE->sdrBrightness == m_sdrBrightness && !std::memcmp(&m_customDrmMode, &RULE->drmMode, sizeof(m_customDrmMode))) {
+ RULE->sdrBrightness == m_sdrBrightness && RULE->sdrMinLuminance == m_minLuminance && RULE->sdrMaxLuminance == m_maxLuminance &&
+ RULE->supportsWideColor == m_supportsWideColor && RULE->supportsHDR == m_supportsHDR && RULE->minLuminance == m_minLuminance && RULE->maxLuminance == m_maxLuminance &&
+ RULE->maxAvgLuminance == m_maxAvgLuminance && !std::memcmp(&m_customDrmMode, &RULE->drmMode, sizeof(m_customDrmMode))) {
Debug::log(LOG, "Not applying a new rule to {} because it's already applied!", m_name);
@@ -734,15 +736,16 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
m_enabled10bit = set10bit;
+ m_supportsWideColor = RULE->supportsHDR;
+ m_supportsHDR = RULE->supportsHDR;
+
auto oldImageDescription = m_imageDescription;
m_cmType = RULE->cmType;
switch (m_cmType) {
- case CM_AUTO: m_cmType = m_enabled10bit && m_output->parsedEDID.supportsBT2020 ? CM_WIDE : CM_SRGB; break;
+ case CM_AUTO: m_cmType = m_enabled10bit && supportsWideColor() ? CM_WIDE : CM_SRGB; break;
case CM_EDID: m_cmType = m_output->parsedEDID.chromaticityCoords.has_value() ? CM_EDID : CM_SRGB; break;
case CM_HDR:
- case CM_HDR_EDID:
- m_cmType = m_output->parsedEDID.supportsBT2020 && m_output->parsedEDID.hdrMetadata.has_value() && m_output->parsedEDID.hdrMetadata->supportsPQ ? m_cmType : CM_SRGB;
- break;
+ case CM_HDR_EDID: m_cmType = supportsHDR() ? m_cmType : CM_SRGB; break;
default: break;
}
switch (m_cmType) {
@@ -788,6 +791,19 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
break;
default: UNREACHABLE();
}
+
+ m_sdrMinLuminance = RULE->sdrMinLuminance;
+ m_sdrMaxLuminance = RULE->sdrMaxLuminance;
+
+ m_minLuminance = RULE->minLuminance;
+ if (m_minLuminance >= 0)
+ m_imageDescription.luminances.min = m_minLuminance;
+ m_maxLuminance = RULE->maxLuminance;
+ if (m_maxLuminance >= 0)
+ m_imageDescription.luminances.max = m_maxLuminance;
+ m_maxAvgLuminance = RULE->maxAvgLuminance;
+ if (m_maxAvgLuminance >= 0)
+ m_imageDescription.luminances.reference = m_maxAvgLuminance;
if (oldImageDescription != m_imageDescription)
PROTO::colorManagement->onMonitorImageDescriptionChanged(m_self);
@@ -1601,6 +1617,26 @@ void CMonitor::onCursorMovedOnMonitor() {
m_tearingState.frameScheduledWhileBusy = true;
}
+bool CMonitor::supportsWideColor() {
+ return m_supportsWideColor || m_output->parsedEDID.supportsBT2020;
+}
+
+bool CMonitor::supportsHDR() {
+ return supportsWideColor() && (m_supportsHDR || (m_output->parsedEDID.hdrMetadata.has_value() ? m_output->parsedEDID.hdrMetadata->supportsPQ : false));
+}
+
+float CMonitor::minLuminance() {
+ return m_minLuminance >= 0 ? m_minLuminance : (m_output->parsedEDID.hdrMetadata.has_value() ? m_output->parsedEDID.hdrMetadata->desiredContentMinLuminance : 0);
+}
+
+int CMonitor::maxLuminance() {
+ return m_maxLuminance >= 0 ? m_maxLuminance : (m_output->parsedEDID.hdrMetadata.has_value() ? m_output->parsedEDID.hdrMetadata->desiredContentMaxLuminance : 80);
+}
+
+int CMonitor::maxAvgLuminance() {
+ return m_maxAvgLuminance >= 0 ? m_maxAvgLuminance : (m_output->parsedEDID.hdrMetadata.has_value() ? m_output->parsedEDID.hdrMetadata->desiredMaxFrameAverageLuminance : 80);
+}
+
CMonitorState::CMonitorState(CMonitor* owner) : m_owner(owner) {
;
}
diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp
index 4dc4ad88..0f35a423 100644
--- a/src/helpers/Monitor.hpp
+++ b/src/helpers/Monitor.hpp
@@ -56,8 +56,19 @@ struct SMonitorRule {
eCMType cmType = CM_SRGB;
float sdrSaturation = 1.0f; // SDR -> HDR
float sdrBrightness = 1.0f; // SDR -> HDR
- drmModeModeInfo drmMode = {};
- std::optional<int> vrr;
+
+ bool supportsWideColor = false; // false does nothing, true overrides EDID
+ bool supportsHDR = false; // false does nothing, true overrides EDID
+ float sdrMinLuminance = 0.2f; // SDR -> HDR
+ int sdrMaxLuminance = 80; // SDR -> HDR
+
+ // Incorrect values will result in reduced luminance range or incorrect tonemapping. Shouldn't damage the HW. Use with care in case of a faulty monitor firmware.
+ float minLuminance = -1.0f; // >= 0 overrides EDID
+ int maxLuminance = -1; // >= 0 overrides EDID
+ int maxAvgLuminance = -1; // >= 0 overrides EDID
+
+ drmModeModeInfo drmMode = {};
+ std::optional<int> vrr;
};
class CMonitor;
@@ -128,6 +139,8 @@ class CMonitor {
eCMType m_cmType = CM_SRGB;
float m_sdrSaturation = 1.0f;
float m_sdrBrightness = 1.0f;
+ float m_sdrMinLuminance = 0.2f;
+ int m_sdrMaxLuminance = 80;
bool m_createdByUser = false;
bool m_isUnsafeFallback = false;
@@ -214,6 +227,12 @@ class CMonitor {
void debugLastPresentation(const std::string& message);
void onMonitorFrame();
+ bool supportsWideColor();
+ bool supportsHDR();
+ float minLuminance();
+ int maxLuminance();
+ int maxAvgLuminance();
+
bool m_enabled = false;
bool m_renderingInitPassed = false;
WP<CWindow> m_previousFSWindow;
@@ -244,4 +263,10 @@ class CMonitor {
CHyprSignalListener presented;
CHyprSignalListener commit;
} m_listeners;
+
+ bool m_supportsWideColor = false;
+ bool m_supportsHDR = false;
+ float m_minLuminance = -1.0f;
+ int m_maxLuminance = -1;
+ int m_maxAvgLuminance = -1;
};