diff --git a/src/backends/drm/drm_output.cpp b/src/backends/drm/drm_output.cpp index 7097ac7931..00d514017a 100644 --- a/src/backends/drm/drm_output.cpp +++ b/src/backends/drm/drm_output.cpp @@ -324,13 +324,7 @@ bool DrmOutput::queueChanges(const std::shared_ptr &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 &props) return true; } +ColorDescription DrmOutput::createColorDescription(const std::shared_ptr &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 &props) { if (!m_connector->isConnected()) { diff --git a/src/backends/drm/drm_output.h b/src/backends/drm/drm_output.h index e5347f4f4b..8d424147cf 100644 --- a/src/backends/drm/drm_output.h +++ b/src/backends/drm/drm_output.h @@ -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 &props) const; QList> getModes() const; diff --git a/src/backends/drm/drm_pipeline.cpp b/src/backends/drm/drm_pipeline.cpp index 1a8d149ea8..d715ae3c09 100644 --- a/src/backends/drm/drm_pipeline.cpp +++ b/src/backends/drm/drm_pipeline.cpp @@ -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 peakBrightnessOverride, std::optional averageBrightnessOverride, std::optional 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 &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; } } diff --git a/src/backends/drm/drm_pipeline.h b/src/backends/drm/drm_pipeline.h index e8b93b0c6e..6cbb9ed921 100644 --- a/src/backends/drm/drm_pipeline.h +++ b/src/backends/drm/drm_pipeline.h @@ -130,12 +130,8 @@ public: void setGammaRamp(const std::shared_ptr &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 &profile); - void setSdrBrightness(double sdrBrightness); - void setSdrGamutWideness(double sdrGamutWideness); - void setBrightnessOverrides(std::optional peakBrightnessOverride, std::optional averageBrightnessOverride, std::optional minBrightnessOverride); enum class CommitMode { Test, @@ -150,7 +146,6 @@ private: uint32_t calculateUnderscan(); static Error errnoToError(); std::shared_ptr createHdrMetadata(NamedTransferFunction transferFunction) const; - ColorDescription createColorDescription() const; // legacy only Error presentLegacy(); @@ -189,15 +184,8 @@ private: std::shared_ptr ctm; DrmConnector::DrmContentType contentType = DrmConnector::DrmContentType::Graphics; - bool BT2020 = false; - NamedTransferFunction transferFunction = NamedTransferFunction::sRGB; - double sdrBrightness = 200; - double sdrGamutWideness = 0; std::shared_ptr iccProfile; ColorDescription colorDescription = ColorDescription::sRGB; - std::optional peakBrightnessOverride; - std::optional averageBrightnessOverride; - std::optional minBrightnessOverride; // the transformation that buffers submitted to the pipeline should have DrmPlane::Transformations renderOrientation = DrmPlane::Transformation::Rotate0;