From 4610a916d3da5d2ed499172ef9809ce6204cf5b5 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Fri, 28 Jul 2023 15:36:34 +0200 Subject: [PATCH] backends/drm: handle atomic commits failing correctly If the pending pageflip flag is not reset, KWin will wait for a pageflip that never comes --- src/backends/drm/drm_commit_thread.cpp | 2 ++ src/backends/drm/drm_pipeline.cpp | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/backends/drm/drm_commit_thread.cpp b/src/backends/drm/drm_commit_thread.cpp index 1dd23eb9db..ecf91efa7d 100644 --- a/src/backends/drm/drm_commit_thread.cpp +++ b/src/backends/drm/drm_commit_thread.cpp @@ -9,6 +9,7 @@ #include "drm_commit_thread.h" #include "drm_commit.h" #include "drm_gpu.h" +#include "logging_p.h" #include "utils/realtime.h" namespace KWin @@ -42,6 +43,7 @@ DrmCommitThread::DrmCommitThread() // the atomic commit takes ownership of the object m_commit.release(); } else { + qCWarning(KWIN_DRM) << "atomic commit failed:" << strerror(errno); m_droppedCommits.push_back(std::move(m_commit)); QMetaObject::invokeMethod(this, &DrmCommitThread::commitFailed, Qt::ConnectionType::QueuedConnection); QMetaObject::invokeMethod(this, &DrmCommitThread::clearDroppedCommits, Qt::ConnectionType::QueuedConnection); diff --git a/src/backends/drm/drm_pipeline.cpp b/src/backends/drm/drm_pipeline.cpp index d14cede697..cbfc1cf2df 100644 --- a/src/backends/drm/drm_pipeline.cpp +++ b/src/backends/drm/drm_pipeline.cpp @@ -41,6 +41,12 @@ DrmPipeline::DrmPipeline(DrmConnector *conn) : m_connector(conn) , m_commitThread(std::make_unique()) { + QObject::connect(m_commitThread.get(), &DrmCommitThread::commitFailed, [this]() { + m_pageflipPending = false; + if (m_output) { + m_output->frameFailed(); + } + }); } DrmPipeline::~DrmPipeline() @@ -421,13 +427,7 @@ void DrmPipeline::pageFlipped(std::chrono::nanoseconds timestamp) void DrmPipeline::setOutput(DrmOutput *output) { - if (m_output) { - QObject::disconnect(m_commitThread.get(), nullptr, m_output, nullptr); - } m_output = output; - if (output) { - QObject::connect(m_commitThread.get(), &DrmCommitThread::commitFailed, output, &DrmAbstractOutput::frameFailed); - } } DrmOutput *DrmPipeline::output() const