backends/drm: handle atomic commits failing correctly

If the pending pageflip flag is not reset, KWin will wait for a pageflip that
never comes
This commit is contained in:
Xaver Hugl 2023-07-28 15:36:34 +02:00
parent 5fae9a944e
commit 4610a916d3
2 changed files with 8 additions and 6 deletions

View file

@ -9,6 +9,7 @@
#include "drm_commit_thread.h" #include "drm_commit_thread.h"
#include "drm_commit.h" #include "drm_commit.h"
#include "drm_gpu.h" #include "drm_gpu.h"
#include "logging_p.h"
#include "utils/realtime.h" #include "utils/realtime.h"
namespace KWin namespace KWin
@ -42,6 +43,7 @@ DrmCommitThread::DrmCommitThread()
// the atomic commit takes ownership of the object // the atomic commit takes ownership of the object
m_commit.release(); m_commit.release();
} else { } else {
qCWarning(KWIN_DRM) << "atomic commit failed:" << strerror(errno);
m_droppedCommits.push_back(std::move(m_commit)); m_droppedCommits.push_back(std::move(m_commit));
QMetaObject::invokeMethod(this, &DrmCommitThread::commitFailed, Qt::ConnectionType::QueuedConnection); QMetaObject::invokeMethod(this, &DrmCommitThread::commitFailed, Qt::ConnectionType::QueuedConnection);
QMetaObject::invokeMethod(this, &DrmCommitThread::clearDroppedCommits, Qt::ConnectionType::QueuedConnection); QMetaObject::invokeMethod(this, &DrmCommitThread::clearDroppedCommits, Qt::ConnectionType::QueuedConnection);

View file

@ -41,6 +41,12 @@ DrmPipeline::DrmPipeline(DrmConnector *conn)
: m_connector(conn) : m_connector(conn)
, m_commitThread(std::make_unique<DrmCommitThread>()) , m_commitThread(std::make_unique<DrmCommitThread>())
{ {
QObject::connect(m_commitThread.get(), &DrmCommitThread::commitFailed, [this]() {
m_pageflipPending = false;
if (m_output) {
m_output->frameFailed();
}
});
} }
DrmPipeline::~DrmPipeline() DrmPipeline::~DrmPipeline()
@ -421,13 +427,7 @@ void DrmPipeline::pageFlipped(std::chrono::nanoseconds timestamp)
void DrmPipeline::setOutput(DrmOutput *output) void DrmPipeline::setOutput(DrmOutput *output)
{ {
if (m_output) {
QObject::disconnect(m_commitThread.get(), nullptr, m_output, nullptr);
}
m_output = output; m_output = output;
if (output) {
QObject::connect(m_commitThread.get(), &DrmCommitThread::commitFailed, output, &DrmAbstractOutput::frameFailed);
}
} }
DrmOutput *DrmPipeline::output() const DrmOutput *DrmPipeline::output() const