backends/drm: set drm content type when available

This commit is contained in:
Xaver Hugl 2022-05-25 11:38:59 +02:00
parent b99ae81b08
commit e9e97e49bf
13 changed files with 97 additions and 15 deletions

View file

@ -94,20 +94,25 @@ bool DrmConnectorMode::operator==(const DrmConnectorMode &otherMode)
}
DrmConnector::DrmConnector(DrmGpu *gpu, uint32_t connectorId)
: DrmObject(gpu, connectorId, {
PropertyDefinition(QByteArrayLiteral("CRTC_ID"), Requirement::Required),
PropertyDefinition(QByteArrayLiteral("non-desktop"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("DPMS"), Requirement::RequiredForLegacy),
PropertyDefinition(QByteArrayLiteral("EDID"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("overscan"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("vrr_capable"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("underscan"), Requirement::Optional, {QByteArrayLiteral("off"), QByteArrayLiteral("on"), QByteArrayLiteral("auto")}),
PropertyDefinition(QByteArrayLiteral("underscan vborder"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("underscan hborder"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("Broadcast RGB"), Requirement::Optional, {QByteArrayLiteral("Automatic"), QByteArrayLiteral("Full"), QByteArrayLiteral("Limited 16:235")}),
PropertyDefinition(QByteArrayLiteral("max bpc"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("link-status"), Requirement::Optional, {QByteArrayLiteral("Good"), QByteArrayLiteral("Bad")}),
},
: DrmObject(gpu,
connectorId,
{PropertyDefinition(QByteArrayLiteral("CRTC_ID"), Requirement::Required),
PropertyDefinition(QByteArrayLiteral("non-desktop"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("DPMS"), Requirement::RequiredForLegacy),
PropertyDefinition(QByteArrayLiteral("EDID"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("overscan"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("vrr_capable"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("underscan"), Requirement::Optional,
{QByteArrayLiteral("off"), QByteArrayLiteral("on"), QByteArrayLiteral("auto")}),
PropertyDefinition(QByteArrayLiteral("underscan vborder"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("underscan hborder"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("Broadcast RGB"), Requirement::Optional,
{QByteArrayLiteral("Automatic"), QByteArrayLiteral("Full"), QByteArrayLiteral("Limited 16:235")}),
PropertyDefinition(QByteArrayLiteral("max bpc"), Requirement::Optional),
PropertyDefinition(QByteArrayLiteral("link-status"), Requirement::Optional,
{QByteArrayLiteral("Good"), QByteArrayLiteral("Bad")}),
PropertyDefinition(QByteArrayLiteral("content type"), Requirement::Optional,
{QByteArrayLiteral("No Data"), QByteArrayLiteral("Graphics"), QByteArrayLiteral("Photo"), QByteArrayLiteral("Cinema"), QByteArrayLiteral("Game")})},
DRM_MODE_OBJECT_CONNECTOR)
, m_pipeline(std::make_unique<DrmPipeline>(this))
, m_conn(drmModeGetConnector(gpu->fd(), connectorId))
@ -457,4 +462,19 @@ QDebug &operator<<(QDebug &s, const KWin::DrmConnector *obj)
return s;
}
DrmConnector::DrmContentType DrmConnector::kwinToDrmContentType(ContentType type)
{
switch (type) {
case ContentType::None:
return DrmContentType::Graphics;
case ContentType::Photo:
return DrmContentType::Photo;
case ContentType::Video:
return DrmContentType::Cinema;
case ContentType::Game:
return DrmContentType::Game;
default:
Q_UNREACHABLE();
}
}
}

View file

@ -64,6 +64,7 @@ public:
Broadcast_RGB = 9,
MaxBpc = 10,
LinkStatus = 11,
ContentType = 12,
Count
};
@ -76,6 +77,13 @@ public:
Good = 0,
Bad = 1
};
enum class DrmContentType : uint64_t {
None = 0,
Graphics = 1,
Photo = 2,
Cinema = 3,
Game = 4
};
bool init() override;
bool updateProperties() override;
@ -103,6 +111,8 @@ public:
Output::RgbRange rgbRange() const;
LinkStatus linkStatus() const;
static DrmContentType kwinToDrmContentType(ContentType type);
private:
QList<std::shared_ptr<DrmConnectorMode>> generateCommonModes();
std::shared_ptr<DrmConnectorMode> generateMode(const QSize &size, float refreshRate);

View file

@ -355,8 +355,10 @@ void DrmOutput::updateDpmsMode(DpmsMode dpmsMode)
bool DrmOutput::present()
{
RenderLoopPrivate *renderLoopPrivate = RenderLoopPrivate::get(m_renderLoop.get());
if (m_pipeline->syncMode() != renderLoopPrivate->presentMode) {
const auto type = DrmConnector::kwinToDrmContentType(contentType());
if (m_pipeline->syncMode() != renderLoopPrivate->presentMode || type != m_pipeline->contentType()) {
m_pipeline->setSyncMode(renderLoopPrivate->presentMode);
m_pipeline->setContentType(type);
if (DrmPipeline::commitPipelines({m_pipeline}, DrmPipeline::CommitMode::Test) == DrmPipeline::Error::None) {
m_pipeline->applyPendingChanges();
} else {

View file

@ -205,6 +205,10 @@ DrmPipeline::Error DrmPipeline::commitPipelinesAtomic(const QVector<DrmPipeline
void DrmPipeline::prepareAtomicPresentation()
{
if (const auto contentType = m_connector->getProp(DrmConnector::PropertyIndex::ContentType)) {
contentType->setEnum(m_pending.contentType);
}
m_pending.crtc->setPending(DrmCrtc::PropertyIndex::VrrEnabled, m_pending.syncMode == RenderLoopPrivate::SyncMode::Adaptive);
m_pending.crtc->setPending(DrmCrtc::PropertyIndex::Gamma_LUT, m_pending.gamma ? m_pending.gamma->blobId() : 0);
const auto modeSize = m_pending.mode->size();
@ -644,6 +648,11 @@ Output::RgbRange DrmPipeline::rgbRange() const
return m_pending.rgbRange;
}
DrmConnector::DrmContentType DrmPipeline::contentType() const
{
return m_pending.contentType;
}
void DrmPipeline::setCrtc(DrmCrtc *crtc)
{
if (crtc && m_pending.crtc && crtc->gammaRampSize() != m_pending.crtc->gammaRampSize() && m_pending.colorTransformation) {
@ -708,4 +717,9 @@ void DrmPipeline::setColorTransformation(const std::shared_ptr<ColorTransformati
m_pending.colorTransformation = transformation;
m_pending.gamma = std::make_shared<DrmGammaRamp>(m_pending.crtc, transformation);
}
void DrmPipeline::setContentType(DrmConnector::DrmContentType type)
{
m_pending.contentType = type;
}
}

View file

@ -20,6 +20,7 @@
#include "core/output.h"
#include "core/renderloop_p.h"
#include "drm_object_plane.h"
#include "drm_object_connector.h"
namespace KWin
{
@ -112,6 +113,7 @@ public:
RenderLoopPrivate::SyncMode syncMode() const;
uint32_t overscan() const;
Output::RgbRange rgbRange() const;
DrmConnector::DrmContentType contentType() const;
void setCrtc(DrmCrtc *crtc);
void setMode(const std::shared_ptr<DrmConnectorMode> &mode);
@ -124,6 +126,7 @@ public:
void setOverscan(uint32_t overscan);
void setRgbRange(Output::RgbRange range);
void setColorTransformation(const std::shared_ptr<ColorTransformation> &transformation);
void setContentType(DrmConnector::DrmContentType type);
enum class CommitMode {
Test,
@ -184,6 +187,7 @@ private:
RenderLoopPrivate::SyncMode syncMode = RenderLoopPrivate::SyncMode::Fixed;
std::shared_ptr<ColorTransformation> colorTransformation;
std::shared_ptr<DrmGammaRamp> gamma;
DrmConnector::DrmContentType contentType = DrmConnector::DrmContentType::Graphics;
std::shared_ptr<DrmPipelineLayer> layer;
std::shared_ptr<DrmOverlayLayer> cursorLayer;

View file

@ -118,6 +118,9 @@ DrmPipeline::Error DrmPipeline::applyPendingChangesLegacy()
qCWarning(KWIN_DRM) << "Setting gamma failed!" << strerror(errno);
return errnoToError();
}
if (const auto contentType = m_connector->getProp(DrmConnector::PropertyIndex::ContentType)) {
contentType->setEnumLegacy(m_pending.contentType);
}
setCursorLegacy();
moveCursorLegacy();
}

View file

@ -628,6 +628,7 @@ void Compositor::composite(RenderLoop *renderLoop)
SurfaceItem *scanoutCandidate = superLayer->delegate()->scanoutCandidate();
renderLoop->setFullscreenSurface(scanoutCandidate);
output->setContentType(scanoutCandidate ? scanoutCandidate->contentType() : ContentType::None);
renderLoop->beginFrame();
bool directScanout = false;

View file

@ -393,4 +393,14 @@ void Output::setColorTransformation(const std::shared_ptr<ColorTransformation> &
Q_UNUSED(transformation);
}
ContentType Output::contentType() const
{
return m_contentType;
}
void Output::setContentType(ContentType contentType)
{
m_contentType = contentType;
}
} // namespace KWin

View file

@ -238,6 +238,9 @@ public:
RenderLoop::VrrPolicy vrrPolicy() const;
RgbRange rgbRange() const;
ContentType contentType() const;
void setContentType(ContentType contentType);
bool isPlaceholder() const;
bool isNonDesktop() const;
@ -339,6 +342,7 @@ protected:
QUuid m_uuid;
int m_directScanoutCount = 0;
int m_refCount = 1;
ContentType m_contentType = ContentType::None;
friend class EffectScreenImpl; // to access m_effectScreen
};

View file

@ -152,6 +152,11 @@ WindowQuadList SurfaceItem::buildQuads() const
return quads;
}
ContentType SurfaceItem::contentType() const
{
return ContentType::None;
}
SurfaceTexture::~SurfaceTexture()
{
}

View file

@ -6,6 +6,7 @@
#pragma once
#include "core/output.h"
#include "item.h"
namespace KWin
@ -41,6 +42,8 @@ public:
void referencePreviousPixmap();
void unreferencePreviousPixmap();
virtual ContentType contentType() const;
protected:
explicit SurfaceItem(Window *window, Item *parent = nullptr);

View file

@ -137,6 +137,11 @@ std::unique_ptr<SurfacePixmap> SurfaceItemWayland::createPixmap()
return std::make_unique<SurfacePixmapWayland>(this);
}
ContentType SurfaceItemWayland::contentType() const
{
return m_surface->contentType();
}
SurfacePixmapWayland::SurfacePixmapWayland(SurfaceItemWayland *item, QObject *parent)
: SurfacePixmap(Compositor::self()->scene()->createSurfaceTextureWayland(this), parent)
, m_item(item)

View file

@ -31,6 +31,7 @@ public:
QRegion shape() const override;
QRegion opaque() const override;
ContentType contentType() const override;
KWaylandServer::SurfaceInterface *surface() const;