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
This commit is contained in:
Xaver Hugl 2023-04-28 21:54:51 +02:00
parent 2fb95eb80c
commit 644e31f389
7 changed files with 64 additions and 7 deletions

View file

@ -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<DrmPipeline>(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;

View file

@ -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> panelOrientation;
DrmProperty hdrMetadata;
DrmEnumProperty<ScalingMode> scalingMode;
DrmEnumProperty<Colorspace> colorspace;
static DrmContentType kwinToDrmContentType(ContentType type);
static Output::Transform toKWinTransform(PanelOrientation orientation);

View file

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

View file

@ -50,6 +50,8 @@ public:
DrmProperty gammaLut;
DrmProperty gammaLutSize;
DrmProperty ctm;
DrmProperty degammaLut;
DrmProperty degammaLutSize;
private:
DrmUniquePtr<drmModeCrtc> m_crtc;

View file

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

View file

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

View file

@ -60,6 +60,11 @@ public:
};
Q_ENUM(Transformation)
Q_DECLARE_FLAGS(Transformations, Transformation)
enum class PixelBlendMode : uint64_t {
None,
PreMultiplied,
Coverage
};
DrmEnumProperty<TypeIndex> type;
DrmProperty srcX;
@ -74,6 +79,8 @@ public:
DrmProperty crtcId;
DrmEnumProperty<Transformations> rotation;
DrmProperty inFormats;
DrmProperty alpha;
DrmEnumProperty<PixelBlendMode> pixelBlendMode;
static int32_t transformationToDegrees(Transformations transformation);