From f775e13c6ee9a84028473c401b15ec5703e2fbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 24 Apr 2015 10:23:06 +0200 Subject: [PATCH] Improve tracking of DrmBuffers in DrmBackend We need to prevent double deletions from the gbm callback. Therefore we track all buffers in DrmBackend and pass the DrmBackend as user data. --- drm_backend.cpp | 26 +++++++++++++++++++++----- drm_backend.h | 8 ++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/drm_backend.cpp b/drm_backend.cpp index c874f82c0d..b6f6c6f0d1 100644 --- a/drm_backend.cpp +++ b/drm_backend.cpp @@ -481,16 +481,25 @@ OpenGLBackend *DrmBackend::createOpenGLBackend() DrmBuffer *DrmBackend::createBuffer(const QSize &size) { - return new DrmBuffer(this, size); + DrmBuffer *b = new DrmBuffer(this, size); + m_buffers << b; + return b; } DrmBuffer *DrmBackend::createBuffer(gbm_surface *surface) { #if HAVE_GBM - return new DrmBuffer(this, surface); + DrmBuffer *b = new DrmBuffer(this, surface); + m_buffers << b; + return b; #endif } +void DrmBackend::bufferDestroyed(DrmBuffer *b) +{ + m_buffers.removeAll(b); +} + DrmOutput::DrmOutput(DrmBackend *backend) : m_backend(backend) { @@ -633,8 +642,14 @@ DrmBuffer::DrmBuffer(DrmBackend *backend, const QSize &size) #if HAVE_GBM static void gbmCallback(gbm_bo *bo, void *data) { - Q_UNUSED(bo); - delete reinterpret_cast(data); + DrmBackend *backend = reinterpret_cast(data); + const auto &buffers = backend->buffers(); + for (auto buffer: buffers) { + if (buffer->gbm() == bo) { + delete buffer; + return; + } + } } #endif @@ -653,12 +668,13 @@ DrmBuffer::DrmBuffer(DrmBackend *backend, gbm_surface *surface) if (drmModeAddFB(m_backend->fd(), m_size.width(), m_size.height(), 24, 32, m_stride, gbm_bo_get_handle(m_bo).u32, &m_bufferId) != 0) { qWarning(KWIN_CORE) << "drmModeAddFB failed"; } - gbm_bo_set_user_data(m_bo, this, gbmCallback); + gbm_bo_set_user_data(m_bo, m_backend, gbmCallback); #endif } DrmBuffer::~DrmBuffer() { + m_backend->bufferDestroyed(this); delete m_image; if (m_memory) { munmap(m_memory, m_bufferSize); diff --git a/drm_backend.h b/drm_backend.h index eb4ddcfc30..2da5268274 100644 --- a/drm_backend.h +++ b/drm_backend.h @@ -62,6 +62,10 @@ public: QVector outputs() const { return m_outputs; } + QVector buffers() const { + return m_buffers; + } + void bufferDestroyed(DrmBuffer *b); Q_SIGNALS: void screensQueried(); @@ -92,6 +96,7 @@ private: int m_cursorIndex = 0; int m_pageFlipsPending = 0; bool m_active = false; + QVector m_buffers; }; class DrmOutput @@ -153,6 +158,9 @@ public: quint32 stride() const { return m_stride; } + gbm_bo *gbm() const { + return m_bo; + } void releaseGbm(); private: