backends/drm: set drm content type when available
This commit is contained in:
parent
b99ae81b08
commit
e9e97e49bf
13 changed files with 97 additions and 15 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -152,6 +152,11 @@ WindowQuadList SurfaceItem::buildQuads() const
|
|||
return quads;
|
||||
}
|
||||
|
||||
ContentType SurfaceItem::contentType() const
|
||||
{
|
||||
return ContentType::None;
|
||||
}
|
||||
|
||||
SurfaceTexture::~SurfaceTexture()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -31,6 +31,7 @@ public:
|
|||
|
||||
QRegion shape() const override;
|
||||
QRegion opaque() const override;
|
||||
ContentType contentType() const override;
|
||||
|
||||
KWaylandServer::SurfaceInterface *surface() const;
|
||||
|
||||
|
|
Loading…
Reference in a new issue