backends/drm: handle disconnected but not removed connector objects properly
The kernel doesn't disable connector objects that represent physical ports when the output gets removed. If KWin tries to change the output configuration without explicitly disabling the connector, atomic commits can fail.
This commit is contained in:
parent
e96b9ba499
commit
2d43f3eee2
1 changed files with 30 additions and 19 deletions
|
@ -260,32 +260,43 @@ bool DrmGpu::updateOutputs()
|
|||
DrmConnector *conn = it == m_connectors.constEnd() ? nullptr : *it;
|
||||
if (!conn) {
|
||||
conn = new DrmConnector(this, currentConnector);
|
||||
if (!conn->init() || !conn->isConnected()) {
|
||||
if (!conn->init()) {
|
||||
delete conn;
|
||||
continue;
|
||||
}
|
||||
m_connectors << conn;
|
||||
m_allObjects << conn;
|
||||
qCDebug(KWIN_DRM, "New %soutput on GPU %s: %s", conn->isNonDesktop() ? "non-desktop " : "", qPrintable(m_devNode), qPrintable(conn->modelName()));
|
||||
const auto pipeline = conn->pipeline();
|
||||
m_pipelines << pipeline;
|
||||
if (conn->isNonDesktop()) {
|
||||
auto leaseOutput = new DrmLeaseOutput(pipeline, m_leaseDevice);
|
||||
m_leaseOutputs << leaseOutput;
|
||||
} else {
|
||||
auto output = new DrmOutput(pipeline);
|
||||
m_drmOutputs << output;
|
||||
m_outputs << output;
|
||||
addedOutputs << output;
|
||||
Q_EMIT outputAdded(output);
|
||||
}
|
||||
pipeline->setLayers(m_platform->renderBackend()->createPrimaryLayer(pipeline), m_platform->renderBackend()->createCursorLayer(pipeline));
|
||||
pipeline->setActive(!conn->isNonDesktop());
|
||||
pipeline->applyPendingChanges();
|
||||
} else {
|
||||
conn->updateProperties();
|
||||
if (conn->isConnected()) {
|
||||
removedConnectors.removeOne(conn);
|
||||
removedConnectors.removeOne(conn);
|
||||
}
|
||||
auto output = findOutput(conn->id());
|
||||
auto leaseOutput = findLeaseOutput(conn->id());
|
||||
if (conn->isConnected()) {
|
||||
if (!output && !leaseOutput) {
|
||||
qCDebug(KWIN_DRM, "New %soutput on GPU %s: %s", conn->isNonDesktop() ? "non-desktop " : "", qPrintable(m_devNode), qPrintable(conn->modelName()));
|
||||
const auto pipeline = conn->pipeline();
|
||||
m_pipelines << pipeline;
|
||||
if (conn->isNonDesktop()) {
|
||||
auto leaseOutput = new DrmLeaseOutput(pipeline, m_leaseDevice);
|
||||
m_leaseOutputs << leaseOutput;
|
||||
} else {
|
||||
auto output = new DrmOutput(pipeline);
|
||||
m_drmOutputs << output;
|
||||
m_outputs << output;
|
||||
addedOutputs << output;
|
||||
Q_EMIT outputAdded(output);
|
||||
}
|
||||
pipeline->setLayers(m_platform->renderBackend()->createPrimaryLayer(pipeline), m_platform->renderBackend()->createCursorLayer(pipeline));
|
||||
pipeline->setActive(!conn->isNonDesktop());
|
||||
pipeline->applyPendingChanges();
|
||||
}
|
||||
} else {
|
||||
conn->disable();
|
||||
if (output) {
|
||||
removeOutput(output);
|
||||
} else if (leaseOutput) {
|
||||
removeLeaseOutput(leaseOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue