backends/drm: Store desktop and non-desktop outputs in the same list

Now, the drm backend exposes all outputs. It's the job of the workspace
layer to filter out outputs it's not interested in.
This commit is contained in:
Vlad Zahorodnii 2022-07-11 12:53:45 +03:00
parent 8dabeb4709
commit 724d6761cd
3 changed files with 20 additions and 55 deletions

View file

@ -386,7 +386,7 @@ QString connectedOutputsHash(const QVector<DrmAbstractOutput *> &outputs)
QStringList hashedOutputs; QStringList hashedOutputs;
hashedOutputs.reserve(outputs.count()); hashedOutputs.reserve(outputs.count());
for (auto output : qAsConst(outputs)) { for (auto output : qAsConst(outputs)) {
if (!output->isPlaceholder()) { if (!output->isPlaceholder() && !output->isNonDesktop()) {
hashedOutputs << outputHash(output); hashedOutputs << outputHash(output);
} }
} }
@ -465,7 +465,7 @@ bool DrmBackend::readOutputsConfiguration(const QVector<DrmAbstractOutput *> &ou
// default position goes from left to right // default position goes from left to right
QPoint pos(0, 0); QPoint pos(0, 0);
for (const auto &output : qAsConst(outputs)) { for (const auto &output : qAsConst(outputs)) {
if (output->isPlaceholder()) { if (output->isPlaceholder() || output->isNonDesktop()) {
continue; continue;
} }
auto props = cfg.changeSet(output); auto props = cfg.changeSet(output);
@ -688,8 +688,8 @@ bool DrmBackend::applyOutputChanges(const OutputConfiguration &config)
const auto &outputs = gpu->outputs(); const auto &outputs = gpu->outputs();
for (const auto &o : outputs) { for (const auto &o : outputs) {
DrmOutput *output = qobject_cast<DrmOutput *>(o); DrmOutput *output = qobject_cast<DrmOutput *>(o);
if (!output) { if (!output || output->isNonDesktop()) {
// virtual outputs don't need testing // virtual and non-desktop outputs don't need testing
continue; continue;
} }
output->queueChanges(config); output->queueChanges(config);

View file

@ -115,11 +115,6 @@ DrmGpu::DrmGpu(DrmBackend *backend, const QString &devNode, int fd, dev_t device
DrmGpu::~DrmGpu() DrmGpu::~DrmGpu()
{ {
const auto leaseOutputs = m_nonDesktopOutputs;
for (const auto &output : leaseOutputs) {
removeNonDesktopOutput(output);
}
delete m_leaseDevice;
waitIdle(); waitIdle();
const auto outputs = m_outputs; const auto outputs = m_outputs;
for (const auto &output : outputs) { for (const auto &output : outputs) {
@ -136,6 +131,7 @@ DrmGpu::~DrmGpu()
m_connectors.clear(); m_connectors.clear();
m_planes.clear(); m_planes.clear();
delete m_socketNotifier; delete m_socketNotifier;
delete m_leaseDevice;
if (m_gbmDevice) { if (m_gbmDevice) {
gbm_device_destroy(m_gbmDevice); gbm_device_destroy(m_gbmDevice);
} }
@ -231,17 +227,17 @@ bool DrmGpu::updateOutputs()
// In principle these things are supposed to be detected through the wayland protocol. // In principle these things are supposed to be detected through the wayland protocol.
// In practice SteamVR doesn't always behave correctly // In practice SteamVR doesn't always behave correctly
auto lessees = drmModeListLessees(m_fd); auto lessees = drmModeListLessees(m_fd);
for (const auto &leaseOutput : qAsConst(m_nonDesktopOutputs)) { for (const auto &output : qAsConst(m_drmOutputs)) {
if (leaseOutput->lease()) { if (output->lease()) {
bool leaseActive = false; bool leaseActive = false;
for (uint i = 0; i < lessees->count; i++) { for (uint i = 0; i < lessees->count; i++) {
if (lessees->lessees[i] == leaseOutput->lease()->lesseeId()) { if (lessees->lessees[i] == output->lease()->lesseeId()) {
leaseActive = true; leaseActive = true;
break; break;
} }
} }
if (!leaseActive) { if (!leaseActive) {
leaseOutput->lease()->revoke(); output->lease()->revoke();
} }
} }
} }
@ -270,29 +266,21 @@ bool DrmGpu::updateOutputs()
for (auto it = m_connectors.begin(); it != m_connectors.end();) { for (auto it = m_connectors.begin(); it != m_connectors.end();) {
DrmConnector *conn = it->get(); DrmConnector *conn = it->get();
const auto output = findOutput(conn->id()); const auto output = findOutput(conn->id());
const auto nonDesktopOutput = findNonDesktopOutput(conn->id());
const bool stillExists = existing.contains(conn); const bool stillExists = existing.contains(conn);
if (!stillExists || !conn->isConnected()) { if (!stillExists || !conn->isConnected()) {
if (output) { if (output) {
removeOutput(output); removeOutput(output);
} else if (nonDesktopOutput) {
removeNonDesktopOutput(nonDesktopOutput);
} }
conn->disable(); conn->disable();
} else if (!output && !nonDesktopOutput) { } else if (!output) {
qCDebug(KWIN_DRM, "New %soutput on GPU %s: %s", conn->isNonDesktop() ? "non-desktop " : "", qPrintable(m_devNode), qPrintable(conn->modelName())); qCDebug(KWIN_DRM, "New %soutput on GPU %s: %s", conn->isNonDesktop() ? "non-desktop " : "", qPrintable(m_devNode), qPrintable(conn->modelName()));
const auto pipeline = conn->pipeline(); const auto pipeline = conn->pipeline();
m_pipelines << pipeline; m_pipelines << pipeline;
if (conn->isNonDesktop()) { auto output = new DrmOutput(pipeline, m_leaseDevice);
auto output = new DrmOutput(pipeline, m_leaseDevice); m_drmOutputs << output;
m_nonDesktopOutputs << output; m_outputs << output;
} else { addedOutputs << output;
auto output = new DrmOutput(pipeline, m_leaseDevice); Q_EMIT outputAdded(output);
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->setLayers(m_platform->renderBackend()->createPrimaryLayer(pipeline), m_platform->renderBackend()->createCursorLayer(pipeline));
pipeline->setActive(!conn->isNonDesktop()); pipeline->setActive(!conn->isNonDesktop());
pipeline->applyPendingChanges(); pipeline->applyPendingChanges();
@ -415,7 +403,7 @@ DrmPipeline::Error DrmGpu::testPendingConfiguration()
QVector<DrmCrtc *> crtcs; QVector<DrmCrtc *> crtcs;
// only change resources that aren't currently leased away // only change resources that aren't currently leased away
for (const auto &conn : m_connectors) { for (const auto &conn : m_connectors) {
bool isLeased = std::any_of(m_nonDesktopOutputs.cbegin(), m_nonDesktopOutputs.cend(), [&conn](const auto output) { bool isLeased = std::any_of(m_drmOutputs.cbegin(), m_drmOutputs.cend(), [&conn](const auto output) {
return output->lease() && output->pipeline()->connector() == conn.get(); return output->lease() && output->pipeline()->connector() == conn.get();
}); });
if (!isLeased) { if (!isLeased) {
@ -423,7 +411,7 @@ DrmPipeline::Error DrmGpu::testPendingConfiguration()
} }
} }
for (const auto &crtc : m_crtcs) { for (const auto &crtc : m_crtcs) {
bool isLeased = std::any_of(m_nonDesktopOutputs.cbegin(), m_nonDesktopOutputs.cend(), [&crtc](const auto output) { bool isLeased = std::any_of(m_drmOutputs.cbegin(), m_drmOutputs.cend(), [&crtc](const auto output) {
return output->lease() && output->pipeline()->crtc() == crtc.get(); return output->lease() && output->pipeline()->crtc() == crtc.get();
}); });
if (!isLeased) { if (!isLeased) {
@ -623,17 +611,6 @@ void DrmGpu::removeVirtualOutput(DrmVirtualOutput *output)
} }
} }
DrmOutput *DrmGpu::findNonDesktopOutput(quint32 connector)
{
auto it = std::find_if(m_nonDesktopOutputs.constBegin(), m_nonDesktopOutputs.constEnd(), [connector](DrmOutput *o) {
return o->pipeline()->connector()->id() == connector;
});
if (it != m_nonDesktopOutputs.constEnd()) {
return *it;
}
return nullptr;
}
void DrmGpu::handleLeaseRequest(KWaylandServer::DrmLeaseV1Interface *leaseRequest) void DrmGpu::handleLeaseRequest(KWaylandServer::DrmLeaseV1Interface *leaseRequest)
{ {
QVector<uint32_t> objects; QVector<uint32_t> objects;
@ -641,7 +618,7 @@ void DrmGpu::handleLeaseRequest(KWaylandServer::DrmLeaseV1Interface *leaseReques
const auto connectors = leaseRequest->connectors(); const auto connectors = leaseRequest->connectors();
for (KWaylandServer::DrmLeaseConnectorV1Interface *connector : connectors) { for (KWaylandServer::DrmLeaseConnectorV1Interface *connector : connectors) {
if (DrmOutput *output = findNonDesktopOutput(connector->id())) { if (DrmOutput *output = findOutput(connector->id())) {
if (output->lease()) { if (output->lease()) {
continue; // already leased continue; // already leased
} }
@ -678,7 +655,7 @@ void DrmGpu::handleLeaseRevoked(KWaylandServer::DrmLeaseV1Interface *lease)
{ {
const auto connectors = lease->connectors(); const auto connectors = lease->connectors();
for (KWaylandServer::DrmLeaseConnectorV1Interface *connector : connectors) { for (KWaylandServer::DrmLeaseConnectorV1Interface *connector : connectors) {
if (DrmOutput *output = findNonDesktopOutput(connector->id())) { if (DrmOutput *output = findOutput(connector->id())) {
output->leaseEnded(); output->leaseEnded();
} }
} }
@ -686,15 +663,6 @@ void DrmGpu::handleLeaseRevoked(KWaylandServer::DrmLeaseV1Interface *lease)
drmModeRevokeLease(m_fd, lease->lesseeId()); drmModeRevokeLease(m_fd, lease->lesseeId());
} }
void DrmGpu::removeNonDesktopOutput(DrmOutput *output)
{
qCDebug(KWIN_DRM) << "Removing leased output" << output;
m_nonDesktopOutputs.removeOne(output);
m_pipelines.removeOne(output->pipeline());
output->pipeline()->setLayers(nullptr, nullptr);
delete output;
}
QVector<DrmAbstractOutput *> DrmGpu::outputs() const QVector<DrmAbstractOutput *> DrmGpu::outputs() const
{ {
return m_outputs; return m_outputs;
@ -758,7 +726,7 @@ bool DrmGpu::needsModeset() const
bool DrmGpu::maybeModeset() bool DrmGpu::maybeModeset()
{ {
auto pipelines = m_pipelines; auto pipelines = m_pipelines;
for (const auto &output : qAsConst(m_nonDesktopOutputs)) { for (const auto &output : qAsConst(m_drmOutputs)) {
if (output->lease()) { if (output->lease()) {
pipelines.removeOne(output->pipeline()); pipelines.removeOne(output->pipeline());
} }

View file

@ -93,9 +93,7 @@ Q_SIGNALS:
private: private:
void dispatchEvents(); void dispatchEvents();
DrmOutput *findOutput(quint32 connector); DrmOutput *findOutput(quint32 connector);
DrmOutput *findNonDesktopOutput(quint32 connector);
void removeOutput(DrmOutput *output); void removeOutput(DrmOutput *output);
void removeNonDesktopOutput(DrmOutput *output);
void initDrmResources(); void initDrmResources();
void waitIdle(); void waitIdle();
@ -128,7 +126,6 @@ private:
QVector<DrmOutput *> m_drmOutputs; QVector<DrmOutput *> m_drmOutputs;
QVector<DrmAbstractOutput *> m_outputs; QVector<DrmAbstractOutput *> m_outputs;
QVector<DrmOutput *> m_nonDesktopOutputs;
KWaylandServer::DrmLeaseDeviceV1Interface *m_leaseDevice = nullptr; KWaylandServer::DrmLeaseDeviceV1Interface *m_leaseDevice = nullptr;
QSocketNotifier *m_socketNotifier = nullptr; QSocketNotifier *m_socketNotifier = nullptr;