backends/drm: track device active status per GPU

This commit is contained in:
Xaver Hugl 2023-04-27 13:18:52 +02:00
parent 258e9d8426
commit 8c412c229b
5 changed files with 35 additions and 75 deletions

View file

@ -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<DrmGpu>(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;
}

View file

@ -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<DrmAbstractOutput *> m_outputs;
DrmVirtualOutput *m_placeHolderOutput = nullptr;
bool m_active = false;
const QStringList m_explicitGpus;
std::vector<std::unique_ptr<DrmGpu>> m_gpus;
std::unique_ptr<DpmsInputEventFilter> m_dpmsFilter;

View file

@ -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) {

View file

@ -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<DrmLease> leaseOutputs(const QVector<DrmOutput *> &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<EglDisplay> m_eglDisplay;

View file

@ -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()