From 644e31f3890092f55728315e6ce9d7c4b03b560b Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Fri, 28 Apr 2023 21:54:51 +0200 Subject: [PATCH] backends/drm: add colorspace, degamma, alpha and pixel blend mode properties Even if we won't use all of them in the near future, they still need to be set to avoid issues with other compositors --- src/backends/drm/drm_connector.cpp | 8 ++++++++ src/backends/drm/drm_connector.h | 9 ++++++++ src/backends/drm/drm_crtc.cpp | 4 ++++ src/backends/drm/drm_crtc.h | 2 ++ src/backends/drm/drm_pipeline.cpp | 33 +++++++++++++++++++++++------- src/backends/drm/drm_plane.cpp | 8 ++++++++ src/backends/drm/drm_plane.h | 7 +++++++ 7 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/backends/drm/drm_connector.cpp b/src/backends/drm/drm_connector.cpp index f8919192be..caf5bd0871 100644 --- a/src/backends/drm/drm_connector.cpp +++ b/src/backends/drm/drm_connector.cpp @@ -129,6 +129,13 @@ DrmConnector::DrmConnector(DrmGpu *gpu, uint32_t connectorId) QByteArrayLiteral("Center"), QByteArrayLiteral("Full aspect"), }) + , colorspace(this, QByteArrayLiteral("Colorspace"), { + QByteArrayLiteral("Default"), + QByteArrayLiteral("BT709_YCC"), + QByteArrayLiteral("opRGB"), + QByteArrayLiteral("BT2020_RGB"), + QByteArrayLiteral("BT2020_YCC"), + }) , m_pipeline(std::make_unique(this)) , m_conn(drmModeGetConnector(gpu->fd(), connectorId)) { @@ -237,6 +244,7 @@ bool DrmConnector::updateProperties() panelOrientation.update(props); hdrMetadata.update(props); scalingMode.update(props); + colorspace.update(props); if (gpu()->atomicModeSetting() && !crtcId.isValid()) { return false; diff --git a/src/backends/drm/drm_connector.h b/src/backends/drm/drm_connector.h index 9c3f4c9689..1e66aca6b7 100644 --- a/src/backends/drm/drm_connector.h +++ b/src/backends/drm/drm_connector.h @@ -103,6 +103,14 @@ public: Center = 2, Full_Aspect = 3 }; + enum class Colorspace : uint64_t { + Default, + BT709_YCC, + opRGB, + BT2020_RGB, + BT2020_YCC, + }; + DrmProperty crtcId; DrmProperty nonDesktop; DrmProperty dpms; @@ -119,6 +127,7 @@ public: DrmEnumProperty panelOrientation; DrmProperty hdrMetadata; DrmEnumProperty scalingMode; + DrmEnumProperty colorspace; static DrmContentType kwinToDrmContentType(ContentType type); static Output::Transform toKWinTransform(PanelOrientation orientation); diff --git a/src/backends/drm/drm_crtc.cpp b/src/backends/drm/drm_crtc.cpp index 485cd247cf..d06099e26c 100644 --- a/src/backends/drm/drm_crtc.cpp +++ b/src/backends/drm/drm_crtc.cpp @@ -27,6 +27,8 @@ DrmCrtc::DrmCrtc(DrmGpu *gpu, uint32_t crtcId, int pipeIndex, DrmPlane *primaryP , gammaLut(this, QByteArrayLiteral("GAMMA_LUT")) , gammaLutSize(this, QByteArrayLiteral("GAMMA_LUT_SIZE")) , ctm(this, QByteArrayLiteral("CTM")) + , degammaLut(this, QByteArrayLiteral("DEGAMMA_LUT")) + , degammaLutSize(this, QByteArrayLiteral("DEGAMMA_LUT_SIZE")) , m_crtc(drmModeGetCrtc(gpu->fd(), crtcId)) , m_pipeIndex(pipeIndex) , m_primaryPlane(primaryPlane) @@ -46,6 +48,8 @@ bool DrmCrtc::updateProperties() gammaLut.update(props); gammaLutSize.update(props); ctm.update(props); + degammaLut.update(props); + degammaLutSize.update(props); return !gpu()->atomicModeSetting() || (modeId.isValid() && active.isValid()); } diff --git a/src/backends/drm/drm_crtc.h b/src/backends/drm/drm_crtc.h index 54a192cba9..e72a80504b 100644 --- a/src/backends/drm/drm_crtc.h +++ b/src/backends/drm/drm_crtc.h @@ -50,6 +50,8 @@ public: DrmProperty gammaLut; DrmProperty gammaLutSize; DrmProperty ctm; + DrmProperty degammaLut; + DrmProperty degammaLutSize; private: DrmUniquePtr m_crtc; diff --git a/src/backends/drm/drm_pipeline.cpp b/src/backends/drm/drm_pipeline.cpp index 81477e4df7..baa93c668c 100644 --- a/src/backends/drm/drm_pipeline.cpp +++ b/src/backends/drm/drm_pipeline.cpp @@ -256,20 +256,39 @@ void DrmPipeline::prepareAtomicModeset(DrmAtomicCommit *commit) if (m_connector->hdrMetadata.isValid()) { commit->addProperty(m_connector->hdrMetadata, 0); } + if (m_connector->colorspace.isValid()) { + commit->addEnum(m_connector->colorspace, DrmConnector::Colorspace::Default); + } if (m_connector->scalingMode.isValid() && m_connector->scalingMode.hasEnum(DrmConnector::ScalingMode::None)) { commit->addEnum(m_connector->scalingMode, DrmConnector::ScalingMode::None); } commit->addProperty(m_pending.crtc->active, 1); commit->addBlob(m_pending.crtc->modeId, m_pending.mode->blob()); - - commit->addProperty(m_pending.crtc->primaryPlane()->crtcId, m_pending.crtc->id()); - if (const auto &rotation = m_pending.crtc->primaryPlane()->rotation; rotation.isValid()) { - commit->addEnum(rotation, {DrmPlane::Transformation::Rotate0}); + if (m_pending.crtc->degammaLut.isValid()) { + commit->addBlob(m_pending.crtc->degammaLut, nullptr); } - if (m_pending.crtc->cursorPlane()) { - if (const auto &rotation = m_pending.crtc->cursorPlane()->rotation; rotation.isValid()) { - commit->addEnum(rotation, DrmPlane::Transformations(DrmPlane::Transformation::Rotate0)); + + const auto primary = m_pending.crtc->primaryPlane(); + commit->addProperty(primary->crtcId, m_pending.crtc->id()); + if (primary->rotation.isValid()) { + commit->addEnum(primary->rotation, {DrmPlane::Transformation::Rotate0}); + } + if (primary->alpha.isValid()) { + commit->addProperty(primary->alpha, 0xFFFF); + } + if (primary->pixelBlendMode.isValid()) { + commit->addEnum(primary->pixelBlendMode, DrmPlane::PixelBlendMode::PreMultiplied); + } + if (const auto cursor = m_pending.crtc->cursorPlane()) { + if (cursor->rotation.isValid()) { + commit->addEnum(cursor->rotation, DrmPlane::Transformations(DrmPlane::Transformation::Rotate0)); + } + if (cursor->alpha.isValid()) { + commit->addProperty(cursor->alpha, 0xFFFF); + } + if (cursor->pixelBlendMode.isValid()) { + commit->addEnum(cursor->pixelBlendMode, DrmPlane::PixelBlendMode::PreMultiplied); } } } diff --git a/src/backends/drm/drm_plane.cpp b/src/backends/drm/drm_plane.cpp index f42bd76a60..b77ab1d8d6 100644 --- a/src/backends/drm/drm_plane.cpp +++ b/src/backends/drm/drm_plane.cpp @@ -48,6 +48,12 @@ DrmPlane::DrmPlane(DrmGpu *gpu, uint32_t planeId) QByteArrayLiteral("reflect-y"), }) , inFormats(this, QByteArrayLiteral("IN_FORMATS")) + , alpha(this, QByteArrayLiteral("alpha")) + , pixelBlendMode(this, QByteArrayLiteral("pixel blend mode"), { + QByteArrayLiteral("None"), + QByteArrayLiteral("Pre-multiplied"), + QByteArrayLiteral("Coverage"), + }) { } @@ -72,6 +78,8 @@ bool DrmPlane::updateProperties() crtcId.update(props); rotation.update(props); inFormats.update(props); + alpha.update(props); + pixelBlendMode.update(props); if (!type.isValid() || !srcX.isValid() || !srcY.isValid() || !srcW.isValid() || !srcH.isValid() || !crtcX.isValid() || !crtcY.isValid() || !crtcW.isValid() || !crtcH.isValid() || !fbId.isValid()) { diff --git a/src/backends/drm/drm_plane.h b/src/backends/drm/drm_plane.h index 6943191c39..921bc71f2f 100644 --- a/src/backends/drm/drm_plane.h +++ b/src/backends/drm/drm_plane.h @@ -60,6 +60,11 @@ public: }; Q_ENUM(Transformation) Q_DECLARE_FLAGS(Transformations, Transformation) + enum class PixelBlendMode : uint64_t { + None, + PreMultiplied, + Coverage + }; DrmEnumProperty type; DrmProperty srcX; @@ -74,6 +79,8 @@ public: DrmProperty crtcId; DrmEnumProperty rotation; DrmProperty inFormats; + DrmProperty alpha; + DrmEnumProperty pixelBlendMode; static int32_t transformationToDegrees(Transformations transformation);