backends/drm: ensure correct colors with direct scanout of NV12 buffers

If another compositor changes the color encoding and color range properties, the
resulting colors will be wrong. This commit ensures they're always set to BT.709
limited range to prevent that
wilder/Plasma/6.2
Xaver Hugl 2 years ago
parent c1312a5551
commit d24edc7890
  1. 11
      src/backends/drm/drm_pipeline.cpp
  2. 11
      src/backends/drm/drm_plane.cpp
  3. 11
      src/backends/drm/drm_plane.h

@ -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;
}

@ -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()) {

@ -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<TypeIndex> type;
DrmProperty srcX;
@ -77,6 +86,8 @@ public:
DrmProperty inFormats;
DrmProperty alpha;
DrmEnumProperty<PixelBlendMode> pixelBlendMode;
DrmEnumProperty<ColorEncoding> colorEncoding;
DrmEnumProperty<ColorRange> colorRange;
static int32_t transformationToDegrees(Transformations transformation);

Loading…
Cancel
Save