diff --git a/src/backends/drm/drm_pipeline.cpp b/src/backends/drm/drm_pipeline.cpp index f6b27b99a5..7ac0407357 100644 --- a/src/backends/drm/drm_pipeline.cpp +++ b/src/backends/drm/drm_pipeline.cpp @@ -249,8 +249,17 @@ DrmPipeline::Error DrmPipeline::prepareAtomicPresentation(DrmAtomicCommit *commi if (!fb) { return Error::InvalidArguments; } - m_pending.crtc->primaryPlane()->set(commit, QPoint(0, 0), fb->buffer()->size(), centerBuffer(fb->buffer()->size(), m_pending.mode->size())); + const auto primary = m_pending.crtc->primaryPlane(); + primary->set(commit, QPoint(0, 0), fb->buffer()->size(), centerBuffer(fb->buffer()->size(), m_pending.mode->size())); commit->addBuffer(m_pending.crtc->primaryPlane(), fb); + if (fb->buffer()->dmabufAttributes()->format == DRM_FORMAT_NV12) { + if (!primary->colorEncoding.isValid() || !primary->colorRange.isValid()) { + // don't allow NV12 direct scanout if we don't know what the driver will do + return Error::InvalidArguments; + } + commit->addEnum(primary->colorEncoding, DrmPlane::ColorEncoding::BT701_YCbCr); + commit->addEnum(primary->colorRange, DrmPlane::ColorRange::Limited_YCbCr); + } return Error::None; } diff --git a/src/backends/drm/drm_plane.cpp b/src/backends/drm/drm_plane.cpp index 1610121bca..6cc31c4ce8 100644 --- a/src/backends/drm/drm_plane.cpp +++ b/src/backends/drm/drm_plane.cpp @@ -54,6 +54,15 @@ DrmPlane::DrmPlane(DrmGpu *gpu, uint32_t planeId) QByteArrayLiteral("Pre-multiplied"), QByteArrayLiteral("Coverage"), }) + , colorEncoding(this, QByteArrayLiteral("COLOR_ENCODING"), { + QByteArrayLiteral("ITU-R BT.601 YCbCr"), + QByteArrayLiteral("ITU-R BT.709 YCbCr"), + QByteArrayLiteral("ITU-R BT.2020 YCbCr"), + }) + , colorRange(this, QByteArrayLiteral("COLOR_RANGE"), { + QByteArrayLiteral("YCbCr limited range"), + QByteArrayLiteral("YCbCr full range"), + }) { } @@ -80,6 +89,8 @@ bool DrmPlane::updateProperties() inFormats.update(props); alpha.update(props); pixelBlendMode.update(props); + colorEncoding.update(props); + colorRange.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 975358d70f..f6829fa161 100644 --- a/src/backends/drm/drm_plane.h +++ b/src/backends/drm/drm_plane.h @@ -61,6 +61,15 @@ public: PreMultiplied, Coverage }; + enum class ColorEncoding : uint64_t { + BT601_YCbCr, + BT701_YCbCr, + BT2020_YCbCr + }; + enum class ColorRange : uint64_t { + Limited_YCbCr, + Full_YCbCr + }; DrmEnumProperty type; DrmProperty srcX; @@ -77,6 +86,8 @@ public: DrmProperty inFormats; DrmProperty alpha; DrmEnumProperty pixelBlendMode; + DrmEnumProperty colorEncoding; + DrmEnumProperty colorRange; static int32_t transformationToDegrees(Transformations transformation);