Commit 2d43f3ee authored by Xaver Hugl's avatar Xaver Hugl
Browse files

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.
parent e96b9ba4
Pipeline #202220 passed with stage
in 13 minutes and 20 seconds
......@@ -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);
}
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment