backends/drm: force a modeset when connectors are unplugged

And turn off unused CRTCs with legacy

BUG: 478476
This commit is contained in:
Xaver Hugl 2023-12-21 03:23:29 +01:00
parent d69331d186
commit 9ea6f311ea
5 changed files with 15 additions and 9 deletions

View file

@ -578,6 +578,8 @@ void DrmGpu::removeOutput(DrmOutput *output)
m_drmOutputs.removeOne(output);
Q_EMIT outputRemoved(output);
output->unref();
// force a modeset to make sure unused objects are cleaned up
m_forceModeset = true;
}
DrmBackend *DrmGpu::platform() const
@ -740,9 +742,9 @@ bool DrmGpu::isActive() const
bool DrmGpu::needsModeset() const
{
return std::any_of(m_pipelines.constBegin(), m_pipelines.constEnd(), [](const auto &pipeline) {
return pipeline->needsModeset();
});
return m_forceModeset || std::any_of(m_pipelines.constBegin(), m_pipelines.constEnd(), [](const auto &pipeline) {
return pipeline->needsModeset();
});
}
bool DrmGpu::maybeModeset()
@ -771,6 +773,7 @@ bool DrmGpu::maybeModeset()
}
}
}
m_forceModeset = false;
if (err == DrmPipeline::Error::None) {
return true;
} else {
@ -783,9 +786,6 @@ bool DrmGpu::maybeModeset()
QList<DrmObject *> DrmGpu::unusedObjects() const
{
if (!m_atomicModeSetting) {
return {};
}
QList<DrmObject *> ret = m_allObjects;
for (const auto &pipeline : m_pipelines) {
ret.removeOne(pipeline->connector());

View file

@ -143,6 +143,7 @@ private:
bool m_asyncPageflipSupported = false;
bool m_isRemoved = false;
bool m_isActive = true;
bool m_forceModeset = false;
clockid_t m_presentationClock;
gbm_device *m_gbmDevice;
FileDescriptor m_gbmFd;

View file

@ -118,7 +118,7 @@ DrmPipeline::Error DrmPipeline::commitPipelines(const QList<DrmPipeline *> &pipe
if (pipelines[0]->gpu()->atomicModeSetting()) {
return commitPipelinesAtomic(pipelines, mode, unusedObjects);
} else {
return commitPipelinesLegacy(pipelines, mode);
return commitPipelinesLegacy(pipelines, mode, unusedObjects);
}
}

View file

@ -153,7 +153,7 @@ private:
Error legacyModeset();
Error applyPendingChangesLegacy();
bool setCursorLegacy();
static Error commitPipelinesLegacy(const QList<DrmPipeline *> &pipelines, CommitMode mode);
static Error commitPipelinesLegacy(const QList<DrmPipeline *> &pipelines, CommitMode mode, const QList<DrmObject *> &unusedObjects);
// atomic modesetting only
Error prepareAtomicCommit(DrmAtomicCommit *commit, CommitMode mode);

View file

@ -57,7 +57,7 @@ DrmPipeline::Error DrmPipeline::legacyModeset()
return Error::None;
}
DrmPipeline::Error DrmPipeline::commitPipelinesLegacy(const QList<DrmPipeline *> &pipelines, CommitMode mode)
DrmPipeline::Error DrmPipeline::commitPipelinesLegacy(const QList<DrmPipeline *> &pipelines, CommitMode mode, const QList<DrmObject *> &unusedObjects)
{
Error err = Error::None;
for (const auto &pipeline : pipelines) {
@ -79,6 +79,11 @@ DrmPipeline::Error DrmPipeline::commitPipelinesLegacy(const QList<DrmPipeline *>
pipeline->pageFlipped(std::chrono::steady_clock::now().time_since_epoch(), PageflipType::Normal, PresentationMode::VSync);
}
}
for (const auto &obj : unusedObjects) {
if (auto crtc = dynamic_cast<DrmCrtc *>(obj)) {
drmModeSetCrtc(pipelines.front()->gpu()->fd(), crtc->id(), 0, 0, 0, nullptr, 0, nullptr);
}
}
}
return err;
}