diff options
| author | UjinT34 <41110182+UjinT34@users.noreply.github.com> | 2025-03-14 02:15:18 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-14 00:15:18 +0100 |
| commit | 8c97cb7858e5d6c35d1a055930904346fb4248db (patch) | |
| tree | 87d7e30393f9177d035183f273be54f03b9451d5 /src/helpers/Monitor.cpp | |
| parent | e86d3a14e46d19d8a47f8ceb6410546715d45f10 (diff) | |
renderer: add simple color management (#9506)
Adds proper color management and transformations for CM surfaces.
Diffstat (limited to 'src/helpers/Monitor.cpp')
| -rw-r--r-- | src/helpers/Monitor.cpp | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index df672caf..ce30b8e7 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -2,6 +2,7 @@ #include "MiscFunctions.hpp" #include "../macros.hpp" #include "math/Math.hpp" +#include "../protocols/ColorManagement.hpp" #include "sync/SyncReleaser.hpp" #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" @@ -412,7 +413,8 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) { if (!force && DELTALESSTHAN(vecPixelSize.x, RULE->resolution.x, 1) && DELTALESSTHAN(vecPixelSize.y, RULE->resolution.y, 1) && DELTALESSTHAN(refreshRate, RULE->refreshRate, 1) && setScale == RULE->scale && ((DELTALESSTHAN(vecPosition.x, RULE->offset.x, 1) && DELTALESSTHAN(vecPosition.y, RULE->offset.y, 1)) || RULE->offset == Vector2D(-INT32_MAX, -INT32_MAX)) && - transform == RULE->transform && RULE->enable10bit == enabled10bit && !std::memcmp(&customDrmMode, &RULE->drmMode, sizeof(customDrmMode))) { + transform == RULE->transform && RULE->enable10bit == enabled10bit && RULE->cmType == cmType && RULE->sdrSaturation == sdrSaturation && + RULE->sdrBrightness == sdrBrightness && !std::memcmp(&customDrmMode, &RULE->drmMode, sizeof(customDrmMode))) { Debug::log(LOG, "Not applying a new rule to {} because it's already applied!", szName); @@ -670,6 +672,66 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) { enabled10bit = set10bit; + auto oldImageDescription = imageDescription; + cmType = RULE->cmType; + switch (cmType) { + case CM_AUTO: cmType = enabled10bit && output->parsedEDID.supportsBT2020 ? CM_WIDE : CM_SRGB; break; + case CM_EDID: cmType = output->parsedEDID.chromaticityCoords.has_value() ? CM_EDID : CM_SRGB; break; + case CM_HDR: + case CM_HDR_EDID: + cmType = output->parsedEDID.supportsBT2020 && output->parsedEDID.hdrMetadata.has_value() && output->parsedEDID.hdrMetadata->supportsPQ ? cmType : CM_SRGB; + break; + default: break; + } + switch (cmType) { + case CM_SRGB: imageDescription = {}; break; // assumes SImageDescirption defaults to sRGB + case CM_WIDE: + imageDescription = {.primariesNameSet = true, + .primariesNamed = NColorManagement::CM_PRIMARIES_BT2020, + .primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_BT2020)}; + break; + case CM_EDID: + imageDescription = {.primariesNameSet = false, + .primariesNamed = NColorManagement::CM_PRIMARIES_BT2020, + .primaries = { + .red = {.x = output->parsedEDID.chromaticityCoords->red.x, .y = output->parsedEDID.chromaticityCoords->red.y}, + .green = {.x = output->parsedEDID.chromaticityCoords->green.x, .y = output->parsedEDID.chromaticityCoords->green.y}, + .blue = {.x = output->parsedEDID.chromaticityCoords->blue.x, .y = output->parsedEDID.chromaticityCoords->blue.y}, + .white = {.x = output->parsedEDID.chromaticityCoords->white.x, .y = output->parsedEDID.chromaticityCoords->white.y}, + }}; + break; + case CM_HDR: + imageDescription = {.transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ, + .primariesNameSet = true, + .primariesNamed = NColorManagement::CM_PRIMARIES_BT2020, + .primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_BT2020), + .luminances = {.min = 0, .max = 10000, .reference = 203}}; + break; + case CM_HDR_EDID: + imageDescription = {.transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ, + .primariesNameSet = false, + .primariesNamed = NColorManagement::CM_PRIMARIES_BT2020, + .primaries = output->parsedEDID.chromaticityCoords.has_value() ? + NColorManagement::SPCPRimaries{ + .red = {.x = output->parsedEDID.chromaticityCoords->red.x, .y = output->parsedEDID.chromaticityCoords->red.y}, + .green = {.x = output->parsedEDID.chromaticityCoords->green.x, .y = output->parsedEDID.chromaticityCoords->green.y}, + .blue = {.x = output->parsedEDID.chromaticityCoords->blue.x, .y = output->parsedEDID.chromaticityCoords->blue.y}, + .white = {.x = output->parsedEDID.chromaticityCoords->white.x, .y = output->parsedEDID.chromaticityCoords->white.y}, + } : + NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_BT2020), + .luminances = {.min = output->parsedEDID.hdrMetadata->desiredContentMinLuminance, + .max = output->parsedEDID.hdrMetadata->desiredContentMaxLuminance, + .reference = output->parsedEDID.hdrMetadata->desiredMaxFrameAverageLuminance}}; + + break; + default: UNREACHABLE(); + } + if (oldImageDescription != imageDescription) + PROTO::colorManagement->onMonitorImageDescriptionChanged(self); + + sdrSaturation = RULE->sdrSaturation; + sdrBrightness = RULE->sdrBrightness; + Vector2D logicalSize = vecPixelSize / scale; if (!*PDISABLESCALECHECKS && (logicalSize.x != std::round(logicalSize.x) || logicalSize.y != std::round(logicalSize.y))) { // invalid scale, will produce fractional pixels. |
