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 void releaseGbm() {}
quint32 bufferId() const {
return m_bufferId;
}

View file

@ -45,15 +45,21 @@ GbmBuffer::GbmBuffer(gbm_bo *buffer, KWaylandServer::BufferInterface *bufferInte
}
GbmBuffer::~GbmBuffer()
{
releaseBuffer();
}
void GbmBuffer::releaseBuffer()
{
if (m_bufferInterface) {
clearBufferInterface();
}
if (m_surface) {
if (m_surface && m_bo) {
m_surface->releaseBuffer(m_bo);
} else if (m_bo) {
gbm_bo_destroy(m_bo);
}
m_bo = nullptr;
}
void GbmBuffer::clearBufferInterface()
@ -86,6 +92,11 @@ DrmGbmBuffer::~DrmGbmBuffer()
}
}
void DrmGbmBuffer::releaseGbm()
{
releaseBuffer();
}
void DrmGbmBuffer::initialize()
{
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;
}
void releaseBuffer();
protected:
QSharedPointer<GbmSurface> m_surface;
gbm_bo *m_bo = nullptr;
@ -61,6 +63,8 @@ public:
}
}
void releaseGbm() override;
bool hasBo() const {
return m_bo != nullptr;
}

View file

@ -75,6 +75,24 @@ void DrmOutput::teardown()
//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()
{
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.
void teardown();
void releaseGbm();
bool showCursor(DrmDumbBuffer *buffer);
bool showCursor();
bool hideCursor();

View file

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