colorspace: make sdr colorimetry not be about rec.2020 anymore
This was just done because of the wrong assumption that displays needed that to show the full native gamut. That turned out to be an amdgpu bug though; with that fixed, most of the 0-100% range is wildly oversaturated. To make the slider more intuitive, this changes the sdr gamut wideness to instead interpolate to the native display primaries as indicated by the EDID.
This commit is contained in:
parent
8d44ece874
commit
9c0085f5a9
7 changed files with 30 additions and 33 deletions
|
@ -57,8 +57,8 @@ void TestColorspaces::roundtripConversion()
|
|||
QFETCH(NamedTransferFunction, dstTransferFunction);
|
||||
QFETCH(double, requiredAccuracy);
|
||||
|
||||
const auto src = ColorDescription(srcColorimetry, srcTransferFunction, 100, 0, 100, 100, 0);
|
||||
const auto dst = ColorDescription(dstColorimetry, dstTransferFunction, 100, 0, 100, 100, 0);
|
||||
const auto src = ColorDescription(srcColorimetry, srcTransferFunction, 100, 0, 100, 100);
|
||||
const auto dst = ColorDescription(dstColorimetry, dstTransferFunction, 100, 0, 100, 100);
|
||||
|
||||
const QVector3D red(1, 0, 0);
|
||||
const QVector3D green(0, 1, 0);
|
||||
|
|
|
@ -112,7 +112,7 @@ std::optional<OutputLayerBeginFrameInfo> EglGbmLayerSurface::startRendering(cons
|
|||
m_surface->intermediaryColorDescription = ColorDescription(colorDescription.colorimetry(), NamedTransferFunction::linear,
|
||||
colorDescription.sdrBrightness(), colorDescription.minHdrBrightness(),
|
||||
colorDescription.maxFrameAverageBrightness(), colorDescription.maxHdrHighlightBrightness(),
|
||||
colorDescription.sdrGamutWideness());
|
||||
colorDescription.sdrColorimetry());
|
||||
} else {
|
||||
m_surface->intermediaryColorDescription = colorDescription;
|
||||
}
|
||||
|
|
|
@ -342,14 +342,15 @@ ColorDescription DrmOutput::createColorDescription(const std::shared_ptr<OutputC
|
|||
{
|
||||
if (props->highDynamicRange.value_or(m_state.highDynamicRange) && m_connector->edid()) {
|
||||
const auto colorimetry = props->wideColorGamut.value_or(m_state.wideColorGamut) ? NamedColorimetry::BT2020 : NamedColorimetry::BT709;
|
||||
const auto nativeColorimetry = m_information.edid.colorimetry().value_or(Colorimetry::fromName(NamedColorimetry::BT709));
|
||||
const auto sdrBrightness = props->sdrBrightness.value_or(m_state.sdrBrightness);
|
||||
return ColorDescription(colorimetry, NamedTransferFunction::PerceptualQuantizer, sdrBrightness,
|
||||
props->minBrightnessOverride.value_or(m_state.minBrightnessOverride).value_or(m_connector->edid()->desiredMinLuminance()),
|
||||
props->maxAverageBrightnessOverride.value_or(m_state.maxAverageBrightnessOverride).value_or(m_connector->edid()->desiredMaxFrameAverageLuminance().value_or(sdrBrightness)),
|
||||
props->maxPeakBrightnessOverride.value_or(m_state.maxPeakBrightnessOverride).value_or(m_connector->edid()->desiredMaxLuminance().value_or(1000)),
|
||||
props->sdrGamutWideness.value_or(m_state.sdrGamutWideness));
|
||||
Colorimetry::fromName(NamedColorimetry::BT709).interpolateGamutTo(nativeColorimetry, props->sdrGamutWideness.value_or(m_state.sdrGamutWideness)));
|
||||
} else if (const auto profile = props->iccProfile.value_or(m_state.iccProfile)) {
|
||||
return ColorDescription(profile->colorimetry(), NamedTransferFunction::gamma22, 200, 0, 200, 200, 0);
|
||||
return ColorDescription(profile->colorimetry(), NamedTransferFunction::gamma22, 200, 0, 200, 200);
|
||||
} else {
|
||||
return ColorDescription::sRGB;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,16 @@ QMatrix4x4 Colorimetry::calculateToXYZMatrix(QVector3D red, QVector3D green, QVe
|
|||
return matrixFromColumns(red * component_scale.x(), green * component_scale.y(), blue * component_scale.z());
|
||||
}
|
||||
|
||||
Colorimetry Colorimetry::interpolateGamutTo(const Colorimetry &one, double factor) const
|
||||
{
|
||||
return Colorimetry{
|
||||
m_red * (1 - factor) + one.red() * factor,
|
||||
m_green * (1 - factor) + one.green() * factor,
|
||||
m_blue * (1 - factor) + one.blue() * factor,
|
||||
m_white, // whitepoint should stay the same
|
||||
};
|
||||
}
|
||||
|
||||
Colorimetry::Colorimetry(QVector2D red, QVector2D green, QVector2D blue, QVector2D white)
|
||||
: m_red(red)
|
||||
, m_green(green)
|
||||
|
@ -183,23 +193,12 @@ const Colorimetry &Colorimetry::fromName(NamedColorimetry name)
|
|||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
const ColorDescription ColorDescription::sRGB = ColorDescription(NamedColorimetry::BT709, NamedTransferFunction::gamma22, 100, 0, 100, 100, 0);
|
||||
const ColorDescription ColorDescription::sRGB = ColorDescription(NamedColorimetry::BT709, NamedTransferFunction::gamma22, 100, 0, 100, 100);
|
||||
|
||||
static Colorimetry sRGBColorimetry(double factor)
|
||||
{
|
||||
return Colorimetry{
|
||||
BT709.red() * (1 - factor) + BT2020.red() * factor,
|
||||
BT709.green() * (1 - factor) + BT2020.green() * factor,
|
||||
BT709.blue() * (1 - factor) + BT2020.blue() * factor,
|
||||
BT709.white(), // whitepoint is the same
|
||||
};
|
||||
}
|
||||
|
||||
ColorDescription::ColorDescription(const Colorimetry &colorimety, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, double maxFrameAverageBrightness, double maxHdrHighlightBrightness, double sdrGamutWideness)
|
||||
ColorDescription::ColorDescription(const Colorimetry &colorimety, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, double maxFrameAverageBrightness, double maxHdrHighlightBrightness, const Colorimetry &sdrColorimetry)
|
||||
: m_colorimetry(colorimety)
|
||||
, m_transferFunction(tf)
|
||||
, m_sdrColorimetry(sRGBColorimetry(sdrGamutWideness))
|
||||
, m_sdrGamutWideness(sdrGamutWideness)
|
||||
, m_sdrColorimetry(sdrColorimetry)
|
||||
, m_sdrBrightness(sdrBrightness)
|
||||
, m_minHdrBrightness(minHdrBrightness)
|
||||
, m_maxFrameAverageBrightness(maxFrameAverageBrightness)
|
||||
|
@ -207,11 +206,10 @@ ColorDescription::ColorDescription(const Colorimetry &colorimety, NamedTransferF
|
|||
{
|
||||
}
|
||||
|
||||
ColorDescription::ColorDescription(NamedColorimetry colorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, double maxFrameAverageBrightness, double maxHdrHighlightBrightness, double sdrGamutWideness)
|
||||
ColorDescription::ColorDescription(NamedColorimetry colorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, double maxFrameAverageBrightness, double maxHdrHighlightBrightness, const Colorimetry &sdrColorimetry)
|
||||
: m_colorimetry(Colorimetry::fromName(colorimetry))
|
||||
, m_transferFunction(tf)
|
||||
, m_sdrColorimetry(sRGBColorimetry(sdrGamutWideness))
|
||||
, m_sdrGamutWideness(sdrGamutWideness)
|
||||
, m_sdrColorimetry(sdrColorimetry)
|
||||
, m_sdrBrightness(sdrBrightness)
|
||||
, m_minHdrBrightness(minHdrBrightness)
|
||||
, m_maxFrameAverageBrightness(maxFrameAverageBrightness)
|
||||
|
@ -254,11 +252,6 @@ double ColorDescription::maxHdrHighlightBrightness() const
|
|||
return m_maxHdrHighlightBrightness;
|
||||
}
|
||||
|
||||
double ColorDescription::sdrGamutWideness() const
|
||||
{
|
||||
return m_sdrGamutWideness;
|
||||
}
|
||||
|
||||
bool ColorDescription::operator==(const ColorDescription &other) const
|
||||
{
|
||||
return m_colorimetry == other.m_colorimetry
|
||||
|
|
|
@ -65,6 +65,10 @@ public:
|
|||
* @returns this colorimetry, adapted to the new whitepoint using the Bradford transform
|
||||
*/
|
||||
Colorimetry adaptedTo(QVector2D newWhitepoint) const;
|
||||
/**
|
||||
* interpolates the primaries depending on the passed factor. The whitepoint stays unchanged
|
||||
*/
|
||||
Colorimetry interpolateGamutTo(const Colorimetry &one, double factor) const;
|
||||
|
||||
const QVector2D &red() const;
|
||||
const QVector2D &green() const;
|
||||
|
@ -105,10 +109,10 @@ public:
|
|||
* @param minHdrBrightness the minimum brightness of HDR content
|
||||
* @param maxFrameAverageBrightness 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 sdrGamutWideness the gamut wideness of sRGB content; 0 is rec.709, 1 is rec.2020, everything in between is interpolated
|
||||
* @param sdrColorimetry
|
||||
*/
|
||||
explicit ColorDescription(const Colorimetry &colorimety, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, double maxFrameAverageBrightness, double maxHdrHighlightBrightness, double sdrGamutWideness);
|
||||
explicit ColorDescription(NamedColorimetry colorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, double maxFrameAverageBrightness, double maxHdrHighlightBrightness, double sdrGamutWideness);
|
||||
explicit ColorDescription(const Colorimetry &colorimety, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, double maxFrameAverageBrightness, double maxHdrHighlightBrightness, const Colorimetry &sdrColorimetry = Colorimetry::fromName(NamedColorimetry::BT709));
|
||||
explicit ColorDescription(NamedColorimetry colorimetry, NamedTransferFunction tf, double sdrBrightness, double minHdrBrightness, double maxFrameAverageBrightness, double maxHdrHighlightBrightness, const Colorimetry &sdrColorimetry = Colorimetry::fromName(NamedColorimetry::BT709));
|
||||
|
||||
const Colorimetry &colorimetry() const;
|
||||
const Colorimetry &sdrColorimetry() const;
|
||||
|
@ -117,7 +121,6 @@ public:
|
|||
double minHdrBrightness() const;
|
||||
double maxFrameAverageBrightness() const;
|
||||
double maxHdrHighlightBrightness() const;
|
||||
double sdrGamutWideness() const;
|
||||
|
||||
bool operator==(const ColorDescription &other) const;
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ void FrogColorManagementSurfaceV1::updateColorDescription()
|
|||
if (m_surface) {
|
||||
// TODO make brightness values optional in ColorDescription
|
||||
SurfaceInterfacePrivate *priv = SurfaceInterfacePrivate::get(m_surface);
|
||||
priv->pending->colorDescription = ColorDescription(m_colorimetry, m_transferFunction, 0, 0, m_maxFrameAverageBrightness, m_maxPeakBrightness, 0);
|
||||
priv->pending->colorDescription = ColorDescription(m_colorimetry, m_transferFunction, 0, 0, m_maxFrameAverageBrightness, m_maxPeakBrightness);
|
||||
priv->pending->colorDescriptionIsSet = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ void XXColorParametricCreatorV1::xx_image_description_creator_params_v1_create(R
|
|||
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;
|
||||
}
|
||||
new XXImageDescriptionV1(resource->client(), image_description, resource->version(), ColorDescription(*m_colorimetry, *m_transferFunction, 100, 0, m_maxFrameAverageBrightness.value_or(100), m_maxPeakBrightness.value_or(100), 0));
|
||||
new XXImageDescriptionV1(resource->client(), image_description, resource->version(), ColorDescription(*m_colorimetry, *m_transferFunction, 100, 0, m_maxFrameAverageBrightness.value_or(100), m_maxPeakBrightness.value_or(100)));
|
||||
}
|
||||
|
||||
void XXColorParametricCreatorV1::xx_image_description_creator_params_v1_set_tf_named(Resource *resource, uint32_t tf)
|
||||
|
|
Loading…
Reference in a new issue