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
master
Xaver Hugl 11 months ago
parent c1312a5551
commit d24edc7890

@ -249,8 +249,17 @@ DrmPipeline::Error DrmPipeline::prepareAtomicPresentation(DrmAtomicCommit *commi
if (!fb) { if (!fb) {
return Error::InvalidArguments; 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); 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; return Error::None;
} }

@ -54,6 +54,15 @@ DrmPlane::DrmPlane(DrmGpu *gpu, uint32_t planeId)
QByteArrayLiteral("Pre-multiplied"), QByteArrayLiteral("Pre-multiplied"),
QByteArrayLiteral("Coverage"), 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); inFormats.update(props);
alpha.update(props); alpha.update(props);
pixelBlendMode.update(props); pixelBlendMode.update(props);
colorEncoding.update(props);
colorRange.update(props);
if (!type.isValid() || !srcX.isValid() || !srcY.isValid() || !srcW.isValid() || !srcH.isValid() if (!type.isValid() || !srcX.isValid() || !srcY.isValid() || !srcW.isValid() || !srcH.isValid()
|| !crtcX.isValid() || !crtcY.isValid() || !crtcW.isValid() || !crtcH.isValid() || !fbId.isValid()) { || !crtcX.isValid() || !crtcY.isValid() || !crtcW.isValid() || !crtcH.isValid() || !fbId.isValid()) {

@ -61,6 +61,15 @@ public:
PreMultiplied, PreMultiplied,
Coverage Coverage
}; };
enum class ColorEncoding : uint64_t {
BT601_YCbCr,
BT701_YCbCr,
BT2020_YCbCr
};
enum class ColorRange : uint64_t {
Limited_YCbCr,
Full_YCbCr
};
DrmEnumProperty<TypeIndex> type; DrmEnumProperty<TypeIndex> type;
DrmProperty srcX; DrmProperty srcX;
@ -77,6 +86,8 @@ public:
DrmProperty inFormats; DrmProperty inFormats;
DrmProperty alpha; DrmProperty alpha;
DrmEnumProperty<PixelBlendMode> pixelBlendMode; DrmEnumProperty<PixelBlendMode> pixelBlendMode;
DrmEnumProperty<ColorEncoding> colorEncoding;
DrmEnumProperty<ColorRange> colorRange;
static int32_t transformationToDegrees(Transformations transformation); static int32_t transformationToDegrees(Transformations transformation);

Loading…
Cancel
Save