color management: change brightness information names to be shorter and more correct
Brightness is a loose word for how bright we perceive things to be, but the values we're using are about objective measurements, about luminance instead.
This commit is contained in:
parent
280594354c
commit
15589c9997
22 changed files with 108 additions and 108 deletions
|
@ -116,8 +116,8 @@ std::optional<OutputLayerBeginFrameInfo> EglGbmLayerSurface::startRendering(cons
|
||||||
}
|
}
|
||||||
if (enableColormanagement) {
|
if (enableColormanagement) {
|
||||||
m_surface->intermediaryColorDescription = ColorDescription(colorDescription.containerColorimetry(), NamedTransferFunction::linear,
|
m_surface->intermediaryColorDescription = ColorDescription(colorDescription.containerColorimetry(), NamedTransferFunction::linear,
|
||||||
colorDescription.sdrBrightness(), colorDescription.minHdrBrightness(),
|
colorDescription.referenceLuminance(), colorDescription.minLuminance(),
|
||||||
colorDescription.maxFrameAverageBrightness(), colorDescription.maxHdrHighlightBrightness(),
|
colorDescription.maxAverageLuminance(), colorDescription.maxHdrLuminance(),
|
||||||
colorDescription.containerColorimetry(), colorDescription.sdrColorimetry());
|
colorDescription.containerColorimetry(), colorDescription.sdrColorimetry());
|
||||||
} else {
|
} else {
|
||||||
m_surface->intermediaryColorDescription = colorDescription;
|
m_surface->intermediaryColorDescription = colorDescription;
|
||||||
|
@ -188,12 +188,12 @@ bool EglGbmLayerSurface::endRendering(const QRegion &damagedRegion, OutputFrame
|
||||||
GLFramebuffer::pushFramebuffer(fbo);
|
GLFramebuffer::pushFramebuffer(fbo);
|
||||||
ShaderBinder binder = m_surface->iccShader ? ShaderBinder(m_surface->iccShader->shader()) : ShaderBinder(ShaderTrait::MapTexture | ShaderTrait::TransformColorspace);
|
ShaderBinder binder = m_surface->iccShader ? ShaderBinder(m_surface->iccShader->shader()) : ShaderBinder(ShaderTrait::MapTexture | ShaderTrait::TransformColorspace);
|
||||||
if (m_surface->iccShader) {
|
if (m_surface->iccShader) {
|
||||||
m_surface->iccShader->setUniforms(m_surface->iccProfile, m_surface->intermediaryColorDescription.sdrBrightness(), m_surface->adaptedChannelFactors);
|
m_surface->iccShader->setUniforms(m_surface->iccProfile, m_surface->intermediaryColorDescription.referenceLuminance(), m_surface->adaptedChannelFactors);
|
||||||
} else {
|
} else {
|
||||||
// enforce a 25 nits minimum sdr brightness
|
// enforce a 25 nits minimum sdr brightness
|
||||||
constexpr double minBrightness = 25;
|
constexpr double minBrightness = 25;
|
||||||
const double sdrBrightness = m_surface->intermediaryColorDescription.sdrBrightness();
|
const double referenceLuminance = m_surface->intermediaryColorDescription.referenceLuminance();
|
||||||
const double brightnessFactor = (m_surface->brightness * (1 - (minBrightness / sdrBrightness))) + (minBrightness / sdrBrightness);
|
const double brightnessFactor = (m_surface->brightness * (1 - (minBrightness / referenceLuminance))) + (minBrightness / referenceLuminance);
|
||||||
QMatrix4x4 ctm;
|
QMatrix4x4 ctm;
|
||||||
ctm(0, 0) = m_surface->adaptedChannelFactors.x() * brightnessFactor;
|
ctm(0, 0) = m_surface->adaptedChannelFactors.x() * brightnessFactor;
|
||||||
ctm(1, 1) = m_surface->adaptedChannelFactors.y() * brightnessFactor;
|
ctm(1, 1) = m_surface->adaptedChannelFactors.y() * brightnessFactor;
|
||||||
|
@ -201,8 +201,8 @@ bool EglGbmLayerSurface::endRendering(const QRegion &damagedRegion, OutputFrame
|
||||||
binder.shader()->setUniform(GLShader::Mat4Uniform::ColorimetryTransformation, ctm);
|
binder.shader()->setUniform(GLShader::Mat4Uniform::ColorimetryTransformation, ctm);
|
||||||
binder.shader()->setUniform(GLShader::IntUniform::SourceNamedTransferFunction, int(m_surface->intermediaryColorDescription.transferFunction()));
|
binder.shader()->setUniform(GLShader::IntUniform::SourceNamedTransferFunction, int(m_surface->intermediaryColorDescription.transferFunction()));
|
||||||
binder.shader()->setUniform(GLShader::IntUniform::DestinationNamedTransferFunction, int(m_surface->targetColorDescription.transferFunction()));
|
binder.shader()->setUniform(GLShader::IntUniform::DestinationNamedTransferFunction, int(m_surface->targetColorDescription.transferFunction()));
|
||||||
binder.shader()->setUniform(GLShader::FloatUniform::SdrBrightness, m_surface->intermediaryColorDescription.sdrBrightness());
|
binder.shader()->setUniform(GLShader::FloatUniform::SdrBrightness, m_surface->intermediaryColorDescription.referenceLuminance());
|
||||||
binder.shader()->setUniform(GLShader::FloatUniform::MaxHdrBrightness, m_surface->intermediaryColorDescription.maxHdrHighlightBrightness().value_or(800));
|
binder.shader()->setUniform(GLShader::FloatUniform::MaxHdrBrightness, m_surface->intermediaryColorDescription.maxHdrLuminance().value_or(800));
|
||||||
}
|
}
|
||||||
QMatrix4x4 mat;
|
QMatrix4x4 mat;
|
||||||
mat.scale(1, -1);
|
mat.scale(1, -1);
|
||||||
|
|
|
@ -381,10 +381,10 @@ ColorDescription DrmOutput::createColorDescription(const std::shared_ptr<OutputC
|
||||||
// TODO the EDID can contain a gamma value, use that when available and colorSource == ColorProfileSource::EDID
|
// TODO the EDID can contain a gamma value, use that when available and colorSource == ColorProfileSource::EDID
|
||||||
const NamedTransferFunction transferFunction = effectiveHdr ? NamedTransferFunction::PerceptualQuantizer : NamedTransferFunction::gamma22;
|
const NamedTransferFunction transferFunction = effectiveHdr ? NamedTransferFunction::PerceptualQuantizer : NamedTransferFunction::gamma22;
|
||||||
const double minBrightness = effectiveHdr ? props->minBrightnessOverride.value_or(m_state.minBrightnessOverride).value_or(m_connector->edid()->desiredMinLuminance()) : 0;
|
const double minBrightness = effectiveHdr ? props->minBrightnessOverride.value_or(m_state.minBrightnessOverride).value_or(m_connector->edid()->desiredMinLuminance()) : 0;
|
||||||
const double maxAverageBrightness = effectiveHdr ? props->maxAverageBrightnessOverride.value_or(m_state.maxAverageBrightnessOverride).value_or(m_connector->edid()->desiredMaxFrameAverageLuminance().value_or(m_state.sdrBrightness)) : 200;
|
const double maxAverageBrightness = effectiveHdr ? props->maxAverageBrightnessOverride.value_or(m_state.maxAverageBrightnessOverride).value_or(m_connector->edid()->desiredMaxFrameAverageLuminance().value_or(m_state.referenceLuminance)) : 200;
|
||||||
const double maxPeakBrightness = effectiveHdr ? props->maxPeakBrightnessOverride.value_or(m_state.maxPeakBrightnessOverride).value_or(m_connector->edid()->desiredMaxLuminance().value_or(800)) : 200;
|
const double maxPeakBrightness = effectiveHdr ? props->maxPeakBrightnessOverride.value_or(m_state.maxPeakBrightnessOverride).value_or(m_connector->edid()->desiredMaxLuminance().value_or(800)) : 200;
|
||||||
const double sdrBrightness = effectiveHdr ? props->sdrBrightness.value_or(m_state.sdrBrightness) : maxPeakBrightness;
|
const double referenceLuminance = effectiveHdr ? props->referenceLuminance.value_or(m_state.referenceLuminance) : maxPeakBrightness;
|
||||||
return ColorDescription(containerColorimetry, transferFunction, sdrBrightness, minBrightness, maxAverageBrightness, maxPeakBrightness, masteringColorimetry, sdrColorimetry);
|
return ColorDescription(containerColorimetry, transferFunction, referenceLuminance, minBrightness, maxAverageBrightness, maxPeakBrightness, masteringColorimetry, sdrColorimetry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrmOutput::applyQueuedChanges(const std::shared_ptr<OutputChangeSet> &props)
|
void DrmOutput::applyQueuedChanges(const std::shared_ptr<OutputChangeSet> &props)
|
||||||
|
@ -405,7 +405,7 @@ void DrmOutput::applyQueuedChanges(const std::shared_ptr<OutputChangeSet> &props
|
||||||
next.overscan = m_pipeline->overscan();
|
next.overscan = m_pipeline->overscan();
|
||||||
next.rgbRange = m_pipeline->rgbRange();
|
next.rgbRange = m_pipeline->rgbRange();
|
||||||
next.highDynamicRange = props->highDynamicRange.value_or(m_state.highDynamicRange);
|
next.highDynamicRange = props->highDynamicRange.value_or(m_state.highDynamicRange);
|
||||||
next.sdrBrightness = props->sdrBrightness.value_or(m_state.sdrBrightness);
|
next.referenceLuminance = props->referenceLuminance.value_or(m_state.referenceLuminance);
|
||||||
next.wideColorGamut = props->wideColorGamut.value_or(m_state.wideColorGamut);
|
next.wideColorGamut = props->wideColorGamut.value_or(m_state.wideColorGamut);
|
||||||
next.autoRotatePolicy = props->autoRotationPolicy.value_or(m_state.autoRotatePolicy);
|
next.autoRotatePolicy = props->autoRotationPolicy.value_or(m_state.autoRotatePolicy);
|
||||||
next.maxPeakBrightnessOverride = props->maxPeakBrightnessOverride.value_or(m_state.maxPeakBrightnessOverride);
|
next.maxPeakBrightnessOverride = props->maxPeakBrightnessOverride.value_or(m_state.maxPeakBrightnessOverride);
|
||||||
|
|
|
@ -7,7 +7,7 @@ precision highp sampler3D;
|
||||||
in vec2 texcoord0;
|
in vec2 texcoord0;
|
||||||
|
|
||||||
uniform sampler2D src;
|
uniform sampler2D src;
|
||||||
uniform float sdrBrightness;
|
uniform float referenceLuminance;
|
||||||
|
|
||||||
uniform mat4 toXYZD50;
|
uniform mat4 toXYZD50;
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ void main()
|
||||||
{
|
{
|
||||||
vec4 tex = texture2D(src, texcoord0);
|
vec4 tex = texture2D(src, texcoord0);
|
||||||
tex.rgb /= max(tex.a, 0.001);
|
tex.rgb /= max(tex.a, 0.001);
|
||||||
tex.rgb /= sdrBrightness;
|
tex.rgb /= referenceLuminance;
|
||||||
tex.rgb = (toXYZD50 * vec4(tex.rgb, 1.0)).rgb;
|
tex.rgb = (toXYZD50 * vec4(tex.rgb, 1.0)).rgb;
|
||||||
if (Bsize > 0) {
|
if (Bsize > 0) {
|
||||||
tex.rgb = sample1DLut(tex.rgb, Bsampler, Bsize);
|
tex.rgb = sample1DLut(tex.rgb, Bsampler, Bsize);
|
||||||
|
|
|
@ -10,7 +10,7 @@ in vec2 texcoord0;
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
uniform sampler2D src;
|
uniform sampler2D src;
|
||||||
uniform float sdrBrightness;
|
uniform float referenceLuminance;
|
||||||
|
|
||||||
uniform mat4 toXYZD50;
|
uniform mat4 toXYZD50;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ void main()
|
||||||
{
|
{
|
||||||
vec4 tex = texture(src, texcoord0);
|
vec4 tex = texture(src, texcoord0);
|
||||||
tex.rgb /= max(tex.a, 0.001);
|
tex.rgb /= max(tex.a, 0.001);
|
||||||
tex.rgb /= sdrBrightness;
|
tex.rgb /= referenceLuminance;
|
||||||
tex.rgb = (toXYZD50 * vec4(tex.rgb, 1.0)).rgb;
|
tex.rgb = (toXYZD50 * vec4(tex.rgb, 1.0)).rgb;
|
||||||
if (Bsize > 0) {
|
if (Bsize > 0) {
|
||||||
tex.rgb = sample1DLut(tex.rgb, Bsampler, Bsize);
|
tex.rgb = sample1DLut(tex.rgb, Bsampler, Bsize);
|
||||||
|
|
|
@ -22,7 +22,7 @@ IccShader::IccShader()
|
||||||
{
|
{
|
||||||
m_locations = {
|
m_locations = {
|
||||||
.src = m_shader->uniformLocation("src"),
|
.src = m_shader->uniformLocation("src"),
|
||||||
.sdrBrightness = m_shader->uniformLocation("sdrBrightness"),
|
.referenceLuminance = m_shader->uniformLocation("referenceLuminance"),
|
||||||
.toXYZD50 = m_shader->uniformLocation("toXYZD50"),
|
.toXYZD50 = m_shader->uniformLocation("toXYZD50"),
|
||||||
.bsize = m_shader->uniformLocation("Bsize"),
|
.bsize = m_shader->uniformLocation("Bsize"),
|
||||||
.bsampler = m_shader->uniformLocation("Bsampler"),
|
.bsampler = m_shader->uniformLocation("Bsampler"),
|
||||||
|
@ -145,7 +145,7 @@ GLShader *IccShader::shader() const
|
||||||
return m_shader.get();
|
return m_shader.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IccShader::setUniforms(const std::shared_ptr<IccProfile> &profile, float sdrBrightness, const QVector3D &channelFactors)
|
void IccShader::setUniforms(const std::shared_ptr<IccProfile> &profile, float referenceLuminance, const QVector3D &channelFactors)
|
||||||
{
|
{
|
||||||
// this failing can be silently ignored, it should only happen with GPU resets and gets corrected later
|
// this failing can be silently ignored, it should only happen with GPU resets and gets corrected later
|
||||||
setProfile(profile);
|
setProfile(profile);
|
||||||
|
@ -155,7 +155,7 @@ void IccShader::setUniforms(const std::shared_ptr<IccProfile> &profile, float sd
|
||||||
nightColor(1, 1) = channelFactors.y();
|
nightColor(1, 1) = channelFactors.y();
|
||||||
nightColor(2, 2) = channelFactors.z();
|
nightColor(2, 2) = channelFactors.z();
|
||||||
m_shader->setUniform(m_locations.toXYZD50, m_toXYZD50 * nightColor);
|
m_shader->setUniform(m_locations.toXYZD50, m_toXYZD50 * nightColor);
|
||||||
m_shader->setUniform(m_locations.sdrBrightness, sdrBrightness);
|
m_shader->setUniform(m_locations.referenceLuminance, referenceLuminance);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
if (m_B) {
|
if (m_B) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
~IccShader();
|
~IccShader();
|
||||||
|
|
||||||
GLShader *shader() const;
|
GLShader *shader() const;
|
||||||
void setUniforms(const std::shared_ptr<IccProfile> &profile, float sdrBrightness, const QVector3D &channelFactors);
|
void setUniforms(const std::shared_ptr<IccProfile> &profile, float referenceLuminance, const QVector3D &channelFactors);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool setProfile(const std::shared_ptr<IccProfile> &profile);
|
bool setProfile(const std::shared_ptr<IccProfile> &profile);
|
||||||
|
@ -42,7 +42,7 @@ private:
|
||||||
struct Locations
|
struct Locations
|
||||||
{
|
{
|
||||||
int src;
|
int src;
|
||||||
int sdrBrightness;
|
int referenceLuminance;
|
||||||
int toXYZD50;
|
int toXYZD50;
|
||||||
int bsize;
|
int bsize;
|
||||||
int bsampler;
|
int bsampler;
|
||||||
|
|
|
@ -200,30 +200,30 @@ const Colorimetry &Colorimetry::fromName(NamedColorimetry name)
|
||||||
|
|
||||||
const ColorDescription ColorDescription::sRGB = ColorDescription(NamedColorimetry::BT709, NamedTransferFunction::gamma22, 100, 0, 100, 100);
|
const ColorDescription ColorDescription::sRGB = ColorDescription(NamedColorimetry::BT709, NamedTransferFunction::gamma22, 100, 0, 100, 100);
|
||||||
|
|
||||||
ColorDescription::ColorDescription(const Colorimetry &containerColorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, std::optional<double> maxFrameAverageBrightness, std::optional<double> maxHdrHighlightBrightness)
|
ColorDescription::ColorDescription(const Colorimetry &containerColorimetry, NamedTransferFunction tf, double referenceLuminance, double minLuminance, std::optional<double> maxAverageLuminance, std::optional<double> maxHdrLuminance)
|
||||||
: ColorDescription(containerColorimetry, tf, sdrBrightness, minHdrBrightness, maxFrameAverageBrightness, maxHdrHighlightBrightness, std::nullopt, Colorimetry::fromName(NamedColorimetry::BT709))
|
: ColorDescription(containerColorimetry, tf, referenceLuminance, minLuminance, maxAverageLuminance, maxHdrLuminance, std::nullopt, Colorimetry::fromName(NamedColorimetry::BT709))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorDescription::ColorDescription(NamedColorimetry containerColorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, std::optional<double> maxFrameAverageBrightness, std::optional<double> maxHdrHighlightBrightness)
|
ColorDescription::ColorDescription(NamedColorimetry containerColorimetry, NamedTransferFunction tf, double referenceLuminance, double minLuminance, std::optional<double> maxAverageLuminance, std::optional<double> maxHdrLuminance)
|
||||||
: ColorDescription(Colorimetry::fromName(containerColorimetry), tf, sdrBrightness, minHdrBrightness, maxFrameAverageBrightness, maxHdrHighlightBrightness, std::nullopt, Colorimetry::fromName(NamedColorimetry::BT709))
|
: ColorDescription(Colorimetry::fromName(containerColorimetry), tf, referenceLuminance, minLuminance, maxAverageLuminance, maxHdrLuminance, std::nullopt, Colorimetry::fromName(NamedColorimetry::BT709))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorDescription::ColorDescription(const Colorimetry &containerColorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, std::optional<double> maxFrameAverageBrightness, std::optional<double> maxHdrHighlightBrightness, std::optional<Colorimetry> masteringColorimetry, const Colorimetry &sdrColorimetry)
|
ColorDescription::ColorDescription(const Colorimetry &containerColorimetry, NamedTransferFunction tf, double referenceLuminance, double minLuminance, std::optional<double> maxAverageLuminance, std::optional<double> maxHdrLuminance, std::optional<Colorimetry> masteringColorimetry, const Colorimetry &sdrColorimetry)
|
||||||
: m_containerColorimetry(containerColorimetry)
|
: m_containerColorimetry(containerColorimetry)
|
||||||
, m_masteringColorimetry(masteringColorimetry)
|
, m_masteringColorimetry(masteringColorimetry)
|
||||||
, m_transferFunction(tf)
|
, m_transferFunction(tf)
|
||||||
, m_sdrColorimetry(sdrColorimetry)
|
, m_sdrColorimetry(sdrColorimetry)
|
||||||
, m_sdrBrightness(sdrBrightness)
|
, m_referenceLuminance(referenceLuminance)
|
||||||
, m_minHdrBrightness(minHdrBrightness)
|
, m_minLuminance(minLuminance)
|
||||||
, m_maxFrameAverageBrightness(maxFrameAverageBrightness)
|
, m_maxAverageLuminance(maxAverageLuminance)
|
||||||
, m_maxHdrHighlightBrightness(maxHdrHighlightBrightness)
|
, m_maxHdrLuminance(maxHdrLuminance)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorDescription::ColorDescription(NamedColorimetry containerColorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, std::optional<double> maxFrameAverageBrightness, std::optional<double> maxHdrHighlightBrightness, std::optional<Colorimetry> masteringColorimetry, const Colorimetry &sdrColorimetry)
|
ColorDescription::ColorDescription(NamedColorimetry containerColorimetry, NamedTransferFunction tf, double referenceLuminance, double minLuminance, std::optional<double> maxAverageLuminance, std::optional<double> maxHdrLuminance, std::optional<Colorimetry> masteringColorimetry, const Colorimetry &sdrColorimetry)
|
||||||
: ColorDescription(Colorimetry::fromName(containerColorimetry), tf, sdrBrightness, minHdrBrightness, maxFrameAverageBrightness, maxHdrHighlightBrightness, masteringColorimetry, sdrColorimetry)
|
: ColorDescription(Colorimetry::fromName(containerColorimetry), tf, referenceLuminance, minLuminance, maxAverageLuminance, maxHdrLuminance, masteringColorimetry, sdrColorimetry)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,24 +247,24 @@ NamedTransferFunction ColorDescription::transferFunction() const
|
||||||
return m_transferFunction;
|
return m_transferFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
double ColorDescription::sdrBrightness() const
|
double ColorDescription::referenceLuminance() const
|
||||||
{
|
{
|
||||||
return m_sdrBrightness;
|
return m_referenceLuminance;
|
||||||
}
|
}
|
||||||
|
|
||||||
double ColorDescription::minHdrBrightness() const
|
double ColorDescription::minLuminance() const
|
||||||
{
|
{
|
||||||
return m_minHdrBrightness;
|
return m_minLuminance;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<double> ColorDescription::maxFrameAverageBrightness() const
|
std::optional<double> ColorDescription::maxAverageLuminance() const
|
||||||
{
|
{
|
||||||
return m_maxFrameAverageBrightness;
|
return m_maxAverageLuminance;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<double> ColorDescription::maxHdrHighlightBrightness() const
|
std::optional<double> ColorDescription::maxHdrLuminance() const
|
||||||
{
|
{
|
||||||
return m_maxHdrHighlightBrightness;
|
return m_maxHdrLuminance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float srgbToLinear(float sRGB)
|
static float srgbToLinear(float sRGB)
|
||||||
|
@ -317,13 +317,13 @@ static QVector3D clamp(const QVector3D &vect, float min = 0, float max = 1)
|
||||||
return QVector3D(std::clamp(vect.x(), min, max), std::clamp(vect.y(), min, max), std::clamp(vect.z(), min, max));
|
return QVector3D(std::clamp(vect.x(), min, max), std::clamp(vect.y(), min, max), std::clamp(vect.z(), min, max));
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector3D ColorDescription::encodedToNits(const QVector3D &nits, NamedTransferFunction tf, double sdrBrightness)
|
QVector3D ColorDescription::encodedToNits(const QVector3D &nits, NamedTransferFunction tf, double referenceLuminance)
|
||||||
{
|
{
|
||||||
switch (tf) {
|
switch (tf) {
|
||||||
case NamedTransferFunction::sRGB:
|
case NamedTransferFunction::sRGB:
|
||||||
return sdrBrightness * QVector3D(srgbToLinear(nits.x()), srgbToLinear(nits.y()), srgbToLinear(nits.z()));
|
return referenceLuminance * QVector3D(srgbToLinear(nits.x()), srgbToLinear(nits.y()), srgbToLinear(nits.z()));
|
||||||
case NamedTransferFunction::gamma22:
|
case NamedTransferFunction::gamma22:
|
||||||
return sdrBrightness * QVector3D(std::pow(nits.x(), 2.2), std::pow(nits.y(), 2.2), std::pow(nits.z(), 2.2));
|
return referenceLuminance * QVector3D(std::pow(nits.x(), 2.2), std::pow(nits.y(), 2.2), std::pow(nits.z(), 2.2));
|
||||||
case NamedTransferFunction::linear:
|
case NamedTransferFunction::linear:
|
||||||
return nits;
|
return nits;
|
||||||
case NamedTransferFunction::scRGB:
|
case NamedTransferFunction::scRGB:
|
||||||
|
@ -334,15 +334,15 @@ QVector3D ColorDescription::encodedToNits(const QVector3D &nits, NamedTransferFu
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector3D ColorDescription::nitsToEncoded(const QVector3D &rgb, NamedTransferFunction tf, double sdrBrightness)
|
QVector3D ColorDescription::nitsToEncoded(const QVector3D &rgb, NamedTransferFunction tf, double referenceLuminance)
|
||||||
{
|
{
|
||||||
switch (tf) {
|
switch (tf) {
|
||||||
case NamedTransferFunction::sRGB: {
|
case NamedTransferFunction::sRGB: {
|
||||||
const auto clamped = clamp(rgb / sdrBrightness);
|
const auto clamped = clamp(rgb / referenceLuminance);
|
||||||
return QVector3D(linearToSRGB(clamped.x()), linearToSRGB(clamped.y()), linearToSRGB(clamped.z()));
|
return QVector3D(linearToSRGB(clamped.x()), linearToSRGB(clamped.y()), linearToSRGB(clamped.z()));
|
||||||
}
|
}
|
||||||
case NamedTransferFunction::gamma22: {
|
case NamedTransferFunction::gamma22: {
|
||||||
const auto clamped = clamp(rgb / sdrBrightness);
|
const auto clamped = clamp(rgb / referenceLuminance);
|
||||||
return QVector3D(std::pow(clamped.x(), 1 / 2.2), std::pow(clamped.y(), 1 / 2.2), std::pow(clamped.z(), 1 / 2.2));
|
return QVector3D(std::pow(clamped.x(), 1 / 2.2), std::pow(clamped.y(), 1 / 2.2), std::pow(clamped.z(), 1 / 2.2));
|
||||||
}
|
}
|
||||||
case NamedTransferFunction::linear:
|
case NamedTransferFunction::linear:
|
||||||
|
@ -357,8 +357,8 @@ QVector3D ColorDescription::nitsToEncoded(const QVector3D &rgb, NamedTransferFun
|
||||||
|
|
||||||
QVector3D ColorDescription::mapTo(QVector3D rgb, const ColorDescription &dst) const
|
QVector3D ColorDescription::mapTo(QVector3D rgb, const ColorDescription &dst) const
|
||||||
{
|
{
|
||||||
rgb = encodedToNits(rgb, m_transferFunction, m_sdrBrightness);
|
rgb = encodedToNits(rgb, m_transferFunction, m_referenceLuminance);
|
||||||
rgb = m_containerColorimetry.toOther(dst.containerColorimetry()) * rgb;
|
rgb = m_containerColorimetry.toOther(dst.containerColorimetry()) * rgb;
|
||||||
return nitsToEncoded(rgb, dst.transferFunction(), dst.sdrBrightness());
|
return nitsToEncoded(rgb, dst.transferFunction(), dst.referenceLuminance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,16 +105,16 @@ public:
|
||||||
/**
|
/**
|
||||||
* @param containerColorimetry the container colorimety of this description
|
* @param containerColorimetry the container colorimety of this description
|
||||||
* @param tf the transfer function of this description
|
* @param tf the transfer function of this description
|
||||||
* @param sdrBrightness the brightness of SDR content
|
* @param referenceLuminance the brightness of SDR content
|
||||||
* @param minHdrBrightness the minimum brightness of HDR content
|
* @param minLuminance the minimum brightness of HDR content
|
||||||
* @param maxFrameAverageBrightness the maximum brightness of HDR content, if the whole screen is white
|
* @param maxAverageLuminance the maximum brightness of HDR content, if the whole screen is white
|
||||||
* @param maxHdrHighlightBrightness the maximum brightness of HDR content, for a small part of the screen only
|
* @param maxHdrLuminance the maximum brightness of HDR content, for a small part of the screen only
|
||||||
* @param sdrColorimetry
|
* @param sdrColorimetry
|
||||||
*/
|
*/
|
||||||
explicit ColorDescription(const Colorimetry &containerColorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, std::optional<double> maxFrameAverageBrightness, std::optional<double> maxHdrHighlightBrightness);
|
explicit ColorDescription(const Colorimetry &containerColorimetry, NamedTransferFunction tf, double referenceLuminance, double minLuminance, std::optional<double> maxAverageLuminance, std::optional<double> maxHdrLuminance);
|
||||||
explicit ColorDescription(NamedColorimetry containerColorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, std::optional<double> maxFrameAverageBrightness, std::optional<double> maxHdrHighlightBrightness);
|
explicit ColorDescription(NamedColorimetry containerColorimetry, NamedTransferFunction tf, double referenceLuminance, double minLuminance, std::optional<double> maxAverageLuminance, std::optional<double> maxHdrLuminance);
|
||||||
explicit ColorDescription(const Colorimetry &containerColorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, std::optional<double> maxFrameAverageBrightness, std::optional<double> maxHdrHighlightBrightness, std::optional<Colorimetry> masteringColorimetry, const Colorimetry &sdrColorimetry);
|
explicit ColorDescription(const Colorimetry &containerColorimetry, NamedTransferFunction tf, double referenceLuminance, double minLuminance, std::optional<double> maxAverageLuminance, std::optional<double> maxHdrLuminance, std::optional<Colorimetry> masteringColorimetry, const Colorimetry &sdrColorimetry);
|
||||||
explicit ColorDescription(NamedColorimetry containerColorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, std::optional<double> maxFrameAverageBrightness, std::optional<double> maxHdrHighlightBrightness, std::optional<Colorimetry> masteringColorimetry, const Colorimetry &sdrColorimetry);
|
explicit ColorDescription(NamedColorimetry containerColorimetry, NamedTransferFunction tf, double referenceLuminance, double minLuminance, std::optional<double> maxAverageLuminance, std::optional<double> maxHdrLuminance, std::optional<Colorimetry> masteringColorimetry, const Colorimetry &sdrColorimetry);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The primaries and whitepoint that colors are encoded for. This is used to convert between different colorspaces.
|
* The primaries and whitepoint that colors are encoded for. This is used to convert between different colorspaces.
|
||||||
|
@ -129,10 +129,10 @@ public:
|
||||||
const std::optional<Colorimetry> &masteringColorimetry() const;
|
const std::optional<Colorimetry> &masteringColorimetry() const;
|
||||||
const Colorimetry &sdrColorimetry() const;
|
const Colorimetry &sdrColorimetry() const;
|
||||||
NamedTransferFunction transferFunction() const;
|
NamedTransferFunction transferFunction() const;
|
||||||
double sdrBrightness() const;
|
double referenceLuminance() const;
|
||||||
double minHdrBrightness() const;
|
double minLuminance() const;
|
||||||
std::optional<double> maxFrameAverageBrightness() const;
|
std::optional<double> maxAverageLuminance() const;
|
||||||
std::optional<double> maxHdrHighlightBrightness() const;
|
std::optional<double> maxHdrLuminance() const;
|
||||||
|
|
||||||
bool operator==(const ColorDescription &other) const = default;
|
bool operator==(const ColorDescription &other) const = default;
|
||||||
|
|
||||||
|
@ -142,17 +142,17 @@ public:
|
||||||
* This color description describes display-referred sRGB, with a gamma22 transfer function
|
* This color description describes display-referred sRGB, with a gamma22 transfer function
|
||||||
*/
|
*/
|
||||||
static const ColorDescription sRGB;
|
static const ColorDescription sRGB;
|
||||||
static QVector3D encodedToNits(const QVector3D &nits, NamedTransferFunction tf, double sdrBrightness);
|
static QVector3D encodedToNits(const QVector3D &nits, NamedTransferFunction tf, double referenceLuminance);
|
||||||
static QVector3D nitsToEncoded(const QVector3D &rgb, NamedTransferFunction tf, double sdrBrightness);
|
static QVector3D nitsToEncoded(const QVector3D &rgb, NamedTransferFunction tf, double referenceLuminance);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Colorimetry m_containerColorimetry;
|
Colorimetry m_containerColorimetry;
|
||||||
std::optional<Colorimetry> m_masteringColorimetry;
|
std::optional<Colorimetry> m_masteringColorimetry;
|
||||||
NamedTransferFunction m_transferFunction;
|
NamedTransferFunction m_transferFunction;
|
||||||
Colorimetry m_sdrColorimetry;
|
Colorimetry m_sdrColorimetry;
|
||||||
double m_sdrBrightness;
|
double m_referenceLuminance;
|
||||||
double m_minHdrBrightness;
|
double m_minLuminance;
|
||||||
std::optional<double> m_maxFrameAverageBrightness;
|
std::optional<double> m_maxAverageLuminance;
|
||||||
std::optional<double> m_maxHdrHighlightBrightness;
|
std::optional<double> m_maxHdrLuminance;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -594,8 +594,8 @@ void Output::setState(const State &state)
|
||||||
if (oldState.highDynamicRange != state.highDynamicRange) {
|
if (oldState.highDynamicRange != state.highDynamicRange) {
|
||||||
Q_EMIT highDynamicRangeChanged();
|
Q_EMIT highDynamicRangeChanged();
|
||||||
}
|
}
|
||||||
if (oldState.sdrBrightness != state.sdrBrightness) {
|
if (oldState.referenceLuminance != state.referenceLuminance) {
|
||||||
Q_EMIT sdrBrightnessChanged();
|
Q_EMIT referenceLuminanceChanged();
|
||||||
}
|
}
|
||||||
if (oldState.wideColorGamut != state.wideColorGamut) {
|
if (oldState.wideColorGamut != state.wideColorGamut) {
|
||||||
Q_EMIT wideColorGamutChanged();
|
Q_EMIT wideColorGamutChanged();
|
||||||
|
@ -706,9 +706,9 @@ bool Output::highDynamicRange() const
|
||||||
return m_state.highDynamicRange;
|
return m_state.highDynamicRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Output::sdrBrightness() const
|
uint32_t Output::referenceLuminance() const
|
||||||
{
|
{
|
||||||
return m_state.sdrBrightness;
|
return m_state.referenceLuminance;
|
||||||
}
|
}
|
||||||
|
|
||||||
Output::AutoRotationPolicy Output::autoRotationPolicy() const
|
Output::AutoRotationPolicy Output::autoRotationPolicy() const
|
||||||
|
|
|
@ -336,7 +336,7 @@ public:
|
||||||
OutputTransform panelOrientation() const;
|
OutputTransform panelOrientation() const;
|
||||||
bool wideColorGamut() const;
|
bool wideColorGamut() const;
|
||||||
bool highDynamicRange() const;
|
bool highDynamicRange() const;
|
||||||
uint32_t sdrBrightness() const;
|
uint32_t referenceLuminance() const;
|
||||||
AutoRotationPolicy autoRotationPolicy() const;
|
AutoRotationPolicy autoRotationPolicy() const;
|
||||||
std::shared_ptr<IccProfile> iccProfile() const;
|
std::shared_ptr<IccProfile> iccProfile() const;
|
||||||
QString iccProfilePath() const;
|
QString iccProfilePath() const;
|
||||||
|
@ -418,7 +418,7 @@ Q_SIGNALS:
|
||||||
void vrrPolicyChanged();
|
void vrrPolicyChanged();
|
||||||
void rgbRangeChanged();
|
void rgbRangeChanged();
|
||||||
void wideColorGamutChanged();
|
void wideColorGamutChanged();
|
||||||
void sdrBrightnessChanged();
|
void referenceLuminanceChanged();
|
||||||
void highDynamicRangeChanged();
|
void highDynamicRangeChanged();
|
||||||
void autoRotationPolicyChanged();
|
void autoRotationPolicyChanged();
|
||||||
void iccProfileChanged();
|
void iccProfileChanged();
|
||||||
|
@ -468,7 +468,7 @@ protected:
|
||||||
RgbRange rgbRange = RgbRange::Automatic;
|
RgbRange rgbRange = RgbRange::Automatic;
|
||||||
bool wideColorGamut = false;
|
bool wideColorGamut = false;
|
||||||
bool highDynamicRange = false;
|
bool highDynamicRange = false;
|
||||||
uint32_t sdrBrightness = 200;
|
uint32_t referenceLuminance = 200;
|
||||||
AutoRotationPolicy autoRotatePolicy = AutoRotationPolicy::InTabletMode;
|
AutoRotationPolicy autoRotatePolicy = AutoRotationPolicy::InTabletMode;
|
||||||
QString iccProfilePath;
|
QString iccProfilePath;
|
||||||
std::shared_ptr<IccProfile> iccProfile;
|
std::shared_ptr<IccProfile> iccProfile;
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
std::optional<Output::RgbRange> rgbRange;
|
std::optional<Output::RgbRange> rgbRange;
|
||||||
std::optional<VrrPolicy> vrrPolicy;
|
std::optional<VrrPolicy> vrrPolicy;
|
||||||
std::optional<bool> highDynamicRange;
|
std::optional<bool> highDynamicRange;
|
||||||
std::optional<uint32_t> sdrBrightness;
|
std::optional<uint32_t> referenceLuminance;
|
||||||
std::optional<bool> wideColorGamut;
|
std::optional<bool> wideColorGamut;
|
||||||
std::optional<Output::AutoRotationPolicy> autoRotationPolicy;
|
std::optional<Output::AutoRotationPolicy> autoRotationPolicy;
|
||||||
std::optional<QString> iccProfilePath;
|
std::optional<QString> iccProfilePath;
|
||||||
|
|
|
@ -7,7 +7,7 @@ const int gamma22_EOTF = 4;
|
||||||
uniform mat4 colorimetryTransform;
|
uniform mat4 colorimetryTransform;
|
||||||
uniform int sourceNamedTransferFunction;
|
uniform int sourceNamedTransferFunction;
|
||||||
uniform int destinationNamedTransferFunction;
|
uniform int destinationNamedTransferFunction;
|
||||||
uniform float sdrBrightness;// in nits
|
uniform float referenceLuminance;// in nits
|
||||||
uniform float maxHdrBrightness; // in nits
|
uniform float maxHdrBrightness; // in nits
|
||||||
|
|
||||||
vec3 nitsToPq(vec3 nits) {
|
vec3 nitsToPq(vec3 nits) {
|
||||||
|
@ -63,7 +63,7 @@ vec3 doTonemapping(vec3 color, float maxBrightness) {
|
||||||
vec4 encodingToNits(vec4 color, int sourceTransferFunction) {
|
vec4 encodingToNits(vec4 color, int sourceTransferFunction) {
|
||||||
if (sourceTransferFunction == sRGB_EOTF) {
|
if (sourceTransferFunction == sRGB_EOTF) {
|
||||||
color.rgb /= max(color.a, 0.001);
|
color.rgb /= max(color.a, 0.001);
|
||||||
color.rgb = sdrBrightness * srgbToLinear(color.rgb);
|
color.rgb = referenceLuminance * srgbToLinear(color.rgb);
|
||||||
color.rgb *= color.a;
|
color.rgb *= color.a;
|
||||||
} else if (sourceTransferFunction == PQ_EOTF) {
|
} else if (sourceTransferFunction == PQ_EOTF) {
|
||||||
color.rgb /= max(color.a, 0.001);
|
color.rgb /= max(color.a, 0.001);
|
||||||
|
@ -73,7 +73,7 @@ vec4 encodingToNits(vec4 color, int sourceTransferFunction) {
|
||||||
color.rgb *= 80.0;
|
color.rgb *= 80.0;
|
||||||
} else if (sourceTransferFunction == gamma22_EOTF) {
|
} else if (sourceTransferFunction == gamma22_EOTF) {
|
||||||
color.rgb /= max(color.a, 0.001);
|
color.rgb /= max(color.a, 0.001);
|
||||||
color.rgb = sdrBrightness * pow(color.rgb, vec3(2.2));
|
color.rgb = referenceLuminance * pow(color.rgb, vec3(2.2));
|
||||||
color.rgb *= color.a;
|
color.rgb *= color.a;
|
||||||
}
|
}
|
||||||
return color;
|
return color;
|
||||||
|
@ -88,7 +88,7 @@ vec4 sourceEncodingToNitsInDestinationColorspace(vec4 color) {
|
||||||
vec4 nitsToEncoding(vec4 color, int destinationTransferFunction) {
|
vec4 nitsToEncoding(vec4 color, int destinationTransferFunction) {
|
||||||
if (destinationTransferFunction == sRGB_EOTF) {
|
if (destinationTransferFunction == sRGB_EOTF) {
|
||||||
color.rgb /= max(color.a, 0.001);
|
color.rgb /= max(color.a, 0.001);
|
||||||
color.rgb = linearToSrgb(doTonemapping(color.rgb, sdrBrightness) / sdrBrightness);
|
color.rgb = linearToSrgb(doTonemapping(color.rgb, referenceLuminance) / referenceLuminance);
|
||||||
color.rgb *= color.a;
|
color.rgb *= color.a;
|
||||||
} else if (destinationTransferFunction == PQ_EOTF) {
|
} else if (destinationTransferFunction == PQ_EOTF) {
|
||||||
color.rgb /= max(color.a, 0.001);
|
color.rgb /= max(color.a, 0.001);
|
||||||
|
@ -98,7 +98,7 @@ vec4 nitsToEncoding(vec4 color, int destinationTransferFunction) {
|
||||||
color.rgb /= 80.0;
|
color.rgb /= 80.0;
|
||||||
} else if (destinationTransferFunction == gamma22_EOTF) {
|
} else if (destinationTransferFunction == gamma22_EOTF) {
|
||||||
color.rgb /= max(color.a, 0.001);
|
color.rgb /= max(color.a, 0.001);
|
||||||
color.rgb = pow(color.rgb / sdrBrightness, vec3(1.0 / 2.2));
|
color.rgb = pow(color.rgb / referenceLuminance, vec3(1.0 / 2.2));
|
||||||
color.rgb *= color.a;
|
color.rgb *= color.a;
|
||||||
}
|
}
|
||||||
return color;
|
return color;
|
||||||
|
|
|
@ -226,7 +226,7 @@ void GLShader::resolveLocations()
|
||||||
|
|
||||||
m_floatLocations[FloatUniform::Saturation] = uniformLocation("saturation");
|
m_floatLocations[FloatUniform::Saturation] = uniformLocation("saturation");
|
||||||
m_floatLocations[FloatUniform::MaxHdrBrightness] = uniformLocation("maxHdrBrightness");
|
m_floatLocations[FloatUniform::MaxHdrBrightness] = uniformLocation("maxHdrBrightness");
|
||||||
m_floatLocations[FloatUniform::SdrBrightness] = uniformLocation("sdrBrightness");
|
m_floatLocations[FloatUniform::SdrBrightness] = uniformLocation("referenceLuminance");
|
||||||
|
|
||||||
m_colorLocations[ColorUniform::Color] = uniformLocation("geometryColor");
|
m_colorLocations[ColorUniform::Color] = uniformLocation("geometryColor");
|
||||||
|
|
||||||
|
@ -458,8 +458,8 @@ bool GLShader::setColorspaceUniforms(const ColorDescription &src, const ColorDes
|
||||||
return setUniform(GLShader::Mat4Uniform::ColorimetryTransformation, srcColorimetry.toOther(dst.containerColorimetry()))
|
return setUniform(GLShader::Mat4Uniform::ColorimetryTransformation, srcColorimetry.toOther(dst.containerColorimetry()))
|
||||||
&& setUniform(GLShader::IntUniform::SourceNamedTransferFunction, int(src.transferFunction()))
|
&& setUniform(GLShader::IntUniform::SourceNamedTransferFunction, int(src.transferFunction()))
|
||||||
&& setUniform(GLShader::IntUniform::DestinationNamedTransferFunction, int(dst.transferFunction()))
|
&& setUniform(GLShader::IntUniform::DestinationNamedTransferFunction, int(dst.transferFunction()))
|
||||||
&& setUniform(FloatUniform::SdrBrightness, dst.sdrBrightness())
|
&& setUniform(FloatUniform::SdrBrightness, dst.referenceLuminance())
|
||||||
&& setUniform(FloatUniform::MaxHdrBrightness, dst.maxHdrHighlightBrightness().value_or(10'000));
|
&& setUniform(FloatUniform::MaxHdrBrightness, dst.maxHdrLuminance().value_or(10'000));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShader::setColorspaceUniformsFromSRGB(const ColorDescription &dst)
|
bool GLShader::setColorspaceUniformsFromSRGB(const ColorDescription &dst)
|
||||||
|
@ -472,7 +472,7 @@ bool GLShader::setColorspaceUniformsToSRGB(const ColorDescription &src)
|
||||||
return setUniform(GLShader::Mat4Uniform::ColorimetryTransformation, src.containerColorimetry().toOther(src.sdrColorimetry()))
|
return setUniform(GLShader::Mat4Uniform::ColorimetryTransformation, src.containerColorimetry().toOther(src.sdrColorimetry()))
|
||||||
&& setUniform(GLShader::IntUniform::SourceNamedTransferFunction, int(src.transferFunction()))
|
&& setUniform(GLShader::IntUniform::SourceNamedTransferFunction, int(src.transferFunction()))
|
||||||
&& setUniform(GLShader::IntUniform::DestinationNamedTransferFunction, int(NamedTransferFunction::gamma22))
|
&& setUniform(GLShader::IntUniform::DestinationNamedTransferFunction, int(NamedTransferFunction::gamma22))
|
||||||
&& setUniform(FloatUniform::SdrBrightness, src.sdrBrightness())
|
&& setUniform(FloatUniform::SdrBrightness, src.referenceLuminance())
|
||||||
&& setUniform(FloatUniform::MaxHdrBrightness, src.sdrBrightness());
|
&& setUniform(FloatUniform::MaxHdrBrightness, src.referenceLuminance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,7 @@ void OutputConfigurationStore::storeConfig(const QList<Output *> &allOutputs, bo
|
||||||
.rgbRange = changeSet->rgbRange.value_or(output->rgbRange()),
|
.rgbRange = changeSet->rgbRange.value_or(output->rgbRange()),
|
||||||
.vrrPolicy = changeSet->vrrPolicy.value_or(output->vrrPolicy()),
|
.vrrPolicy = changeSet->vrrPolicy.value_or(output->vrrPolicy()),
|
||||||
.highDynamicRange = changeSet->highDynamicRange.value_or(output->highDynamicRange()),
|
.highDynamicRange = changeSet->highDynamicRange.value_or(output->highDynamicRange()),
|
||||||
.sdrBrightness = changeSet->sdrBrightness.value_or(output->sdrBrightness()),
|
.referenceLuminance = changeSet->referenceLuminance.value_or(output->referenceLuminance()),
|
||||||
.wideColorGamut = changeSet->wideColorGamut.value_or(output->wideColorGamut()),
|
.wideColorGamut = changeSet->wideColorGamut.value_or(output->wideColorGamut()),
|
||||||
.autoRotation = changeSet->autoRotationPolicy.value_or(output->autoRotationPolicy()),
|
.autoRotation = changeSet->autoRotationPolicy.value_or(output->autoRotationPolicy()),
|
||||||
.iccProfilePath = changeSet->iccProfilePath.value_or(output->iccProfilePath()),
|
.iccProfilePath = changeSet->iccProfilePath.value_or(output->iccProfilePath()),
|
||||||
|
@ -266,7 +266,7 @@ void OutputConfigurationStore::storeConfig(const QList<Output *> &allOutputs, bo
|
||||||
.rgbRange = output->rgbRange(),
|
.rgbRange = output->rgbRange(),
|
||||||
.vrrPolicy = output->vrrPolicy(),
|
.vrrPolicy = output->vrrPolicy(),
|
||||||
.highDynamicRange = output->highDynamicRange(),
|
.highDynamicRange = output->highDynamicRange(),
|
||||||
.sdrBrightness = output->sdrBrightness(),
|
.referenceLuminance = output->referenceLuminance(),
|
||||||
.wideColorGamut = output->wideColorGamut(),
|
.wideColorGamut = output->wideColorGamut(),
|
||||||
.autoRotation = output->autoRotationPolicy(),
|
.autoRotation = output->autoRotationPolicy(),
|
||||||
.iccProfilePath = output->iccProfilePath(),
|
.iccProfilePath = output->iccProfilePath(),
|
||||||
|
@ -320,7 +320,7 @@ std::pair<OutputConfiguration, QList<Output *>> OutputConfigurationStore::setupT
|
||||||
.rgbRange = state.rgbRange,
|
.rgbRange = state.rgbRange,
|
||||||
.vrrPolicy = state.vrrPolicy,
|
.vrrPolicy = state.vrrPolicy,
|
||||||
.highDynamicRange = state.highDynamicRange,
|
.highDynamicRange = state.highDynamicRange,
|
||||||
.sdrBrightness = state.sdrBrightness,
|
.referenceLuminance = state.referenceLuminance,
|
||||||
.wideColorGamut = state.wideColorGamut,
|
.wideColorGamut = state.wideColorGamut,
|
||||||
.autoRotationPolicy = state.autoRotation,
|
.autoRotationPolicy = state.autoRotation,
|
||||||
.iccProfilePath = state.iccProfilePath,
|
.iccProfilePath = state.iccProfilePath,
|
||||||
|
@ -450,7 +450,7 @@ std::pair<OutputConfiguration, QList<Output *>> OutputConfigurationStore::genera
|
||||||
.rgbRange = existingData.rgbRange.value_or(kscreenChangeSet.rgbRange.value_or(Output::RgbRange::Automatic)),
|
.rgbRange = existingData.rgbRange.value_or(kscreenChangeSet.rgbRange.value_or(Output::RgbRange::Automatic)),
|
||||||
.vrrPolicy = existingData.vrrPolicy.value_or(kscreenChangeSet.vrrPolicy.value_or(VrrPolicy::Automatic)),
|
.vrrPolicy = existingData.vrrPolicy.value_or(kscreenChangeSet.vrrPolicy.value_or(VrrPolicy::Automatic)),
|
||||||
.highDynamicRange = existingData.highDynamicRange.value_or(false),
|
.highDynamicRange = existingData.highDynamicRange.value_or(false),
|
||||||
.sdrBrightness = existingData.sdrBrightness.value_or(std::clamp(output->maxAverageBrightness().value_or(200), 200.0, 500.0)),
|
.referenceLuminance = existingData.referenceLuminance.value_or(std::clamp(output->maxAverageBrightness().value_or(200), 200.0, 500.0)),
|
||||||
.wideColorGamut = existingData.wideColorGamut.value_or(false),
|
.wideColorGamut = existingData.wideColorGamut.value_or(false),
|
||||||
.autoRotationPolicy = existingData.autoRotation.value_or(Output::AutoRotationPolicy::InTabletMode),
|
.autoRotationPolicy = existingData.autoRotation.value_or(Output::AutoRotationPolicy::InTabletMode),
|
||||||
.colorProfileSource = existingData.colorProfileSource.value_or(Output::ColorProfileSource::sRGB),
|
.colorProfileSource = existingData.colorProfileSource.value_or(Output::ColorProfileSource::sRGB),
|
||||||
|
@ -713,7 +713,7 @@ void OutputConfigurationStore::load()
|
||||||
state.highDynamicRange = it->toBool();
|
state.highDynamicRange = it->toBool();
|
||||||
}
|
}
|
||||||
if (const auto it = data.find("sdrBrightness"); it != data.end() && it->isDouble()) {
|
if (const auto it = data.find("sdrBrightness"); it != data.end() && it->isDouble()) {
|
||||||
state.sdrBrightness = it->toInt(200);
|
state.referenceLuminance = it->toInt(200);
|
||||||
}
|
}
|
||||||
if (const auto it = data.find("wideColorGamut"); it != data.end() && it->isBool()) {
|
if (const auto it = data.find("wideColorGamut"); it != data.end() && it->isBool()) {
|
||||||
state.wideColorGamut = it->toBool();
|
state.wideColorGamut = it->toBool();
|
||||||
|
@ -945,8 +945,8 @@ void OutputConfigurationStore::save()
|
||||||
if (output.highDynamicRange) {
|
if (output.highDynamicRange) {
|
||||||
o["highDynamicRange"] = *output.highDynamicRange;
|
o["highDynamicRange"] = *output.highDynamicRange;
|
||||||
}
|
}
|
||||||
if (output.sdrBrightness) {
|
if (output.referenceLuminance) {
|
||||||
o["sdrBrightness"] = int(*output.sdrBrightness);
|
o["sdrBrightness"] = int(*output.referenceLuminance);
|
||||||
}
|
}
|
||||||
if (output.wideColorGamut) {
|
if (output.wideColorGamut) {
|
||||||
o["wideColorGamut"] = *output.wideColorGamut;
|
o["wideColorGamut"] = *output.wideColorGamut;
|
||||||
|
|
|
@ -73,7 +73,7 @@ private:
|
||||||
std::optional<Output::RgbRange> rgbRange;
|
std::optional<Output::RgbRange> rgbRange;
|
||||||
std::optional<VrrPolicy> vrrPolicy;
|
std::optional<VrrPolicy> vrrPolicy;
|
||||||
std::optional<bool> highDynamicRange;
|
std::optional<bool> highDynamicRange;
|
||||||
std::optional<uint32_t> sdrBrightness;
|
std::optional<uint32_t> referenceLuminance;
|
||||||
std::optional<bool> wideColorGamut;
|
std::optional<bool> wideColorGamut;
|
||||||
std::optional<Output::AutoRotationPolicy> autoRotation;
|
std::optional<Output::AutoRotationPolicy> autoRotation;
|
||||||
std::optional<QString> iccProfilePath;
|
std::optional<QString> iccProfilePath;
|
||||||
|
|
|
@ -65,7 +65,7 @@ void ColorPickerEffect::paintScreen(const RenderTarget &renderTarget, const Rend
|
||||||
std::array<float, 4> data;
|
std::array<float, 4> data;
|
||||||
constexpr GLsizei PIXEL_SIZE = 1;
|
constexpr GLsizei PIXEL_SIZE = 1;
|
||||||
const QPoint texturePosition = viewport.mapToRenderTarget(m_scheduledPosition).toPoint();
|
const QPoint texturePosition = viewport.mapToRenderTarget(m_scheduledPosition).toPoint();
|
||||||
const ColorDescription sRGBencoding(Colorimetry::fromName(NamedColorimetry::BT709), NamedTransferFunction::gamma22, renderTarget.colorDescription().sdrBrightness(), 0, renderTarget.colorDescription().sdrBrightness(), renderTarget.colorDescription().sdrBrightness());
|
const ColorDescription sRGBencoding(Colorimetry::fromName(NamedColorimetry::BT709), NamedTransferFunction::gamma22, renderTarget.colorDescription().referenceLuminance(), 0, renderTarget.colorDescription().referenceLuminance(), renderTarget.colorDescription().referenceLuminance());
|
||||||
|
|
||||||
glReadPixels(texturePosition.x(), renderTarget.size().height() - texturePosition.y() - PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE, GL_RGBA, GL_FLOAT, data.data());
|
glReadPixels(texturePosition.x(), renderTarget.size().height() - texturePosition.y() - PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE, GL_RGBA, GL_FLOAT, data.data());
|
||||||
QVector3D sRGB = 255 * renderTarget.colorDescription().mapTo(QVector3D(data[0], data[1], data[2]), sRGBencoding);
|
QVector3D sRGB = 255 * renderTarget.colorDescription().mapTo(QVector3D(data[0], data[1], data[2]), sRGBencoding);
|
||||||
|
|
|
@ -80,9 +80,9 @@ void FrogColorManagementSurfaceV1::setPreferredColorDescription(const ColorDescr
|
||||||
encodePrimary(color.green().x()), encodePrimary(color.green().y()),
|
encodePrimary(color.green().x()), encodePrimary(color.green().y()),
|
||||||
encodePrimary(color.blue().x()), encodePrimary(color.blue().y()),
|
encodePrimary(color.blue().x()), encodePrimary(color.blue().y()),
|
||||||
encodePrimary(color.white().x()), encodePrimary(color.white().y()),
|
encodePrimary(color.white().x()), encodePrimary(color.white().y()),
|
||||||
std::round(colorDescription.maxHdrHighlightBrightness().value_or(0)),
|
std::round(colorDescription.maxHdrLuminance().value_or(0)),
|
||||||
std::round(colorDescription.minHdrBrightness() / 0.0001),
|
std::round(colorDescription.minLuminance() / 0.0001),
|
||||||
std::round(colorDescription.maxFrameAverageBrightness().value_or(0)));
|
std::round(colorDescription.maxAverageLuminance().value_or(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrogColorManagementSurfaceV1::frog_color_managed_surface_set_known_transfer_function(Resource *resource, uint32_t transfer_function)
|
void FrogColorManagementSurfaceV1::frog_color_managed_surface_set_known_transfer_function(Resource *resource, uint32_t transfer_function)
|
||||||
|
@ -131,7 +131,7 @@ void FrogColorManagementSurfaceV1::frog_color_managed_surface_set_hdr_metadata(R
|
||||||
uint32_t max_cll, uint32_t max_fall)
|
uint32_t max_cll, uint32_t max_fall)
|
||||||
{
|
{
|
||||||
if (max_fall > 0) {
|
if (max_fall > 0) {
|
||||||
m_maxFrameAverageBrightness = max_fall;
|
m_maxAverageLuminance = max_fall;
|
||||||
}
|
}
|
||||||
if (max_cll > 0) {
|
if (max_cll > 0) {
|
||||||
m_maxPeakBrightness = max_cll;
|
m_maxPeakBrightness = max_cll;
|
||||||
|
@ -161,7 +161,7 @@ void FrogColorManagementSurfaceV1::updateColorDescription()
|
||||||
{
|
{
|
||||||
if (m_surface) {
|
if (m_surface) {
|
||||||
SurfaceInterfacePrivate *priv = SurfaceInterfacePrivate::get(m_surface);
|
SurfaceInterfacePrivate *priv = SurfaceInterfacePrivate::get(m_surface);
|
||||||
priv->pending->colorDescription = ColorDescription(m_containerColorimetry, m_transferFunction, 0, 0, m_maxFrameAverageBrightness, m_maxPeakBrightness, m_masteringColorimetry, Colorimetry::fromName(NamedColorimetry::BT709));
|
priv->pending->colorDescription = ColorDescription(m_containerColorimetry, m_transferFunction, 0, 0, m_maxAverageLuminance, m_maxPeakBrightness, m_masteringColorimetry, Colorimetry::fromName(NamedColorimetry::BT709));
|
||||||
priv->pending->colorDescriptionIsSet = true;
|
priv->pending->colorDescriptionIsSet = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ private:
|
||||||
NamedTransferFunction m_transferFunction = NamedTransferFunction::sRGB;
|
NamedTransferFunction m_transferFunction = NamedTransferFunction::sRGB;
|
||||||
NamedColorimetry m_containerColorimetry = NamedColorimetry::BT709;
|
NamedColorimetry m_containerColorimetry = NamedColorimetry::BT709;
|
||||||
std::optional<Colorimetry> m_masteringColorimetry;
|
std::optional<Colorimetry> m_masteringColorimetry;
|
||||||
std::optional<double> m_maxFrameAverageBrightness;
|
std::optional<double> m_maxAverageLuminance;
|
||||||
std::optional<double> m_maxPeakBrightness;
|
std::optional<double> m_maxPeakBrightness;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ public:
|
||||||
vrr_policy m_vrrPolicy = vrr_policy_automatic;
|
vrr_policy m_vrrPolicy = vrr_policy_automatic;
|
||||||
rgb_range m_rgbRange = rgb_range_automatic;
|
rgb_range m_rgbRange = rgb_range_automatic;
|
||||||
bool m_highDynamicRange = false;
|
bool m_highDynamicRange = false;
|
||||||
uint32_t m_sdrBrightness = 200;
|
uint32_t m_referenceLuminance = 200;
|
||||||
bool m_wideColorGamut = false;
|
bool m_wideColorGamut = false;
|
||||||
auto_rotate_policy m_autoRotation = auto_rotate_policy::auto_rotate_policy_in_tablet_mode;
|
auto_rotate_policy m_autoRotation = auto_rotate_policy::auto_rotate_policy_in_tablet_mode;
|
||||||
QString m_iccProfilePath;
|
QString m_iccProfilePath;
|
||||||
|
@ -253,7 +253,7 @@ OutputDeviceV2Interface::OutputDeviceV2Interface(Display *display, Output *handl
|
||||||
connect(handle, &Output::rgbRangeChanged,
|
connect(handle, &Output::rgbRangeChanged,
|
||||||
this, &OutputDeviceV2Interface::updateRgbRange);
|
this, &OutputDeviceV2Interface::updateRgbRange);
|
||||||
connect(handle, &Output::highDynamicRangeChanged, this, &OutputDeviceV2Interface::updateHighDynamicRange);
|
connect(handle, &Output::highDynamicRangeChanged, this, &OutputDeviceV2Interface::updateHighDynamicRange);
|
||||||
connect(handle, &Output::sdrBrightnessChanged, this, &OutputDeviceV2Interface::updateSdrBrightness);
|
connect(handle, &Output::referenceLuminanceChanged, this, &OutputDeviceV2Interface::updateSdrBrightness);
|
||||||
connect(handle, &Output::wideColorGamutChanged, this, &OutputDeviceV2Interface::updateWideColorGamut);
|
connect(handle, &Output::wideColorGamutChanged, this, &OutputDeviceV2Interface::updateWideColorGamut);
|
||||||
connect(handle, &Output::autoRotationPolicyChanged, this, &OutputDeviceV2Interface::updateAutoRotate);
|
connect(handle, &Output::autoRotationPolicyChanged, this, &OutputDeviceV2Interface::updateAutoRotate);
|
||||||
connect(handle, &Output::iccProfileChanged, this, &OutputDeviceV2Interface::updateIccProfilePath);
|
connect(handle, &Output::iccProfileChanged, this, &OutputDeviceV2Interface::updateIccProfilePath);
|
||||||
|
@ -429,7 +429,7 @@ void OutputDeviceV2InterfacePrivate::sendHighDynamicRange(Resource *resource)
|
||||||
void OutputDeviceV2InterfacePrivate::sendSdrBrightness(Resource *resource)
|
void OutputDeviceV2InterfacePrivate::sendSdrBrightness(Resource *resource)
|
||||||
{
|
{
|
||||||
if (resource->version() >= KDE_OUTPUT_DEVICE_V2_SDR_BRIGHTNESS_SINCE_VERSION) {
|
if (resource->version() >= KDE_OUTPUT_DEVICE_V2_SDR_BRIGHTNESS_SINCE_VERSION) {
|
||||||
send_sdr_brightness(resource->handle, m_sdrBrightness);
|
send_sdr_brightness(resource->handle, m_referenceLuminance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,8 +723,8 @@ void OutputDeviceV2Interface::updateHighDynamicRange()
|
||||||
|
|
||||||
void OutputDeviceV2Interface::updateSdrBrightness()
|
void OutputDeviceV2Interface::updateSdrBrightness()
|
||||||
{
|
{
|
||||||
if (d->m_sdrBrightness != d->m_handle->sdrBrightness()) {
|
if (d->m_referenceLuminance != d->m_handle->referenceLuminance()) {
|
||||||
d->m_sdrBrightness = d->m_handle->sdrBrightness();
|
d->m_referenceLuminance = d->m_handle->referenceLuminance();
|
||||||
const auto clientResources = d->resourceMap();
|
const auto clientResources = d->resourceMap();
|
||||||
for (const auto &resource : clientResources) {
|
for (const auto &resource : clientResources) {
|
||||||
d->sendSdrBrightness(resource);
|
d->sendSdrBrightness(resource);
|
||||||
|
|
|
@ -273,7 +273,7 @@ void OutputConfigurationV2Interface::kde_output_configuration_v2_set_sdr_brightn
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (OutputDeviceV2Interface *output = OutputDeviceV2Interface::get(outputdevice)) {
|
if (OutputDeviceV2Interface *output = OutputDeviceV2Interface::get(outputdevice)) {
|
||||||
config.changeSet(output->handle())->sdrBrightness = sdr_brightness;
|
config.changeSet(output->handle())->referenceLuminance = sdr_brightness;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,11 +148,11 @@ void XXColorParametricCreatorV2::xx_image_description_creator_params_v2_create(R
|
||||||
wl_resource_post_error(resource->handle, error::error_incomplete_set, "colorimetry or transfer function missing");
|
wl_resource_post_error(resource->handle, error::error_incomplete_set, "colorimetry or transfer function missing");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_transferFunction != NamedTransferFunction::PerceptualQuantizer && (m_maxFrameAverageBrightness || m_maxPeakBrightness)) {
|
if (m_transferFunction != NamedTransferFunction::PerceptualQuantizer && (m_maxAverageLuminance || m_maxPeakBrightness)) {
|
||||||
wl_resource_post_error(resource->handle, error::error_inconsistent_set, "max_cll and max_fall must only be set with the PQ transfer function");
|
wl_resource_post_error(resource->handle, error::error_inconsistent_set, "max_cll and max_fall must only be set with the PQ transfer function");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new XXImageDescriptionV2(resource->client(), image_description, resource->version(), ColorDescription(*m_colorimetry, *m_transferFunction, 100, 0, m_maxFrameAverageBrightness.value_or(100), m_maxPeakBrightness.value_or(100)));
|
new XXImageDescriptionV2(resource->client(), image_description, resource->version(), ColorDescription(*m_colorimetry, *m_transferFunction, 100, 0, m_maxAverageLuminance.value_or(100), m_maxPeakBrightness.value_or(100)));
|
||||||
wl_resource_destroy(resource->handle);
|
wl_resource_destroy(resource->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ void XXColorParametricCreatorV2::xx_image_description_creator_params_v2_set_max_
|
||||||
|
|
||||||
void XXColorParametricCreatorV2::xx_image_description_creator_params_v2_set_max_fall(Resource *resource, uint32_t max_fall)
|
void XXColorParametricCreatorV2::xx_image_description_creator_params_v2_set_max_fall(Resource *resource, uint32_t max_fall)
|
||||||
{
|
{
|
||||||
m_maxFrameAverageBrightness = max_fall;
|
m_maxAverageLuminance = max_fall;
|
||||||
}
|
}
|
||||||
|
|
||||||
XXImageDescriptionV2::XXImageDescriptionV2(wl_client *client, uint32_t id, uint32_t version, const ColorDescription &color)
|
XXImageDescriptionV2::XXImageDescriptionV2(wl_client *client, uint32_t id, uint32_t version, const ColorDescription &color)
|
||||||
|
|
|
@ -70,7 +70,7 @@ private:
|
||||||
|
|
||||||
std::optional<Colorimetry> m_colorimetry;
|
std::optional<Colorimetry> m_colorimetry;
|
||||||
std::optional<NamedTransferFunction> m_transferFunction;
|
std::optional<NamedTransferFunction> m_transferFunction;
|
||||||
std::optional<double> m_maxFrameAverageBrightness;
|
std::optional<double> m_maxAverageLuminance;
|
||||||
std::optional<double> m_maxPeakBrightness;
|
std::optional<double> m_maxPeakBrightness;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue