diff --git a/src/backends/drm/CMakeLists.txt b/src/backends/drm/CMakeLists.txt index 2cd2e768bb..3958822ecf 100644 --- a/src/backends/drm/CMakeLists.txt +++ b/src/backends/drm/CMakeLists.txt @@ -17,7 +17,6 @@ set(DRM_SOURCES drm_pipeline_legacy.cpp drm_abstract_output.cpp drm_virtual_output.cpp - drm_lease_output.cpp drm_qpainter_layer.cpp egl_gbm_backend.cpp egl_gbm_layer.cpp diff --git a/src/backends/drm/drm_gpu.cpp b/src/backends/drm/drm_gpu.cpp index 6a6d86369c..f465ab8744 100644 --- a/src/backends/drm/drm_gpu.cpp +++ b/src/backends/drm/drm_gpu.cpp @@ -13,7 +13,6 @@ #include "abstract_egl_backend.h" #include "drm_backend.h" #include "drm_layer.h" -#include "drm_lease_output.h" #include "drm_object_connector.h" #include "drm_object_crtc.h" #include "drm_object_plane.h" @@ -116,9 +115,9 @@ DrmGpu::DrmGpu(DrmBackend *backend, const QString &devNode, int fd, dev_t device DrmGpu::~DrmGpu() { - const auto leaseOutputs = m_leaseOutputs; + const auto leaseOutputs = m_nonDesktopOutputs; for (const auto &output : leaseOutputs) { - removeLeaseOutput(output); + removeNonDesktopOutput(output); } delete m_leaseDevice; waitIdle(); @@ -232,7 +231,7 @@ bool DrmGpu::updateOutputs() // In principle these things are supposed to be detected through the wayland protocol. // In practice SteamVR doesn't always behave correctly auto lessees = drmModeListLessees(m_fd); - for (const auto &leaseOutput : qAsConst(m_leaseOutputs)) { + for (const auto &leaseOutput : qAsConst(m_nonDesktopOutputs)) { if (leaseOutput->lease()) { bool leaseActive = false; for (uint i = 0; i < lessees->count; i++) { @@ -271,24 +270,24 @@ bool DrmGpu::updateOutputs() for (auto it = m_connectors.begin(); it != m_connectors.end();) { DrmConnector *conn = it->get(); const auto output = findOutput(conn->id()); - const auto leaseOutput = findLeaseOutput(conn->id()); + const auto nonDesktopOutput = findNonDesktopOutput(conn->id()); const bool stillExists = existing.contains(conn); if (!stillExists || !conn->isConnected()) { if (output) { removeOutput(output); - } else if (leaseOutput) { - removeLeaseOutput(leaseOutput); + } else if (nonDesktopOutput) { + removeNonDesktopOutput(nonDesktopOutput); } conn->disable(); - } else if (!output && !leaseOutput) { + } else if (!output && !nonDesktopOutput) { 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; + auto output = new DrmOutput(pipeline, m_leaseDevice); + m_nonDesktopOutputs << output; } else { - auto output = new DrmOutput(pipeline); + auto output = new DrmOutput(pipeline, m_leaseDevice); m_drmOutputs << output; m_outputs << output; addedOutputs << output; @@ -416,7 +415,7 @@ DrmPipeline::Error DrmGpu::testPendingConfiguration() QVector crtcs; // only change resources that aren't currently leased away for (const auto &conn : m_connectors) { - bool isLeased = std::any_of(m_leaseOutputs.cbegin(), m_leaseOutputs.cend(), [&conn](const auto output) { + bool isLeased = std::any_of(m_nonDesktopOutputs.cbegin(), m_nonDesktopOutputs.cend(), [&conn](const auto output) { return output->lease() && output->pipeline()->connector() == conn.get(); }); if (!isLeased) { @@ -424,7 +423,7 @@ DrmPipeline::Error DrmGpu::testPendingConfiguration() } } for (const auto &crtc : m_crtcs) { - bool isLeased = std::any_of(m_leaseOutputs.cbegin(), m_leaseOutputs.cend(), [&crtc](const auto output) { + bool isLeased = std::any_of(m_nonDesktopOutputs.cbegin(), m_nonDesktopOutputs.cend(), [&crtc](const auto output) { return output->lease() && output->pipeline()->crtc() == crtc.get(); }); if (!isLeased) { @@ -624,12 +623,12 @@ void DrmGpu::removeVirtualOutput(DrmVirtualOutput *output) } } -DrmLeaseOutput *DrmGpu::findLeaseOutput(quint32 connector) +DrmOutput *DrmGpu::findNonDesktopOutput(quint32 connector) { - auto it = std::find_if(m_leaseOutputs.constBegin(), m_leaseOutputs.constEnd(), [connector](DrmLeaseOutput *o) { + auto it = std::find_if(m_nonDesktopOutputs.constBegin(), m_nonDesktopOutputs.constEnd(), [connector](DrmOutput *o) { return o->pipeline()->connector()->id() == connector; }); - if (it != m_leaseOutputs.constEnd()) { + if (it != m_nonDesktopOutputs.constEnd()) { return *it; } return nullptr; @@ -638,11 +637,11 @@ DrmLeaseOutput *DrmGpu::findLeaseOutput(quint32 connector) void DrmGpu::handleLeaseRequest(KWaylandServer::DrmLeaseV1Interface *leaseRequest) { QVector objects; - QVector outputs; + QVector outputs; const auto connectors = leaseRequest->connectors(); for (KWaylandServer::DrmLeaseConnectorV1Interface *connector : connectors) { - if (DrmLeaseOutput *output = findLeaseOutput(connector->id())) { + if (DrmOutput *output = findNonDesktopOutput(connector->id())) { if (output->lease()) { continue; // already leased } @@ -679,7 +678,7 @@ void DrmGpu::handleLeaseRevoked(KWaylandServer::DrmLeaseV1Interface *lease) { const auto connectors = lease->connectors(); for (KWaylandServer::DrmLeaseConnectorV1Interface *connector : connectors) { - if (DrmLeaseOutput *output = findLeaseOutput(connector->id())) { + if (DrmOutput *output = findNonDesktopOutput(connector->id())) { output->leaseEnded(); } } @@ -687,10 +686,10 @@ void DrmGpu::handleLeaseRevoked(KWaylandServer::DrmLeaseV1Interface *lease) drmModeRevokeLease(m_fd, lease->lesseeId()); } -void DrmGpu::removeLeaseOutput(DrmLeaseOutput *output) +void DrmGpu::removeNonDesktopOutput(DrmOutput *output) { qCDebug(KWIN_DRM) << "Removing leased output" << output; - m_leaseOutputs.removeOne(output); + m_nonDesktopOutputs.removeOne(output); m_pipelines.removeOne(output->pipeline()); output->pipeline()->setLayers(nullptr, nullptr); delete output; @@ -759,7 +758,7 @@ bool DrmGpu::needsModeset() const bool DrmGpu::maybeModeset() { auto pipelines = m_pipelines; - for (const auto &output : qAsConst(m_leaseOutputs)) { + for (const auto &output : qAsConst(m_nonDesktopOutputs)) { if (output->lease()) { pipelines.removeOne(output->pipeline()); } diff --git a/src/backends/drm/drm_gpu.h b/src/backends/drm/drm_gpu.h index 937bc009c0..12b99ccb02 100644 --- a/src/backends/drm/drm_gpu.h +++ b/src/backends/drm/drm_gpu.h @@ -41,7 +41,6 @@ class DrmPlane; class DrmBackend; class EglGbmBackend; class DrmAbstractOutput; -class DrmLeaseOutput; class DrmRenderBackend; class DrmGpu : public QObject @@ -94,9 +93,9 @@ Q_SIGNALS: private: void dispatchEvents(); DrmOutput *findOutput(quint32 connector); - DrmLeaseOutput *findLeaseOutput(quint32 connector); + DrmOutput *findNonDesktopOutput(quint32 connector); void removeOutput(DrmOutput *output); - void removeLeaseOutput(DrmLeaseOutput *output); + void removeNonDesktopOutput(DrmOutput *output); void initDrmResources(); void waitIdle(); @@ -129,7 +128,7 @@ private: QVector m_drmOutputs; QVector m_outputs; - QVector m_leaseOutputs; + QVector m_nonDesktopOutputs; KWaylandServer::DrmLeaseDeviceV1Interface *m_leaseDevice = nullptr; QSocketNotifier *m_socketNotifier = nullptr; diff --git a/src/backends/drm/drm_lease_output.cpp b/src/backends/drm/drm_lease_output.cpp deleted file mode 100644 index 57daadcb2b..0000000000 --- a/src/backends/drm/drm_lease_output.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2021 Xaver Hugl - - SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "drm_lease_output.h" - -#include "drm_layer.h" -#include "drm_object_connector.h" -#include "drm_object_crtc.h" -#include "drm_object_plane.h" -#include "drm_pipeline.h" -#include "wayland/drmleasedevice_v1_interface.h" - -#include "logging.h" - -#include - -namespace KWin -{ - -DrmLeaseOutput::DrmLeaseOutput(DrmPipeline *pipeline, KWaylandServer::DrmLeaseDeviceV1Interface *leaseDevice) - : m_pipeline(pipeline) -{ - const DrmConnector *connector = pipeline->connector(); - qCDebug(KWIN_DRM) << "offering connector" << connector->id() << "for lease"; - - m_offer = std::make_unique( - leaseDevice, - connector->id(), - connector->modelName(), - QStringLiteral("%1 %2").arg(connector->edid()->manufacturerString(), connector->modelName())); -} - -DrmLeaseOutput::~DrmLeaseOutput() -{ - qCDebug(KWIN_DRM) << "revoking lease offer for connector" << m_pipeline->connector()->id(); -} - -bool DrmLeaseOutput::addLeaseObjects(QVector &objectList) -{ - if (!m_pipeline->crtc()) { - qCWarning(KWIN_DRM) << "Can't lease connector: No suitable crtc available"; - return false; - } - qCDebug(KWIN_DRM) << "adding connector" << m_pipeline->connector()->id() << "to lease"; - objectList << m_pipeline->connector()->id(); - objectList << m_pipeline->crtc()->id(); - if (m_pipeline->crtc()->primaryPlane()) { - objectList << m_pipeline->crtc()->primaryPlane()->id(); - } - return true; -} - -void DrmLeaseOutput::leased(KWaylandServer::DrmLeaseV1Interface *lease) -{ - m_lease = lease; -} - -void DrmLeaseOutput::leaseEnded() -{ - qCDebug(KWIN_DRM) << "ended lease for connector" << m_pipeline->connector()->id(); - m_lease = nullptr; -} - -KWaylandServer::DrmLeaseV1Interface *DrmLeaseOutput::lease() const -{ - return m_lease; -} - -DrmPipeline *DrmLeaseOutput::pipeline() const -{ - return m_pipeline; -} - -} diff --git a/src/backends/drm/drm_lease_output.h b/src/backends/drm/drm_lease_output.h deleted file mode 100644 index 3334bdfea2..0000000000 --- a/src/backends/drm/drm_lease_output.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2021 Xaver Hugl - - SPDX-License-Identifier: GPL-2.0-or-later - */ - -#pragma once - -#include "wayland/drmleasedevice_v1_interface.h" -#include -#include - -namespace KWin -{ - -class DrmConnector; -class DrmPipeline; - -/** - * a DrmLeaseOutput represents a non-desktop output (usually a VR headset) - * that is not used directly by the compositor but is instead leased out to - * applications (usually VR compositors) that drive the output themselves - */ -class DrmLeaseOutput -{ -public: - DrmLeaseOutput(DrmPipeline *pipeline, KWaylandServer::DrmLeaseDeviceV1Interface *leaseDevice); - ~DrmLeaseOutput(); - - bool addLeaseObjects(QVector &objectList); - void leased(KWaylandServer::DrmLeaseV1Interface *lease); - void leaseEnded(); - - KWaylandServer::DrmLeaseV1Interface *lease() const; - DrmPipeline *pipeline() const; - -private: - DrmPipeline *m_pipeline; - std::unique_ptr m_offer; - KWaylandServer::DrmLeaseV1Interface *m_lease = nullptr; -}; - -} diff --git a/src/backends/drm/drm_output.cpp b/src/backends/drm/drm_output.cpp index 322797b1c5..27921d95ea 100644 --- a/src/backends/drm/drm_output.cpp +++ b/src/backends/drm/drm_output.cpp @@ -28,6 +28,7 @@ #include "renderloop_p.h" #include "scene.h" #include "session.h" +#include "wayland/drmleasedevice_v1_interface.h" // Qt #include #include @@ -42,7 +43,7 @@ namespace KWin { -DrmOutput::DrmOutput(DrmPipeline *pipeline) +DrmOutput::DrmOutput(DrmPipeline *pipeline, KWaylandServer::DrmLeaseDeviceV1Interface *leaseDevice) : DrmAbstractOutput(pipeline->connector()->gpu()) , m_pipeline(pipeline) , m_connector(pipeline->connector()) @@ -78,6 +79,7 @@ DrmOutput::DrmOutput(DrmPipeline *pipeline) .subPixel = conn->subpixel(), .capabilities = capabilities, .internal = conn->isInternal(), + .nonDesktop = conn->isNonDesktop(), }); const QList> modes = getModes(); @@ -93,9 +95,17 @@ DrmOutput::DrmOutput(DrmPipeline *pipeline) setDrmDpmsMode(DpmsMode::Off); }); - connect(Cursors::self(), &Cursors::currentCursorChanged, this, &DrmOutput::updateCursor); - connect(Cursors::self(), &Cursors::hiddenChanged, this, &DrmOutput::updateCursor); - connect(Cursors::self(), &Cursors::positionChanged, this, &DrmOutput::moveCursor); + if (conn->isNonDesktop()) { + m_offer = std::make_unique( + leaseDevice, + conn->id(), + conn->modelName(), + QStringLiteral("%1 %2").arg(conn->edid()->manufacturerString(), conn->modelName())); + } else { + connect(Cursors::self(), &Cursors::currentCursorChanged, this, &DrmOutput::updateCursor); + connect(Cursors::self(), &Cursors::hiddenChanged, this, &DrmOutput::updateCursor); + connect(Cursors::self(), &Cursors::positionChanged, this, &DrmOutput::moveCursor); + } } DrmOutput::~DrmOutput() @@ -103,6 +113,40 @@ DrmOutput::~DrmOutput() m_pipeline->setOutput(nullptr); } +bool DrmOutput::addLeaseObjects(QVector &objectList) +{ + Q_ASSERT(m_offer); + if (!m_pipeline->crtc()) { + qCWarning(KWIN_DRM) << "Can't lease connector: No suitable crtc available"; + return false; + } + qCDebug(KWIN_DRM) << "adding connector" << m_pipeline->connector()->id() << "to lease"; + objectList << m_pipeline->connector()->id(); + objectList << m_pipeline->crtc()->id(); + if (m_pipeline->crtc()->primaryPlane()) { + objectList << m_pipeline->crtc()->primaryPlane()->id(); + } + return true; +} + +void DrmOutput::leased(KWaylandServer::DrmLeaseV1Interface *lease) +{ + Q_ASSERT(m_offer); + m_lease = lease; +} + +void DrmOutput::leaseEnded() +{ + Q_ASSERT(m_offer); + qCDebug(KWIN_DRM) << "ended lease for connector" << m_pipeline->connector()->id(); + m_lease = nullptr; +} + +KWaylandServer::DrmLeaseV1Interface *DrmOutput::lease() const +{ + return m_lease; +} + void DrmOutput::updateCursor() { static bool valid; diff --git a/src/backends/drm/drm_output.h b/src/backends/drm/drm_output.h index fadef52a13..c7891a3e3b 100644 --- a/src/backends/drm/drm_output.h +++ b/src/backends/drm/drm_output.h @@ -21,6 +21,13 @@ #include #include +namespace KWaylandServer +{ +class DrmLeaseConnectorV1Interface; +class DrmLeaseDeviceV1Interface; +class DrmLeaseV1Interface; +} + namespace KWin { @@ -35,7 +42,7 @@ class KWIN_EXPORT DrmOutput : public DrmAbstractOutput { Q_OBJECT public: - DrmOutput(DrmPipeline *pipeline); + DrmOutput(DrmPipeline *pipeline, KWaylandServer::DrmLeaseDeviceV1Interface *leaseDevice); ~DrmOutput() override; DrmConnector *connector() const; @@ -53,6 +60,11 @@ public: void updateCursor(); void moveCursor(); + KWaylandServer::DrmLeaseV1Interface *lease() const; + bool addLeaseObjects(QVector &objectList); + void leased(KWaylandServer::DrmLeaseV1Interface *lease); + void leaseEnded(); + void setColorTransformation(const std::shared_ptr &transformation) override; private: @@ -73,6 +85,8 @@ private: bool m_cursorTextureDirty = true; std::unique_ptr m_cursorTexture; QTimer m_turnOffTimer; + std::unique_ptr m_offer; + KWaylandServer::DrmLeaseV1Interface *m_lease = nullptr; }; } diff --git a/src/backends/drm/egl_gbm_backend.cpp b/src/backends/drm/egl_gbm_backend.cpp index db17ccb435..59bfc29026 100644 --- a/src/backends/drm/egl_gbm_backend.cpp +++ b/src/backends/drm/egl_gbm_backend.cpp @@ -240,7 +240,7 @@ EGLConfig EglGbmBackend::config(uint32_t format) const std::shared_ptr EglGbmBackend::createPrimaryLayer(DrmPipeline *pipeline) { - if (pipeline->output()) { + if (!pipeline->output()->isNonDesktop()) { return std::make_shared(this, pipeline); } else { return std::make_shared(pipeline); diff --git a/src/backends/drm/scene_qpainter_drm_backend.cpp b/src/backends/drm/scene_qpainter_drm_backend.cpp index 9e152f5e95..0fc425aee7 100644 --- a/src/backends/drm/scene_qpainter_drm_backend.cpp +++ b/src/backends/drm/scene_qpainter_drm_backend.cpp @@ -46,7 +46,7 @@ OutputLayer *DrmQPainterBackend::primaryLayer(Output *output) std::shared_ptr DrmQPainterBackend::createPrimaryLayer(DrmPipeline *pipeline) { - if (pipeline->output()) { + if (!pipeline->output()->isNonDesktop()) { return std::make_shared(pipeline); } else { return std::make_shared(pipeline); diff --git a/src/output.cpp b/src/output.cpp index b76852a86a..76cc02e432 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -399,6 +399,11 @@ bool Output::isPlaceholder() const return m_information.placeholder; } +bool Output::isNonDesktop() const +{ + return m_information.nonDesktop; +} + Output::RgbRange Output::rgbRange() const { return m_rgbRange; diff --git a/src/output.h b/src/output.h index 84b5131ff2..156666eb24 100644 --- a/src/output.h +++ b/src/output.h @@ -239,6 +239,7 @@ public: RgbRange rgbRange() const; bool isPlaceholder() const; + bool isNonDesktop() const; virtual void setColorTransformation(const std::shared_ptr &transformation); @@ -310,6 +311,7 @@ protected: Capabilities capabilities; bool internal = false; bool placeholder = false; + bool nonDesktop = false; }; void setInformation(const Information &information);