Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/config/ConfigDescriptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,13 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
.type = CONFIG_OPTION_CHOICE,
.data = SConfigOptionDescription::SChoiceData{0, "disable,always,ondemand,ignore"},
},
SConfigOptionDescription{
.value = "render:cm_sdr_eotf",
.description = "Default transfer function for displaying SDR apps. 0 - Treat unspecified as sRGB, 1 - Treat unspecified as Gamma 2.2, 2 - Treat "
"unspecified and sRGB as Gamma 2.2",
.type = CONFIG_OPTION_CHOICE,
.data = SConfigOptionDescription::SChoiceData{0, "srgb,gamma22,gamma22force"},
},

/*
* cursor:
Expand Down
5 changes: 5 additions & 0 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,7 @@ CConfigManager::CConfigManager() {
registerConfigVar("render:cm_auto_hdr", Hyprlang::INT{1});
registerConfigVar("render:new_render_scheduling", Hyprlang::INT{0});
registerConfigVar("render:non_shader_cm", Hyprlang::INT{2});
registerConfigVar("render:cm_sdr_eotf", Hyprlang::INT{0});

registerConfigVar("ecosystem:no_update_news", Hyprlang::INT{0});
registerConfigVar("ecosystem:no_donation_nag", Hyprlang::INT{0});
Expand Down Expand Up @@ -842,6 +843,7 @@ CConfigManager::CConfigManager() {
m_config->addSpecialConfigValue("monitorv2", "mirror", {STRVAL_EMPTY});
m_config->addSpecialConfigValue("monitorv2", "bitdepth", {STRVAL_EMPTY}); // TODO use correct type
m_config->addSpecialConfigValue("monitorv2", "cm", {"auto"});
m_config->addSpecialConfigValue("monitorv2", "sdr_eotf", Hyprlang::INT{0});
m_config->addSpecialConfigValue("monitorv2", "sdrbrightness", Hyprlang::FLOAT{1.0});
m_config->addSpecialConfigValue("monitorv2", "sdrsaturation", Hyprlang::FLOAT{1.0});
m_config->addSpecialConfigValue("monitorv2", "vrr", Hyprlang::INT{0});
Expand Down Expand Up @@ -1115,6 +1117,9 @@ std::optional<std::string> CConfigManager::handleMonitorv2(const std::string& ou
VAL = m_config->getSpecialConfigValuePtr("monitorv2", "cm", output.c_str());
if (VAL && VAL->m_bSetByUser)
parser.parseCM(std::any_cast<Hyprlang::STRING>(VAL->getValue()));
VAL = m_config->getSpecialConfigValuePtr("monitorv2", "sdr_eotf", output.c_str());
if (VAL && VAL->m_bSetByUser)
parser.rule().sdrEotf = std::any_cast<Hyprlang::INT>(VAL->getValue());
VAL = m_config->getSpecialConfigValuePtr("monitorv2", "sdrbrightness", output.c_str());
if (VAL && VAL->m_bSetByUser)
parser.rule().sdrBrightness = std::any_cast<Hyprlang::FLOAT>(VAL->getValue());
Expand Down
29 changes: 20 additions & 9 deletions src/helpers/Monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,32 +465,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) {
auto oldImageDescription = m_imageDescription;
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 > 0 ? NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22 : NColorManagement::CM_TRANSFER_FUNCTION_SRGB) :
(cmSdrEotf == 1 ? NColorManagement::CM_TRANSFER_FUNCTION_SRGB : NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22);

switch (cmType) {
case NCMType::CM_SRGB: m_imageDescription = {}; break; // assumes SImageDescirption defaults to sRGB
case NCMType::CM_SRGB: m_imageDescription = {.transferFunction = chosenSdrEotf}; break; // assumes SImageDescription defaults to sRGB
case NCMType::CM_WIDE:
m_imageDescription = {.primariesNameSet = true,
m_imageDescription = {.transferFunction = chosenSdrEotf,
.primariesNameSet = true,
.primariesNamed = NColorManagement::CM_PRIMARIES_BT2020,
.primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_BT2020)};
break;
case NCMType::CM_DCIP3:
m_imageDescription = {.primariesNameSet = true,
m_imageDescription = {.transferFunction = chosenSdrEotf,
.primariesNameSet = true,
.primariesNamed = NColorManagement::CM_PRIMARIES_DCI_P3,
.primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_DCI_P3)};
break;
case NCMType::CM_DP3:
m_imageDescription = {.primariesNameSet = true,
m_imageDescription = {.transferFunction = chosenSdrEotf,
.primariesNameSet = true,
.primariesNamed = NColorManagement::CM_PRIMARIES_DISPLAY_P3,
.primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_DISPLAY_P3)};
break;
case NCMType::CM_ADOBE:
m_imageDescription = {.primariesNameSet = true,
m_imageDescription = {.transferFunction = chosenSdrEotf,
.primariesNameSet = true,
.primariesNamed = NColorManagement::CM_PRIMARIES_ADOBE_RGB,
.primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_ADOBE_RGB)};
break;
case NCMType::CM_EDID:
m_imageDescription = {.primariesNameSet = false,
m_imageDescription = {.transferFunction = chosenSdrEotf,
.primariesNameSet = true,
.primariesNamed = NColorManagement::CM_PRIMARIES_BT2020,
.primaries = {
.red = {.x = m_output->parsedEDID.chromaticityCoords->red.x, .y = m_output->parsedEDID.chromaticityCoords->red.y},
Expand Down Expand Up @@ -868,14 +877,16 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
default: break;
}

m_sdrEotf = RULE->sdrEotf;

m_sdrMinLuminance = RULE->sdrMinLuminance;
m_sdrMaxLuminance = RULE->sdrMaxLuminance;

m_minLuminance = RULE->minLuminance;
m_maxLuminance = RULE->maxLuminance;
m_maxAvgLuminance = RULE->maxAvgLuminance;

applyCMType(m_cmType);
applyCMType(m_cmType, m_sdrEotf);

m_sdrSaturation = RULE->sdrSaturation;
m_sdrBrightness = RULE->sdrBrightness;
Expand Down
4 changes: 3 additions & 1 deletion src/helpers/Monitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct SMonitorRule {
std::string mirrorOf = "";
bool enable10bit = false;
NCMType::eCMType cmType = NCMType::CM_SRGB;
int sdrEotf = 0;
float sdrSaturation = 1.0f; // SDR -> HDR
float sdrBrightness = 1.0f; // SDR -> HDR

Expand Down Expand Up @@ -131,6 +132,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;
float m_sdrSaturation = 1.0f;
float m_sdrBrightness = 1.0f;
float m_sdrMinLuminance = 0.2f;
Expand Down Expand Up @@ -272,7 +274,7 @@ class CMonitor {
// methods
void onConnect(bool noRule);
void onDisconnect(bool destroy = false);
void applyCMType(NCMType::eCMType cmType);
void applyCMType(NCMType::eCMType cmType, int cmSdrEotf);
bool applyMonitorRule(SMonitorRule* pMonitorRule, bool force = false);
void addDamage(const pixman_region32_t* rg);
void addDamage(const CRegion& rg);
Expand Down
14 changes: 12 additions & 2 deletions src/render/OpenGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1552,14 +1552,24 @@ static std::map<std::pair<uint32_t, uint32_t>, std::array<GLfloat, 9>> primaries

static bool isSDR2HDR(const NColorManagement::SImageDescription& imageDescription, const NColorManagement::SImageDescription& targetImageDescription) {
// might be too strict
return imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_SRGB &&
return (imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_SRGB ||
imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22) &&
(targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ||
targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_HLG);
}

void CHyprOpenGLImpl::passCMUniforms(SShader& shader, const NColorManagement::SImageDescription& imageDescription,
const NColorManagement::SImageDescription& targetImageDescription, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance) {
shader.setUniformInt(SHADER_SOURCE_TF, imageDescription.transferFunction);
static auto PSDREOTF = CConfigValue<Hyprlang::INT>("render:cm_sdr_eotf");

if (m_renderData.surface.valid() &&
((!m_renderData.surface->m_colorManagement.valid() && *PSDREOTF >= 1) ||
(*PSDREOTF == 2 && m_renderData.surface->m_colorManagement.valid() &&
imageDescription.transferFunction == NColorManagement::eTransferFunction::CM_TRANSFER_FUNCTION_SRGB))) {
shader.setUniformInt(SHADER_SOURCE_TF, NColorManagement::eTransferFunction::CM_TRANSFER_FUNCTION_GAMMA22);
} else
shader.setUniformInt(SHADER_SOURCE_TF, imageDescription.transferFunction);

shader.setUniformInt(SHADER_TARGET_TF, targetImageDescription.transferFunction);

const auto targetPrimaries = targetImageDescription.primariesNameSet || targetImageDescription.primaries == SPCPRimaries{} ?
Expand Down
5 changes: 3 additions & 2 deletions src/render/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1555,9 +1555,10 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
if (*PAUTOHDR && !(pMonitor->inHDR() && configuredHDR)) {
// modify or restore monitor image description for auto-hdr
// FIXME ok for now, will need some other logic if monitor image description can be modified some other way
const auto targetCM = wantHDR ? (*PAUTOHDR == 2 ? NCMType::CM_HDR_EDID : NCMType::CM_HDR) : pMonitor->m_cmType;
const auto targetCM = wantHDR ? (*PAUTOHDR == 2 ? NCMType::CM_HDR_EDID : NCMType::CM_HDR) : pMonitor->m_cmType;
const auto targetSDREOTF = pMonitor->m_sdrEotf;
Debug::log(INFO, "[CM] Auto HDR: changing monitor cm to {}", sc<uint8_t>(targetCM));
pMonitor->applyCMType(targetCM);
pMonitor->applyCMType(targetCM, targetSDREOTF);
pMonitor->m_previousFSWindow.reset(); // trigger CTM update
}
Debug::log(INFO, wantHDR ? "[CM] Updating HDR metadata from monitor" : "[CM] Restoring SDR mode");
Expand Down
2 changes: 1 addition & 1 deletion src/render/shaders/glsl/CM.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ vec4 doColorManagement(vec4 pixColor, int srcTF, int dstTF, mat4x2 dstPrimaries)
mat3 dstxyz = primaries2xyz(dstPrimaries);
pixColor = tonemap(pixColor, dstxyz);
pixColor = fromLinearNit(pixColor, dstTF, dstTFRange);
if (srcTF == CM_TRANSFER_FUNCTION_SRGB && dstTF == CM_TRANSFER_FUNCTION_ST2084_PQ) {
if ((srcTF == CM_TRANSFER_FUNCTION_SRGB || srcTF == CM_TRANSFER_FUNCTION_GAMMA22) && dstTF == CM_TRANSFER_FUNCTION_ST2084_PQ) {
pixColor = saturate(pixColor, dstxyz, sdrSaturation);
pixColor.rgb *= sdrBrightnessMultiplier;
}
Expand Down
Loading