backends/drm: move color description creation to DrmOutput

It being in DrmPipeline just meant that a whole bunch of settings had to
be duplicated there, without any real reason
This commit is contained in:
Xaver Hugl 2023-12-22 02:58:10 +01:00
parent 4425bcd4e0
commit 8b1fddffbe
4 changed files with 28 additions and 82 deletions

View file

@ -324,13 +324,7 @@ bool DrmOutput::queueChanges(const std::shared_ptr<OutputChangeSet> &props)
m_pipeline->setRgbRange(props->rgbRange.value_or(m_pipeline->rgbRange()));
m_pipeline->setRenderOrientation(outputToPlaneTransform(props->transform.value_or(transform())));
m_pipeline->setEnable(props->enabled.value_or(m_pipeline->enabled()));
m_pipeline->setBT2020(bt2020);
m_pipeline->setNamedTransferFunction(hdr ? NamedTransferFunction::PerceptualQuantizer : NamedTransferFunction::sRGB);
m_pipeline->setSdrBrightness(props->sdrBrightness.value_or(m_state.sdrBrightness));
m_pipeline->setSdrGamutWideness(props->sdrGamutWideness.value_or(m_state.sdrGamutWideness));
m_pipeline->setBrightnessOverrides(props->maxPeakBrightnessOverride.value_or(m_state.maxPeakBrightnessOverride),
props->maxAverageBrightnessOverride.value_or(m_state.maxAverageBrightnessOverride),
props->minBrightnessOverride.value_or(m_state.minBrightnessOverride));
m_pipeline->setColorDescription(createColorDescription(props));
if (bt2020 || hdr) {
// ICC profiles don't support HDR (yet)
m_pipeline->setIccProfile(nullptr);
@ -345,6 +339,23 @@ bool DrmOutput::queueChanges(const std::shared_ptr<OutputChangeSet> &props)
return true;
}
ColorDescription DrmOutput::createColorDescription(const std::shared_ptr<OutputChangeSet> &props) const
{
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 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));
} else if (const auto profile = props->iccProfile.value_or(m_state.iccProfile)) {
return ColorDescription(profile->colorimetry(), NamedTransferFunction::gamma22, 200, 0, 200, 200, 0);
} else {
return ColorDescription::sRGB;
}
}
void DrmOutput::applyQueuedChanges(const std::shared_ptr<OutputChangeSet> &props)
{
if (!m_connector->isConnected()) {

View file

@ -66,6 +66,7 @@ private:
bool setDrmDpmsMode(DpmsMode mode);
void setDpmsMode(DpmsMode mode) override;
bool doSetChannelFactors(const QVector3D &rgb);
ColorDescription createColorDescription(const std::shared_ptr<OutputChangeSet> &props) const;
QList<std::shared_ptr<OutputMode>> getModes() const;

View file

@ -314,11 +314,11 @@ bool DrmPipeline::prepareAtomicModeset(DrmAtomicCommit *commit)
commit->addProperty(m_connector->maxBpc, preferred);
}
if (m_connector->hdrMetadata.isValid()) {
commit->addBlob(m_connector->hdrMetadata, createHdrMetadata(m_pending.transferFunction));
} else if (m_pending.transferFunction != NamedTransferFunction::sRGB) {
commit->addBlob(m_connector->hdrMetadata, createHdrMetadata(m_pending.colorDescription.transferFunction()));
} else if (m_pending.colorDescription.transferFunction() != NamedTransferFunction::gamma22) {
return false;
}
if (m_pending.BT2020) {
if (m_pending.colorDescription.colorimetry().name == NamedColorimetry::BT2020) {
if (!m_connector->colorspace.isValid() || !m_connector->colorspace.hasEnum(DrmConnector::Colorspace::BT2020_RGB)) {
return false;
}
@ -710,74 +710,20 @@ void DrmPipeline::setCTM(const QMatrix3x3 &ctm)
}
}
void DrmPipeline::setColorDescription(const ColorDescription &description)
{
m_pending.colorDescription = description;
}
void DrmPipeline::setContentType(DrmConnector::DrmContentType type)
{
m_pending.contentType = type;
}
void DrmPipeline::setBT2020(bool useBT2020)
{
if (m_pending.BT2020 != useBT2020) {
m_pending.BT2020 = useBT2020;
m_pending.colorDescription = createColorDescription();
}
}
void DrmPipeline::setNamedTransferFunction(NamedTransferFunction tf)
{
if (m_pending.transferFunction != tf) {
m_pending.transferFunction = tf;
m_pending.colorDescription = createColorDescription();
}
}
void DrmPipeline::setSdrBrightness(double sdrBrightness)
{
if (m_pending.sdrBrightness != sdrBrightness) {
m_pending.sdrBrightness = sdrBrightness;
m_pending.colorDescription = createColorDescription();
}
}
void DrmPipeline::setSdrGamutWideness(double sdrGamutWideness)
{
if (m_pending.sdrGamutWideness != sdrGamutWideness) {
m_pending.sdrGamutWideness = sdrGamutWideness;
m_pending.colorDescription = createColorDescription();
}
}
void DrmPipeline::setBrightnessOverrides(std::optional<double> peakBrightnessOverride, std::optional<double> averageBrightnessOverride, std::optional<double> minBrightnessOverride)
{
if (m_pending.peakBrightnessOverride != peakBrightnessOverride || m_pending.averageBrightnessOverride != averageBrightnessOverride || m_pending.minBrightnessOverride != minBrightnessOverride) {
m_pending.peakBrightnessOverride = peakBrightnessOverride;
m_pending.averageBrightnessOverride = averageBrightnessOverride;
m_pending.minBrightnessOverride = minBrightnessOverride;
m_pending.colorDescription = createColorDescription();
}
}
void DrmPipeline::setIccProfile(const std::shared_ptr<IccProfile> &profile)
{
if (m_pending.iccProfile != profile) {
m_pending.iccProfile = profile;
m_pending.colorDescription = createColorDescription();
}
}
ColorDescription DrmPipeline::createColorDescription() const
{
if (m_pending.transferFunction == NamedTransferFunction::PerceptualQuantizer && m_connector->edid()) {
const auto colorimetry = m_pending.BT2020 ? NamedColorimetry::BT2020 : NamedColorimetry::BT709;
return ColorDescription(colorimetry, m_pending.transferFunction, m_pending.sdrBrightness,
m_pending.minBrightnessOverride.value_or(m_connector->edid()->desiredMinLuminance()),
m_pending.averageBrightnessOverride.value_or(m_connector->edid()->desiredMaxFrameAverageLuminance().value_or(m_pending.sdrBrightness)),
m_pending.peakBrightnessOverride.value_or(m_connector->edid()->desiredMaxLuminance().value_or(1000)),
m_pending.sdrGamutWideness);
} else if (m_pending.iccProfile) {
return ColorDescription(m_pending.iccProfile->colorimetry(), NamedTransferFunction::sRGB, 200, 0, 200, 200, 0);
} else {
return ColorDescription::sRGB;
}
}

View file

@ -130,12 +130,8 @@ public:
void setGammaRamp(const std::shared_ptr<ColorTransformation> &transformation);
void setCTM(const QMatrix3x3 &ctm);
void setContentType(DrmConnector::DrmContentType type);
void setBT2020(bool useBT2020);
void setNamedTransferFunction(NamedTransferFunction tf);
void setColorDescription(const ColorDescription &description);
void setIccProfile(const std::shared_ptr<IccProfile> &profile);
void setSdrBrightness(double sdrBrightness);
void setSdrGamutWideness(double sdrGamutWideness);
void setBrightnessOverrides(std::optional<double> peakBrightnessOverride, std::optional<double> averageBrightnessOverride, std::optional<double> minBrightnessOverride);
enum class CommitMode {
Test,
@ -150,7 +146,6 @@ private:
uint32_t calculateUnderscan();
static Error errnoToError();
std::shared_ptr<DrmBlob> createHdrMetadata(NamedTransferFunction transferFunction) const;
ColorDescription createColorDescription() const;
// legacy only
Error presentLegacy();
@ -189,15 +184,8 @@ private:
std::shared_ptr<DrmBlob> ctm;
DrmConnector::DrmContentType contentType = DrmConnector::DrmContentType::Graphics;
bool BT2020 = false;
NamedTransferFunction transferFunction = NamedTransferFunction::sRGB;
double sdrBrightness = 200;
double sdrGamutWideness = 0;
std::shared_ptr<IccProfile> iccProfile;
ColorDescription colorDescription = ColorDescription::sRGB;
std::optional<double> peakBrightnessOverride;
std::optional<double> averageBrightnessOverride;
std::optional<double> minBrightnessOverride;
// the transformation that buffers submitted to the pipeline should have
DrmPlane::Transformations renderOrientation = DrmPlane::Transformation::Rotate0;