platforms/drm: tie primary planes to crtcs

This commit is contained in:
Xaver Hugl 2021-09-27 13:53:52 +02:00
parent 3a9491ca6d
commit fbb5c95cc4
6 changed files with 39 additions and 29 deletions

View file

@ -190,8 +190,24 @@ void DrmGpu::initDrmResources()
qCCritical(KWIN_DRM) << "drmModeGetResources for getting CRTCs failed on GPU" << m_devNode;
return;
}
auto planes = m_planes;
for (int i = 0; i < resources->count_crtcs; ++i) {
auto c = new DrmCrtc(this, resources->crtcs[i], i);
DrmPlane *primary = nullptr;
for (const auto &plane : qAsConst(planes)) {
if (plane->type() == DrmPlane::TypeIndex::Primary
&& plane->isCrtcSupported(i)) {
primary = plane;
if (plane->getProp(DrmPlane::PropertyIndex::CrtcId)->current() == resources->crtcs[i]) {
break;
}
}
}
if (m_atomicModeSetting && !primary) {
qCWarning(KWIN_DRM) << "Could not find a suitable primary plane for crtc" << resources->crtcs[i];
continue;
}
planes.removeOne(primary);
auto c = new DrmCrtc(this, resources->crtcs[i], i, primary);
if (!c->init()) {
delete c;
continue;
@ -301,18 +317,16 @@ bool DrmGpu::updateOutputs()
}
auto connectors = connectedConnectors;
auto crtcs = m_crtcs;
auto planes = m_planes;
// don't touch resources that are leased
for (const auto &output : qAsConst(m_leaseOutputs)) {
if (output->lease()) {
connectors.removeOne(output->pipeline()->connector());
crtcs.removeOne(output->pipeline()->crtc());
planes.removeOne(output->pipeline()->primaryPlane());
} else {
m_pipelines.removeOne(output->pipeline());
}
}
auto config = findWorkingCombination({}, connectors, crtcs, planes);
auto config = findWorkingCombination({}, connectors, crtcs);
if (config.isEmpty() && !connectors.isEmpty()) {
qCCritical(KWIN_DRM) << "DrmGpu::findWorkingCombination failed to find any functional combinations! Reverting to the old configuration!";
for (auto it = oldPipelines.begin(); it != oldPipelines.end(); it++) {
@ -368,7 +382,7 @@ bool DrmGpu::updateOutputs()
return true;
}
QVector<DrmPipeline *> DrmGpu::findWorkingCombination(const QVector<DrmPipeline *> &pipelines, QVector<DrmConnector *> connectors, QVector<DrmCrtc *> crtcs, const QVector<DrmPlane *> &planes)
QVector<DrmPipeline *> DrmGpu::findWorkingCombination(const QVector<DrmPipeline *> &pipelines, QVector<DrmConnector *> connectors, QVector<DrmCrtc *> crtcs)
{
if (connectors.isEmpty() || crtcs.isEmpty()) {
// no further pipelines can be added -> test configuration
@ -393,15 +407,13 @@ QVector<DrmPipeline *> DrmGpu::findWorkingCombination(const QVector<DrmPipeline
});
}
auto recurse = [this, connector, connectors, crtcs, planes, pipelines] (DrmCrtc *crtc, DrmPlane *primaryPlane) {
auto pipeline = new DrmPipeline(this, connector, crtc, primaryPlane);
auto recurse = [this, connector, connectors, crtcs, pipelines] (DrmCrtc *crtc) {
auto pipeline = new DrmPipeline(this, connector, crtc);
auto crtcsLeft = crtcs;
crtcsLeft.removeOne(crtc);
auto planesLeft = planes;
planesLeft.removeOne(primaryPlane);
auto allPipelines = pipelines;
allPipelines << pipeline;
auto ret = findWorkingCombination(allPipelines, connectors, crtcsLeft, planesLeft);
auto ret = findWorkingCombination(allPipelines, connectors, crtcsLeft);
if (ret.isEmpty()) {
delete pipeline;
}
@ -410,19 +422,8 @@ QVector<DrmPipeline *> DrmGpu::findWorkingCombination(const QVector<DrmPipeline
for (const auto &encoderId : encoders) {
DrmScopedPointer<drmModeEncoder> encoder(drmModeGetEncoder(m_fd, encoderId));
for (const auto &crtc : qAsConst(crtcs)) {
if (m_atomicModeSetting) {
for (const auto &plane : qAsConst(planes)) {
if (plane->type() == DrmPlane::TypeIndex::Primary
&& plane->isCrtcSupported(crtc->pipeIndex())) {
if (auto workingPipelines = recurse(crtc, plane); !workingPipelines.isEmpty()) {
return workingPipelines;
}
}
}
} else {
if (auto workingPipelines = recurse(crtc, nullptr); !workingPipelines.isEmpty()) {
return workingPipelines;
}
if (auto workingPipelines = recurse(crtc); !workingPipelines.isEmpty()) {
return workingPipelines;
}
}
}

View file

@ -92,7 +92,7 @@ private:
void removeLeaseOutput(DrmLeaseOutput *output);
void initDrmResources();
QVector<DrmPipeline *> findWorkingCombination(const QVector<DrmPipeline *> &pipelines, QVector<DrmConnector *> connectors, QVector<DrmCrtc *> crtcs, const QVector<DrmPlane *> &planes);
QVector<DrmPipeline *> findWorkingCombination(const QVector<DrmPipeline *> &pipelines, QVector<DrmConnector *> connectors, QVector<DrmCrtc *> crtcs);
bool commitCombination(const QVector<DrmPipeline *> &pipelines);
void handleLeaseRequest(KWaylandServer::DrmLeaseV1Interface *leaseRequest);

View file

@ -17,7 +17,7 @@
namespace KWin
{
DrmCrtc::DrmCrtc(DrmGpu *gpu, uint32_t crtcId, int pipeIndex)
DrmCrtc::DrmCrtc(DrmGpu *gpu, uint32_t crtcId, int pipeIndex, DrmPlane *primaryPlane)
: DrmObject(gpu, crtcId, {
PropertyDefinition(QByteArrayLiteral("MODE_ID"), Requirement::Required),
PropertyDefinition(QByteArrayLiteral("ACTIVE"), Requirement::Required),
@ -26,6 +26,7 @@ DrmCrtc::DrmCrtc(DrmGpu *gpu, uint32_t crtcId, int pipeIndex)
}, DRM_MODE_OBJECT_CRTC)
, m_crtc(drmModeGetCrtc(gpu->fd(), crtcId))
, m_pipeIndex(pipeIndex)
, m_primaryPlane(primaryPlane)
{
}
@ -132,4 +133,9 @@ QPoint DrmCrtc::cursorPos() const
return m_cursor.pos;
}
DrmPlane *DrmCrtc::primaryPlane() const
{
return m_primaryPlane;
}
}

View file

@ -22,11 +22,12 @@ class DrmBuffer;
class DrmDumbBuffer;
class GammaRamp;
class DrmGpu;
class DrmPlane;
class DrmCrtc : public DrmObject
{
public:
DrmCrtc(DrmGpu *gpu, uint32_t crtcId, int pipeIndex);
DrmCrtc(DrmGpu *gpu, uint32_t crtcId, int pipeIndex, DrmPlane *primaryPlane);
enum class PropertyIndex : uint32_t {
ModeId = 0,
@ -41,6 +42,7 @@ public:
int pipeIndex() const;
int gammaRampSize() const;
DrmPlane *primaryPlane() const;
drmModeModeInfo queryCurrentMode();
QSharedPointer<DrmBuffer> current() const;
@ -60,6 +62,7 @@ private:
QSharedPointer<DrmBuffer> m_currentBuffer;
QSharedPointer<DrmBuffer> m_nextBuffer;
int m_pipeIndex;
DrmPlane *m_primaryPlane;
struct {
QPoint pos;

View file

@ -34,12 +34,12 @@
namespace KWin
{
DrmPipeline::DrmPipeline(DrmGpu *gpu, DrmConnector *conn, DrmCrtc *crtc, DrmPlane *primaryPlane)
DrmPipeline::DrmPipeline(DrmGpu *gpu, DrmConnector *conn, DrmCrtc *crtc)
: m_output(nullptr)
, m_gpu(gpu)
, m_connector(conn)
, m_crtc(crtc)
, m_primaryPlane(primaryPlane)
, m_primaryPlane(crtc->primaryPlane())
{
m_allObjects << m_connector << m_crtc;
if (m_primaryPlane) {

View file

@ -33,7 +33,7 @@ class GammaRamp;
class DrmPipeline
{
public:
DrmPipeline(DrmGpu *gpu, DrmConnector *conn, DrmCrtc *crtc, DrmPlane *primaryPlane);
DrmPipeline(DrmGpu *gpu, DrmConnector *conn, DrmCrtc *crtc);
~DrmPipeline();
/**