renderer: better sdr eotf settings (#12812)
This commit is contained in:
parent
0e9196867b
commit
c71fbd854d
9 changed files with 174 additions and 65 deletions
|
|
@ -2,6 +2,7 @@
|
||||||
#include "../../shared.hpp"
|
#include "../../shared.hpp"
|
||||||
#include "../../hyprctlCompat.hpp"
|
#include "../../hyprctlCompat.hpp"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <format>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <hyprutils/os/Process.hpp>
|
#include <hyprutils/os/Process.hpp>
|
||||||
#include <hyprutils/memory/WeakPtr.hpp>
|
#include <hyprutils/memory/WeakPtr.hpp>
|
||||||
|
|
@ -15,40 +16,46 @@ using namespace Hyprutils::Memory;
|
||||||
#define UP CUniquePointer
|
#define UP CUniquePointer
|
||||||
#define SP CSharedPointer
|
#define SP CSharedPointer
|
||||||
|
|
||||||
static bool test() {
|
const static auto SLEEP_DURATIONS = std::array{1, 10};
|
||||||
|
|
||||||
|
static bool test() {
|
||||||
NLog::log("{}Testing process spawning", Colors::GREEN);
|
NLog::log("{}Testing process spawning", Colors::GREEN);
|
||||||
|
|
||||||
// Note: POSIX sleep does not support fractional seconds, so
|
for (const auto duration : SLEEP_DURATIONS) {
|
||||||
// can't sleep for less than 1 second.
|
// Note: POSIX sleep does not support fractional seconds, so
|
||||||
OK(getFromSocket("/dispatch exec sleep 1"));
|
// can't sleep for less than 1 second.
|
||||||
|
OK(getFromSocket(std::format("/dispatch exec sleep {}", duration)));
|
||||||
|
|
||||||
// Ensure that sleep is our child
|
// Ensure that sleep is our child
|
||||||
const std::string sleepPidS = Tests::execAndGet("pgrep sleep");
|
const std::string sleepPidS = Tests::execAndGet("pgrep sleep");
|
||||||
pid_t sleepPid;
|
pid_t sleepPid;
|
||||||
try {
|
try {
|
||||||
sleepPid = std::stoull(sleepPidS);
|
sleepPid = std::stoull(sleepPidS);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
NLog::log("{}Sleep was not spawned or several sleeps are running: pgrep returned '{}'", Colors::RED, sleepPidS);
|
NLog::log("{}Sleep was not spawned or several sleeps are running: pgrep returned '{}'", Colors::RED, sleepPidS);
|
||||||
return false;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string sleepParentComm = Tests::execAndGet("cat \"/proc/$(ps -o ppid:1= -p " + sleepPidS + ")/comm\"");
|
||||||
|
NLog::log("{}Expecting that sleep's parent is Hyprland", Colors::YELLOW);
|
||||||
|
EXPECT_CONTAINS(sleepParentComm, "Hyprland");
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(duration));
|
||||||
|
|
||||||
|
// Ensure that sleep did not become a zombie
|
||||||
|
EXPECT(Tests::processAlive(sleepPid), false);
|
||||||
|
|
||||||
|
// kill all
|
||||||
|
NLog::log("{}Killing all windows", Colors::YELLOW);
|
||||||
|
Tests::killAllWindows();
|
||||||
|
|
||||||
|
NLog::log("{}Expecting 0 windows", Colors::YELLOW);
|
||||||
|
EXPECT(Tests::windowCount(), 0);
|
||||||
|
|
||||||
|
return !ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string sleepParentComm = Tests::execAndGet("cat \"/proc/$(ps -o ppid:1= -p " + sleepPidS + ")/comm\"");
|
return false;
|
||||||
NLog::log("{}Expecting that sleep's parent is Hyprland", Colors::YELLOW);
|
|
||||||
EXPECT_CONTAINS(sleepParentComm, "Hyprland");
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
||||||
|
|
||||||
// Ensure that sleep did not become a zombie
|
|
||||||
EXPECT(Tests::processAlive(sleepPid), false);
|
|
||||||
|
|
||||||
// kill all
|
|
||||||
NLog::log("{}Killing all windows", Colors::YELLOW);
|
|
||||||
Tests::killAllWindows();
|
|
||||||
|
|
||||||
NLog::log("{}Expecting 0 windows", Colors::YELLOW);
|
|
||||||
EXPECT(Tests::windowCount(), 0);
|
|
||||||
|
|
||||||
return !ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_TEST_FN(test)
|
REGISTER_TEST_FN(test)
|
||||||
|
|
|
||||||
|
|
@ -1568,10 +1568,10 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "render:cm_sdr_eotf",
|
.value = "render:cm_sdr_eotf",
|
||||||
.description = "Default transfer function for displaying SDR apps. 0 - Use default value (Gamma 2.2), 1 - Treat unspecified as Gamma 2.2, 2 - Treat "
|
.description = "Default transfer function for displaying SDR apps. default - Use default value (Gamma 2.2), gamma22 - Treat unspecified as Gamma 2.2, gamma22force - Treat "
|
||||||
"unspecified and sRGB as Gamma 2.2, 3 - Treat unspecified as sRGB",
|
"unspecified and sRGB as Gamma 2.2, srgb - Treat unspecified as sRGB",
|
||||||
.type = CONFIG_OPTION_CHOICE,
|
.type = CONFIG_OPTION_STRING_SHORT,
|
||||||
.data = SConfigOptionDescription::SChoiceData{0, "default,gamma22,gamma22force,srgb"},
|
.data = SConfigOptionDescription::SStringData{"default"},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "render:commit_timing_enabled",
|
.value = "render:commit_timing_enabled",
|
||||||
|
|
|
||||||
|
|
@ -795,7 +795,7 @@ CConfigManager::CConfigManager() {
|
||||||
registerConfigVar("render:cm_auto_hdr", Hyprlang::INT{1});
|
registerConfigVar("render:cm_auto_hdr", Hyprlang::INT{1});
|
||||||
registerConfigVar("render:new_render_scheduling", Hyprlang::INT{0});
|
registerConfigVar("render:new_render_scheduling", Hyprlang::INT{0});
|
||||||
registerConfigVar("render:non_shader_cm", Hyprlang::INT{3});
|
registerConfigVar("render:non_shader_cm", Hyprlang::INT{3});
|
||||||
registerConfigVar("render:cm_sdr_eotf", Hyprlang::INT{0});
|
registerConfigVar("render:cm_sdr_eotf", {"default"});
|
||||||
registerConfigVar("render:commit_timing_enabled", Hyprlang::INT{1});
|
registerConfigVar("render:commit_timing_enabled", Hyprlang::INT{1});
|
||||||
|
|
||||||
registerConfigVar("ecosystem:no_update_news", Hyprlang::INT{0});
|
registerConfigVar("ecosystem:no_update_news", Hyprlang::INT{0});
|
||||||
|
|
@ -859,7 +859,7 @@ CConfigManager::CConfigManager() {
|
||||||
m_config->addSpecialConfigValue("monitorv2", "mirror", {STRVAL_EMPTY});
|
m_config->addSpecialConfigValue("monitorv2", "mirror", {STRVAL_EMPTY});
|
||||||
m_config->addSpecialConfigValue("monitorv2", "bitdepth", {STRVAL_EMPTY}); // TODO use correct type
|
m_config->addSpecialConfigValue("monitorv2", "bitdepth", {STRVAL_EMPTY}); // TODO use correct type
|
||||||
m_config->addSpecialConfigValue("monitorv2", "cm", {"auto"});
|
m_config->addSpecialConfigValue("monitorv2", "cm", {"auto"});
|
||||||
m_config->addSpecialConfigValue("monitorv2", "sdr_eotf", Hyprlang::INT{0});
|
m_config->addSpecialConfigValue("monitorv2", "sdr_eotf", {"default"});
|
||||||
m_config->addSpecialConfigValue("monitorv2", "sdrbrightness", Hyprlang::FLOAT{1.0});
|
m_config->addSpecialConfigValue("monitorv2", "sdrbrightness", Hyprlang::FLOAT{1.0});
|
||||||
m_config->addSpecialConfigValue("monitorv2", "sdrsaturation", Hyprlang::FLOAT{1.0});
|
m_config->addSpecialConfigValue("monitorv2", "sdrsaturation", Hyprlang::FLOAT{1.0});
|
||||||
m_config->addSpecialConfigValue("monitorv2", "vrr", Hyprlang::INT{0});
|
m_config->addSpecialConfigValue("monitorv2", "vrr", Hyprlang::INT{0});
|
||||||
|
|
@ -1209,8 +1209,18 @@ std::optional<std::string> CConfigManager::handleMonitorv2(const std::string& ou
|
||||||
if (VAL && VAL->m_bSetByUser)
|
if (VAL && VAL->m_bSetByUser)
|
||||||
parser.parseCM(std::any_cast<Hyprlang::STRING>(VAL->getValue()));
|
parser.parseCM(std::any_cast<Hyprlang::STRING>(VAL->getValue()));
|
||||||
VAL = m_config->getSpecialConfigValuePtr("monitorv2", "sdr_eotf", output.c_str());
|
VAL = m_config->getSpecialConfigValuePtr("monitorv2", "sdr_eotf", output.c_str());
|
||||||
if (VAL && VAL->m_bSetByUser)
|
if (VAL && VAL->m_bSetByUser) {
|
||||||
parser.rule().sdrEotf = std::any_cast<Hyprlang::INT>(VAL->getValue());
|
const std::string value = std::any_cast<Hyprlang::STRING>(VAL->getValue());
|
||||||
|
// remap legacy
|
||||||
|
if (value == "0")
|
||||||
|
parser.rule().sdrEotf = NTransferFunction::TF_AUTO;
|
||||||
|
else if (value == "1")
|
||||||
|
parser.rule().sdrEotf = NTransferFunction::TF_SRGB;
|
||||||
|
else if (value == "2")
|
||||||
|
parser.rule().sdrEotf = NTransferFunction::TF_GAMMA22;
|
||||||
|
else
|
||||||
|
parser.rule().sdrEotf = NTransferFunction::fromString(value);
|
||||||
|
}
|
||||||
VAL = m_config->getSpecialConfigValuePtr("monitorv2", "sdrbrightness", output.c_str());
|
VAL = m_config->getSpecialConfigValuePtr("monitorv2", "sdrbrightness", output.c_str());
|
||||||
if (VAL && VAL->m_bSetByUser)
|
if (VAL && VAL->m_bSetByUser)
|
||||||
parser.rule().sdrBrightness = std::any_cast<Hyprlang::FLOAT>(VAL->getValue());
|
parser.rule().sdrBrightness = std::any_cast<Hyprlang::FLOAT>(VAL->getValue());
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include "MiscFunctions.hpp"
|
#include "MiscFunctions.hpp"
|
||||||
#include "../macros.hpp"
|
#include "../macros.hpp"
|
||||||
#include "SharedDefs.hpp"
|
#include "SharedDefs.hpp"
|
||||||
|
#include "../helpers/TransferFunction.hpp"
|
||||||
#include "math/Math.hpp"
|
#include "math/Math.hpp"
|
||||||
#include "../protocols/ColorManagement.hpp"
|
#include "../protocols/ColorManagement.hpp"
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
|
|
@ -29,6 +30,7 @@
|
||||||
#include "../hyprerror/HyprError.hpp"
|
#include "../hyprerror/HyprError.hpp"
|
||||||
#include "../layout/LayoutManager.hpp"
|
#include "../layout/LayoutManager.hpp"
|
||||||
#include "../i18n/Engine.hpp"
|
#include "../i18n/Engine.hpp"
|
||||||
|
#include "../protocols/types/ColorManagement.hpp"
|
||||||
#include "sync/SyncTimeline.hpp"
|
#include "sync/SyncTimeline.hpp"
|
||||||
#include "time/Time.hpp"
|
#include "time/Time.hpp"
|
||||||
#include "../desktop/view/LayerSurface.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; });
|
std::erase_if(g_pCompositor->m_monitors, [&](PHLMONITOR& el) { return el.get() == this; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMonitor::applyCMType(NCMType::eCMType cmType, int cmSdrEotf) {
|
static NColorManagement::eTransferFunction chooseTF(NTransferFunction::eTF tf) {
|
||||||
auto oldImageDescription = m_imageDescription;
|
const auto sdrEOTF = NTransferFunction::fromConfig();
|
||||||
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);
|
|
||||||
|
|
||||||
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 NColorManagement::SImageDescription::SPCMasteringLuminances masteringLuminances = getMasteringLuminances();
|
||||||
|
|
||||||
const auto maxFALL = this->maxFALL();
|
const auto maxFALL = this->maxFALL();
|
||||||
const auto maxCLL = this->maxCLL();
|
const auto maxCLL = this->maxCLL();
|
||||||
|
|
||||||
switch (cmType) {
|
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:
|
case NCMType::CM_WIDE:
|
||||||
m_imageDescription = CImageDescription::from({.transferFunction = chosenSdrEotf,
|
m_imageDescription = CImageDescription::from({.transferFunction = chosenSdrEotf,
|
||||||
.primariesNameSet = true,
|
.primariesNameSet = true,
|
||||||
|
|
@ -2152,11 +2175,11 @@ bool CMonitor::canNoShaderCM() {
|
||||||
if (SRC_DESC_VALUE.icc.fd >= 0 || m_imageDescription->value().icc.fd >= 0)
|
if (SRC_DESC_VALUE.icc.fd >= 0 || m_imageDescription->value().icc.fd >= 0)
|
||||||
return false; // no ICC support
|
return false; // no ICC support
|
||||||
|
|
||||||
static auto PSDREOTF = CConfigValue<Hyprlang::INT>("render:cm_sdr_eotf");
|
const auto sdrEOTF = NTransferFunction::fromConfig();
|
||||||
// only primaries differ
|
// only primaries differ
|
||||||
return (
|
return (
|
||||||
(SRC_DESC_VALUE.transferFunction == m_imageDescription->value().transferFunction ||
|
(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)) &&
|
m_imageDescription->value().transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22)) &&
|
||||||
SRC_DESC_VALUE.transferFunctionPower == m_imageDescription->value().transferFunctionPower &&
|
SRC_DESC_VALUE.transferFunctionPower == m_imageDescription->value().transferFunctionPower &&
|
||||||
(!inHDR() || SRC_DESC_VALUE.luminances == m_imageDescription->value().luminances)
|
(!inHDR() || SRC_DESC_VALUE.luminances == m_imageDescription->value().luminances)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
#include <aquamarine/allocator/Swapchain.hpp>
|
#include <aquamarine/allocator/Swapchain.hpp>
|
||||||
#include <hyprutils/os/FileDescriptor.hpp>
|
#include <hyprutils/os/FileDescriptor.hpp>
|
||||||
|
|
||||||
|
#include "../helpers/TransferFunction.hpp"
|
||||||
|
|
||||||
class CMonitorFrameScheduler;
|
class CMonitorFrameScheduler;
|
||||||
|
|
||||||
// Enum for the different types of auto directions, e.g. auto-left, auto-up.
|
// Enum for the different types of auto directions, e.g. auto-left, auto-up.
|
||||||
|
|
@ -50,7 +52,7 @@ struct SMonitorRule {
|
||||||
std::string mirrorOf = "";
|
std::string mirrorOf = "";
|
||||||
bool enable10bit = false;
|
bool enable10bit = false;
|
||||||
NCMType::eCMType cmType = NCMType::CM_SRGB;
|
NCMType::eCMType cmType = NCMType::CM_SRGB;
|
||||||
int sdrEotf = 0;
|
NTransferFunction::eTF sdrEotf = NTransferFunction::TF_DEFAULT;
|
||||||
float sdrSaturation = 1.0f; // SDR -> HDR
|
float sdrSaturation = 1.0f; // SDR -> HDR
|
||||||
float sdrBrightness = 1.0f; // SDR -> HDR
|
float sdrBrightness = 1.0f; // SDR -> HDR
|
||||||
Desktop::CReservedArea reservedArea;
|
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_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.
|
bool m_enabled10bit = false; // as above, this can be TRUE even if 10 bit failed.
|
||||||
NCMType::eCMType m_cmType = NCMType::CM_SRGB;
|
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_sdrSaturation = 1.0f;
|
||||||
float m_sdrBrightness = 1.0f;
|
float m_sdrBrightness = 1.0f;
|
||||||
float m_sdrMinLuminance = 0.2f;
|
float m_sdrMinLuminance = 0.2f;
|
||||||
|
|
@ -284,7 +286,7 @@ class CMonitor {
|
||||||
// methods
|
// methods
|
||||||
void onConnect(bool noRule);
|
void onConnect(bool noRule);
|
||||||
void onDisconnect(bool destroy = false);
|
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);
|
bool applyMonitorRule(SMonitorRule* pMonitorRule, bool force = false);
|
||||||
void addDamage(const pixman_region32_t* rg);
|
void addDamage(const pixman_region32_t* rg);
|
||||||
void addDamage(const CRegion& rg);
|
void addDamage(const CRegion& rg);
|
||||||
|
|
|
||||||
35
src/helpers/TransferFunction.cpp
Normal file
35
src/helpers/TransferFunction.cpp
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
19
src/helpers/TransferFunction.hpp
Normal file
19
src/helpers/TransferFunction.hpp
Normal file
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
@ -298,12 +298,17 @@ namespace NColorManagement {
|
||||||
|
|
||||||
using PImageDescription = WP<const CImageDescription>;
|
using PImageDescription = WP<const CImageDescription>;
|
||||||
|
|
||||||
static const auto DEFAULT_IMAGE_DESCRIPTION = CImageDescription::from(SImageDescription{});
|
static const auto DEFAULT_IMAGE_DESCRIPTION = CImageDescription::from(SImageDescription{.transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22,
|
||||||
|
.primariesNameSet = true,
|
||||||
|
.primariesNamed = NColorManagement::CM_PRIMARIES_SRGB,
|
||||||
|
.primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_SRGB),
|
||||||
|
.luminances = {.min = SDR_MIN_LUMINANCE, .max = 80, .reference = 80}});
|
||||||
|
|
||||||
static const auto DEFAULT_HDR_IMAGE_DESCRIPTION = CImageDescription::from(SImageDescription{.transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ,
|
static const auto DEFAULT_HDR_IMAGE_DESCRIPTION = CImageDescription::from(SImageDescription{.transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ,
|
||||||
.primariesNameSet = true,
|
.primariesNameSet = true,
|
||||||
.primariesNamed = NColorManagement::CM_PRIMARIES_BT2020,
|
.primariesNamed = NColorManagement::CM_PRIMARIES_BT2020,
|
||||||
.primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_BT2020),
|
.primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_BT2020),
|
||||||
.luminances = {.min = 0, .max = 10000, .reference = 203}});
|
.luminances = {.min = HDR_MIN_LUMINANCE, .max = 10000, .reference = 203}});
|
||||||
;
|
;
|
||||||
static const auto SCRGB_IMAGE_DESCRIPTION = CImageDescription::from(SImageDescription{
|
static const auto SCRGB_IMAGE_DESCRIPTION = CImageDescription::from(SImageDescription{
|
||||||
.windowsScRGB = true,
|
.windowsScRGB = true,
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../helpers/MiscFunctions.hpp"
|
#include "../helpers/MiscFunctions.hpp"
|
||||||
#include "../helpers/CursorShapes.hpp"
|
#include "../helpers/CursorShapes.hpp"
|
||||||
|
#include "../helpers/TransferFunction.hpp"
|
||||||
#include "../config/ConfigValue.hpp"
|
#include "../config/ConfigValue.hpp"
|
||||||
#include "../config/ConfigManager.hpp"
|
#include "../config/ConfigManager.hpp"
|
||||||
#include "../managers/PointerManager.hpp"
|
#include "../managers/PointerManager.hpp"
|
||||||
|
|
@ -1245,13 +1246,20 @@ static bool isHDR2SDR(const NColorManagement::SImageDescription& imageDescriptio
|
||||||
|
|
||||||
void CHyprOpenGLImpl::passCMUniforms(WP<CShader> shader, const NColorManagement::PImageDescription imageDescription,
|
void CHyprOpenGLImpl::passCMUniforms(WP<CShader> shader, const NColorManagement::PImageDescription imageDescription,
|
||||||
const NColorManagement::PImageDescription targetImageDescription, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance) {
|
const NColorManagement::PImageDescription targetImageDescription, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance) {
|
||||||
static auto PSDREOTF = CConfigValue<Hyprlang::INT>("render:cm_sdr_eotf");
|
const auto sdrEOTF = NTransferFunction::fromConfig();
|
||||||
|
|
||||||
if (m_renderData.surface.valid() &&
|
if (m_renderData.surface.valid()) {
|
||||||
((!m_renderData.surface->m_colorManagement.valid() && *PSDREOTF >= 1) ||
|
if (m_renderData.surface->m_colorManagement.valid()) {
|
||||||
(*PSDREOTF == 2 && m_renderData.surface->m_colorManagement.valid() &&
|
if (sdrEOTF == NTransferFunction::TF_FORCED_GAMMA22 && imageDescription->value().transferFunction == NColorManagement::eTransferFunction::CM_TRANSFER_FUNCTION_SRGB)
|
||||||
imageDescription->value().transferFunction == NColorManagement::eTransferFunction::CM_TRANSFER_FUNCTION_SRGB))) {
|
shader->setUniformInt(SHADER_SOURCE_TF, NColorManagement::eTransferFunction::CM_TRANSFER_FUNCTION_GAMMA22);
|
||||||
shader->setUniformInt(SHADER_SOURCE_TF, NColorManagement::eTransferFunction::CM_TRANSFER_FUNCTION_GAMMA22);
|
else
|
||||||
|
shader->setUniformInt(SHADER_SOURCE_TF, imageDescription->value().transferFunction);
|
||||||
|
} else if (sdrEOTF == NTransferFunction::TF_SRGB)
|
||||||
|
shader->setUniformInt(SHADER_SOURCE_TF, NColorManagement::eTransferFunction::CM_TRANSFER_FUNCTION_SRGB);
|
||||||
|
else if (sdrEOTF == NTransferFunction::TF_GAMMA22 || sdrEOTF == NTransferFunction::TF_FORCED_GAMMA22)
|
||||||
|
shader->setUniformInt(SHADER_SOURCE_TF, NColorManagement::eTransferFunction::CM_TRANSFER_FUNCTION_GAMMA22);
|
||||||
|
else
|
||||||
|
shader->setUniformInt(SHADER_SOURCE_TF, imageDescription->value().transferFunction);
|
||||||
} else
|
} else
|
||||||
shader->setUniformInt(SHADER_SOURCE_TF, imageDescription->value().transferFunction);
|
shader->setUniformInt(SHADER_SOURCE_TF, imageDescription->value().transferFunction);
|
||||||
|
|
||||||
|
|
@ -1377,16 +1385,16 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c
|
||||||
tex->setTexParameter(GL_TEXTURE_MIN_FILTER, tex->minFilter);
|
tex->setTexParameter(GL_TEXTURE_MIN_FILTER, tex->minFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isHDRSurface = m_renderData.surface.valid() && m_renderData.surface->m_colorManagement.valid() ? m_renderData.surface->m_colorManagement->isHDR() : false;
|
const bool isHDRSurface = m_renderData.surface.valid() && m_renderData.surface->m_colorManagement.valid() ? m_renderData.surface->m_colorManagement->isHDR() : false;
|
||||||
const bool canPassHDRSurface = isHDRSurface && !m_renderData.surface->m_colorManagement->isWindowsScRGB(); // windows scRGB requires CM shader
|
const bool canPassHDRSurface = isHDRSurface && !m_renderData.surface->m_colorManagement->isWindowsScRGB(); // windows scRGB requires CM shader
|
||||||
|
|
||||||
const auto imageDescription = m_renderData.surface.valid() && m_renderData.surface->m_colorManagement.valid() ?
|
const auto imageDescription = m_renderData.surface.valid() && m_renderData.surface->m_colorManagement.valid() ?
|
||||||
CImageDescription::from(m_renderData.surface->m_colorManagement->imageDescription()) :
|
CImageDescription::from(m_renderData.surface->m_colorManagement->imageDescription()) :
|
||||||
(data.cmBackToSRGB ? data.cmBackToSRGBSource->m_imageDescription : DEFAULT_IMAGE_DESCRIPTION);
|
(data.cmBackToSRGB ? data.cmBackToSRGBSource->m_imageDescription : DEFAULT_IMAGE_DESCRIPTION);
|
||||||
|
|
||||||
static auto PSDREOTF = CConfigValue<Hyprlang::INT>("render:cm_sdr_eotf");
|
const auto sdrEOTF = NTransferFunction::fromConfig();
|
||||||
auto chosenSdrEotf = *PSDREOTF != 3 ? NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22 : NColorManagement::CM_TRANSFER_FUNCTION_SRGB;
|
auto chosenSdrEotf = sdrEOTF != NTransferFunction::TF_SRGB ? NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22 : NColorManagement::CM_TRANSFER_FUNCTION_SRGB;
|
||||||
const auto targetImageDescription =
|
const auto targetImageDescription =
|
||||||
data.cmBackToSRGB ? CImageDescription::from(NColorManagement::SImageDescription{.transferFunction = chosenSdrEotf}) : m_renderData.pMonitor->m_imageDescription;
|
data.cmBackToSRGB ? CImageDescription::from(NColorManagement::SImageDescription{.transferFunction = chosenSdrEotf}) : m_renderData.pMonitor->m_imageDescription;
|
||||||
|
|
||||||
const bool skipCM = !*PENABLECM || !m_cmSupported /* CM unsupported or disabled */
|
const bool skipCM = !*PENABLECM || !m_cmSupported /* CM unsupported or disabled */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue