platforms/drm: release gbm buffers before eglDestroySurface

BUG: 436500
This commit is contained in:
Xaver Hugl 2021-05-02 22:38:36 +02:00 committed by Aleix Pol Gonzalez
parent 49fcadb185
commit 5bd938f0f0
6 changed files with 41 additions and 3 deletions

View file

@ -25,6 +25,8 @@ public:
virtual bool needsModeChange(DrmBuffer *b) const {Q_UNUSED(b) return false;} virtual bool needsModeChange(DrmBuffer *b) const {Q_UNUSED(b) return false;}
virtual void releaseGbm() {}
quint32 bufferId() const { quint32 bufferId() const {
return m_bufferId; return m_bufferId;
} }

View file

@ -45,15 +45,21 @@ GbmBuffer::GbmBuffer(gbm_bo *buffer, KWaylandServer::BufferInterface *bufferInte
} }
GbmBuffer::~GbmBuffer() GbmBuffer::~GbmBuffer()
{
releaseBuffer();
}
void GbmBuffer::releaseBuffer()
{ {
if (m_bufferInterface) { if (m_bufferInterface) {
clearBufferInterface(); clearBufferInterface();
} }
if (m_surface) { if (m_surface && m_bo) {
m_surface->releaseBuffer(m_bo); m_surface->releaseBuffer(m_bo);
} else if (m_bo) { } else if (m_bo) {
gbm_bo_destroy(m_bo); gbm_bo_destroy(m_bo);
} }
m_bo = nullptr;
} }
void GbmBuffer::clearBufferInterface() void GbmBuffer::clearBufferInterface()
@ -86,6 +92,11 @@ DrmGbmBuffer::~DrmGbmBuffer()
} }
} }
void DrmGbmBuffer::releaseGbm()
{
releaseBuffer();
}
void DrmGbmBuffer::initialize() void DrmGbmBuffer::initialize()
{ {
m_size = QSize(gbm_bo_get_width(m_bo), gbm_bo_get_height(m_bo)); m_size = QSize(gbm_bo_get_width(m_bo), gbm_bo_get_height(m_bo));

View file

@ -38,6 +38,8 @@ public:
return m_bo; return m_bo;
} }
void releaseBuffer();
protected: protected:
QSharedPointer<GbmSurface> m_surface; QSharedPointer<GbmSurface> m_surface;
gbm_bo *m_bo = nullptr; gbm_bo *m_bo = nullptr;
@ -61,6 +63,8 @@ public:
} }
} }
void releaseGbm() override;
bool hasBo() const { bool hasBo() const {
return m_bo != nullptr; return m_bo != nullptr;
} }

View file

@ -75,6 +75,24 @@ void DrmOutput::teardown()
//this is needed so that the pageflipcallback handle isn't deleted //this is needed so that the pageflipcallback handle isn't deleted
} }
void DrmOutput::releaseGbm()
{
if (auto buffer = m_crtc->current()) {
buffer->releaseGbm();
}
if (auto buffer = m_crtc->next()) {
buffer->releaseGbm();
}
if (m_primaryPlane) {
if (auto buffer = m_primaryPlane->current()) {
buffer->releaseGbm();
}
if (auto buffer = m_primaryPlane->next()) {
buffer->releaseGbm();
}
}
}
bool DrmOutput::hideCursor() bool DrmOutput::hideCursor()
{ {
if (RenderLoopPrivate::get(m_renderLoop)->presentMode == RenderLoopPrivate::SyncMode::Adaptive if (RenderLoopPrivate::get(m_renderLoop)->presentMode == RenderLoopPrivate::SyncMode::Adaptive

View file

@ -44,6 +44,7 @@ public:
///queues deleting the output after a page flip has completed. ///queues deleting the output after a page flip has completed.
void teardown(); void teardown();
void releaseGbm();
bool showCursor(DrmDumbBuffer *buffer); bool showCursor(DrmDumbBuffer *buffer);
bool showCursor(); bool showCursor();
bool hideCursor(); bool hideCursor();

View file

@ -71,9 +71,9 @@ void EglGbmBackend::cleanupOutput(Output &output)
{ {
cleanupFramebuffer(output); cleanupFramebuffer(output);
output.buffer = nullptr;
output.secondaryBuffer = nullptr;
if (output.eglSurface != EGL_NO_SURFACE) { if (output.eglSurface != EGL_NO_SURFACE) {
// gbm buffers have to be released before destroying the egl surface
output.output->releaseGbm();
eglDestroySurface(eglDisplay(), output.eglSurface); eglDestroySurface(eglDisplay(), output.eglSurface);
} }
} }
@ -200,6 +200,8 @@ bool EglGbmBackend::resetOutput(Output &output, DrmOutput *drmOutput)
// destroy previous surface // destroy previous surface
if (output.eglSurface != EGL_NO_SURFACE) { if (output.eglSurface != EGL_NO_SURFACE) {
// gbm buffers have to be released before destroying the egl surface
output.output->releaseGbm();
eglDestroySurface(eglDisplay(), output.eglSurface); eglDestroySurface(eglDisplay(), output.eglSurface);
} }
output.eglSurface = eglSurface; output.eglSurface = eglSurface;