From d4423186b98ff2c1015d3811fe57eff3b599c039 Mon Sep 17 00:00:00 2001 From: Roman Gilg Date: Fri, 14 Jul 2017 13:42:52 +0200 Subject: [PATCH] [platforms/drm] Delete buffer on all errors in present Summary: When returning early in DrmOutput::present() because of some error KWin didn't delete the proposed buffer, therefore not releasing the surface lock of the GBM buffer to the EGL surface. This patch makes sure that on any error in present we cleanup the proposed DrmBuffer. Reviewers: #kwin Subscribers: #kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D6660 --- plugins/platforms/drm/drm_backend.cpp | 9 +++++++++ plugins/platforms/drm/drm_output.cpp | 9 ++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/plugins/platforms/drm/drm_backend.cpp b/plugins/platforms/drm/drm_backend.cpp index 3d2bef32aa..30141ab6ef 100644 --- a/plugins/platforms/drm/drm_backend.cpp +++ b/plugins/platforms/drm/drm_backend.cpp @@ -561,11 +561,20 @@ DrmOutput *DrmBackend::findOutput(const QByteArray &uuid) void DrmBackend::present(DrmBuffer *buffer, DrmOutput *output) { + if (!buffer || buffer->bufferId() == 0) { + if (m_deleteBufferAfterPageFlip) { + delete buffer; + } + return; + } + if (output->present(buffer)) { m_pageFlipsPending++; if (m_pageFlipsPending == 1 && Compositor::self()) { Compositor::self()->aboutToSwapBuffers(); } + } else if (m_deleteBufferAfterPageFlip) { + delete buffer; } } diff --git a/plugins/platforms/drm/drm_output.cpp b/plugins/platforms/drm/drm_output.cpp index 334af43636..d0cd2d3200 100644 --- a/plugins/platforms/drm/drm_output.cpp +++ b/plugins/platforms/drm/drm_output.cpp @@ -765,9 +765,6 @@ void DrmOutput::pageFlipped() bool DrmOutput::present(DrmBuffer *buffer) { - if (!buffer || buffer->bufferId() == 0) { - return false; - } if (m_backend->atomicModeSetting()) { return presentAtomically(buffer); } else { @@ -816,14 +813,13 @@ bool DrmOutput::presentAtomically(DrmBuffer *buffer) if (!doAtomicCommit(AtomicCommitMode::Test)) { //TODO: When we use planes for layered rendering, fallback to renderer instead. Also for direct scanout? + //TODO: Probably should undo setNext and reset the flip list qCDebug(KWIN_DRM) << "Atomic test commit failed. Aborting present."; - if (this->m_backend->deleteBufferAfterPageFlip()) { - delete buffer; - } return false; } if (!doAtomicCommit(AtomicCommitMode::Real)) { qCDebug(KWIN_DRM) << "Atomic commit failed. This should have never happened! Aborting present."; + //TODO: Probably should undo setNext and reset the flip list return false; } m_pageFlipPending = true; @@ -856,7 +852,6 @@ bool DrmOutput::presentLegacy(DrmBuffer *buffer) } else { errno_save = errno; qCWarning(KWIN_DRM) << "Page flip failed:" << strerror(errno); - delete buffer; } return ok; }