From 8c412c229b9edfc9ed6e8de4c5ae1975e7dbcfc7 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Thu, 27 Apr 2023 13:18:52 +0200 Subject: [PATCH] backends/drm: track device active status per GPU --- src/backends/drm/drm_backend.cpp | 65 +++------------------------ src/backends/drm/drm_backend.h | 7 --- src/backends/drm/drm_gpu.cpp | 24 ++++++++++ src/backends/drm/drm_gpu.h | 4 ++ src/wayland/drmlease_v1_interface.cpp | 10 +---- 5 files changed, 35 insertions(+), 75 deletions(-) diff --git a/src/backends/drm/drm_backend.cpp b/src/backends/drm/drm_backend.cpp index a3c8690974..edb1cbc591 100644 --- a/src/backends/drm/drm_backend.cpp +++ b/src/backends/drm/drm_backend.cpp @@ -87,11 +87,6 @@ Session *DrmBackend::session() const return m_session; } -bool DrmBackend::isActive() const -{ - return m_active; -} - Outputs DrmBackend::outputs() const { return m_outputs; @@ -133,60 +128,16 @@ void DrmBackend::checkOutputsAreOn() m_dpmsFilter.reset(); } -void DrmBackend::activate(bool active) -{ - if (active) { - qCDebug(KWIN_DRM) << "Activating session."; - reactivate(); - } else { - qCDebug(KWIN_DRM) << "Deactivating session."; - deactivate(); - } -} - -void DrmBackend::reactivate() -{ - if (m_active) { - return; - } - m_active = true; - - for (const auto &output : std::as_const(m_outputs)) { - output->renderLoop()->uninhibit(); - output->renderLoop()->scheduleRepaint(); - } - - // While the session had been inactive, an output could have been added or - // removed, we need to re-scan outputs. - updateOutputs(); - Q_EMIT activeChanged(); -} - -void DrmBackend::deactivate() -{ - if (!m_active) { - return; - } - - for (const auto &output : std::as_const(m_outputs)) { - output->renderLoop()->inhibit(); - } - - m_active = false; - Q_EMIT activeChanged(); -} - bool DrmBackend::initialize() { - // TODO: Pause/Resume individual GPU devices instead. connect(m_session, &Session::devicePaused, this, [this](dev_t deviceId) { - if (primaryGpu()->deviceId() == deviceId) { - deactivate(); + if (const auto gpu = findGpu(deviceId)) { + gpu->setActive(false); } }); connect(m_session, &Session::deviceResumed, this, [this](dev_t deviceId) { - if (primaryGpu()->deviceId() == deviceId) { - reactivate(); + if (const auto gpu = findGpu(deviceId)) { + gpu->setActive(true); } }); connect(m_session, &Session::awoke, this, &DrmBackend::turnOutputsOn); @@ -225,10 +176,6 @@ bool DrmBackend::initialize() void DrmBackend::handleUdevEvent() { while (auto device = m_udevMonitor->getDevice()) { - if (!m_active) { - continue; - } - // Ignore the device seat if the KWIN_DRM_DEVICES envvar is set. if (!m_explicitGpus.isEmpty()) { if (!m_explicitGpus.contains(device->devNode())) { @@ -261,7 +208,7 @@ void DrmBackend::handleUdevEvent() if (!gpu) { gpu = addGpu(device->devNode()); } - if (gpu) { + if (gpu && gpu->isActive()) { qCDebug(KWIN_DRM) << "Received change event for monitored drm device" << gpu->devNode(); updateOutputs(); } @@ -296,7 +243,6 @@ DrmGpu *DrmBackend::addGpu(const QString &fileName) qCDebug(KWIN_DRM, "adding GPU %s", qPrintable(fileName)); m_gpus.push_back(std::make_unique(this, fileName, fd, buf.st_rdev)); auto gpu = m_gpus.back().get(); - m_active = true; connect(gpu, &DrmGpu::outputAdded, this, &DrmBackend::addOutput); connect(gpu, &DrmGpu::outputRemoved, this, &DrmBackend::removeOutput); Q_EMIT gpuAdded(gpu); @@ -380,7 +326,6 @@ QString DrmBackend::supportInformation() const s.nospace(); s << "Name: " << "DRM" << Qt::endl; - s << "Active: " << m_active << Qt::endl; for (size_t g = 0; g < m_gpus.size(); g++) { s << "Atomic Mode Setting on GPU " << g << ": " << m_gpus.at(g)->atomicModeSetting() << Qt::endl; } diff --git a/src/backends/drm/drm_backend.h b/src/backends/drm/drm_backend.h index 984351a653..bd113b05ca 100644 --- a/src/backends/drm/drm_backend.h +++ b/src/backends/drm/drm_backend.h @@ -68,8 +68,6 @@ public: DrmGpu *findGpu(dev_t deviceId) const; size_t gpuCount() const; - bool isActive() const; - void setRenderBackend(DrmRenderBackend *backend); DrmRenderBackend *renderBackend() const; @@ -83,7 +81,6 @@ public Q_SLOTS: void sceneInitialized() override; Q_SIGNALS: - void activeChanged(); void gpuAdded(DrmGpu *gpu); void gpuRemoved(DrmGpu *gpu); @@ -94,9 +91,6 @@ private: friend class DrmGpu; void addOutput(DrmAbstractOutput *output); void removeOutput(DrmAbstractOutput *output); - void activate(bool active); - void reactivate(); - void deactivate(); void handleUdevEvent(); DrmGpu *addGpu(const QString &fileName); @@ -107,7 +101,6 @@ private: QVector m_outputs; DrmVirtualOutput *m_placeHolderOutput = nullptr; - bool m_active = false; const QStringList m_explicitGpus; std::vector> m_gpus; std::unique_ptr m_dpmsFilter; diff --git a/src/backends/drm/drm_gpu.cpp b/src/backends/drm/drm_gpu.cpp index ee4e1f4113..6771ae1f17 100644 --- a/src/backends/drm/drm_gpu.cpp +++ b/src/backends/drm/drm_gpu.cpp @@ -690,6 +690,30 @@ void DrmGpu::setRemoved() m_isRemoved = true; } +void DrmGpu::setActive(bool active) +{ + if (m_isActive != active) { + m_isActive = active; + if (active) { + for (const auto &output : std::as_const(m_drmOutputs)) { + output->renderLoop()->uninhibit(); + } + // while the session was inactive, the output list may have changed + m_platform->updateOutputs(); + } else { + for (const auto &output : std::as_const(m_drmOutputs)) { + output->renderLoop()->inhibit(); + } + } + Q_EMIT activeChanged(active); + } +} + +bool DrmGpu::isActive() const +{ + return m_isActive; +} + bool DrmGpu::needsModeset() const { return std::any_of(m_pipelines.constBegin(), m_pipelines.constEnd(), [](const auto &pipeline) { diff --git a/src/backends/drm/drm_gpu.h b/src/backends/drm/drm_gpu.h index 7737d36b1f..cfac2c5097 100644 --- a/src/backends/drm/drm_gpu.h +++ b/src/backends/drm/drm_gpu.h @@ -70,6 +70,8 @@ public: bool isRemoved() const; void setRemoved(); + void setActive(bool active); + bool isActive() const; bool atomicModeSetting() const; bool addFB2ModifiersSupported() const; @@ -108,6 +110,7 @@ public: std::unique_ptr leaseOutputs(const QVector &outputs); Q_SIGNALS: + void activeChanged(bool active); void outputAdded(DrmAbstractOutput *output); void outputRemoved(DrmAbstractOutput *output); @@ -133,6 +136,7 @@ private: bool m_isVirtualMachine; bool m_asyncPageflipSupported = false; bool m_isRemoved = false; + bool m_isActive = true; clockid_t m_presentationClock; gbm_device *m_gbmDevice; std::unique_ptr m_eglDisplay; diff --git a/src/wayland/drmlease_v1_interface.cpp b/src/wayland/drmlease_v1_interface.cpp index 2022653848..38351d1192 100644 --- a/src/wayland/drmlease_v1_interface.cpp +++ b/src/wayland/drmlease_v1_interface.cpp @@ -29,13 +29,6 @@ DrmLeaseManagerV1::DrmLeaseManagerV1(KWin::DrmBackend *backend, Display *display connect(m_backend, &KWin::DrmBackend::gpuAdded, this, &DrmLeaseManagerV1::addGpu); connect(m_backend, &KWin::DrmBackend::gpuRemoved, this, &DrmLeaseManagerV1::removeGpu); connect(m_backend, &KWin::DrmBackend::outputsQueried, this, &DrmLeaseManagerV1::handleOutputsQueried); - connect(m_backend, &KWin::DrmBackend::activeChanged, this, [this]() { - if (!m_backend->isActive()) { - for (const auto device : m_leaseDevices) { - device->setDrmMaster(false); - } - } - }); } DrmLeaseManagerV1::~DrmLeaseManagerV1() @@ -61,7 +54,7 @@ void DrmLeaseManagerV1::handleOutputsQueried() { for (const auto device : m_leaseDevices) { device->done(); - device->setDrmMaster(m_backend->isActive()); + device->setDrmMaster(device->gpu()->isActive()); } } @@ -75,6 +68,7 @@ DrmLeaseDeviceV1Interface::DrmLeaseDeviceV1Interface(Display *display, KWin::Drm } connect(gpu, &KWin::DrmGpu::outputAdded, this, &DrmLeaseDeviceV1Interface::addOutput); connect(gpu, &KWin::DrmGpu::outputRemoved, this, &DrmLeaseDeviceV1Interface::removeOutput); + connect(gpu, &KWin::DrmGpu::activeChanged, this, &DrmLeaseDeviceV1Interface::setDrmMaster); } DrmLeaseDeviceV1Interface::~DrmLeaseDeviceV1Interface()