From 26ffdc559c78fa5f9b9f5a05f7d6d9b778e711c8 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Wed, 30 Jan 2019 13:48:51 +0100 Subject: Android: Fix memory leak of GL resources DeferredDelete events have implicitly higher priority, which makes this event to be handled before MetaCall events. See QSGSoftwareRenderThread::sync(): ... QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); Where it processes deferred deletes and no meta calls will be delivered even if they were requested before the deferred delete. Task-number: QTBUG-67280 Change-Id: Iba23550d2cffb1cea1b4c2fe4c903078d9f2f046 Reviewed-by: Oliver Wolff Reviewed-by: Joerg Bornemann --- .../android/src/common/qandroidvideooutput.cpp | 21 ++++++++++++++------- .../android/src/common/qandroidvideooutput.h | 4 +++- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'src/plugins/android') diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp index b425b9d89..a8351aadb 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.cpp +++ b/src/plugins/android/src/common/qandroidvideooutput.cpp @@ -82,6 +82,10 @@ void OpenGLResourcesDeleter::deleteShaderProgramHelper(void *prog) delete reinterpret_cast(prog); } +void OpenGLResourcesDeleter::deleteThisHelper() +{ + delete this; +} class AndroidTextureVideoBuffer : public QAbstractVideoBuffer { @@ -170,6 +174,7 @@ QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QObject *parent) , m_externalTex(0) , m_fbo(0) , m_program(0) + , m_glDeleter(0) , m_surfaceTextureCanAttachToContext(QtAndroidPrivate::androidSdkVersion() >= 16) { @@ -179,11 +184,11 @@ QAndroidTextureVideoOutput::~QAndroidTextureVideoOutput() { clearSurfaceTexture(); - if (!m_glDeleter.isNull()) { // Make sure all of these are deleted on the render thread. + if (m_glDeleter) { // Make sure all of these are deleted on the render thread. m_glDeleter->deleteFbo(m_fbo); m_glDeleter->deleteShaderProgram(m_program); m_glDeleter->deleteTexture(m_externalTex); - m_glDeleter->deleteLater(); + m_glDeleter->deleteThis(); } } @@ -231,7 +236,8 @@ bool QAndroidTextureVideoOutput::initSurfaceTexture() // for the GL render thread to call us back to do it. if (QOpenGLContext::currentContext()) { glGenTextures(1, &m_externalTex); - m_glDeleter.reset(new OpenGLResourcesDeleter); + if (!m_glDeleter) + m_glDeleter = new OpenGLResourcesDeleter; } else if (!m_externalTex) { return false; } @@ -246,7 +252,7 @@ bool QAndroidTextureVideoOutput::initSurfaceTexture() } else { delete m_surfaceTexture; m_surfaceTexture = 0; - if (!m_glDeleter.isNull()) + if (m_glDeleter) m_glDeleter->deleteTexture(m_externalTex); m_externalTex = 0; } @@ -267,7 +273,7 @@ void QAndroidTextureVideoOutput::clearSurfaceTexture() // only if detachFromGLContext() called (API level >= 16), so we'll do it manually, // on the render thread. if (m_surfaceTextureCanAttachToContext) { - if (!m_glDeleter.isNull()) + if (m_glDeleter) m_glDeleter->deleteTexture(m_externalTex); m_externalTex = 0; } @@ -401,7 +407,7 @@ void QAndroidTextureVideoOutput::createGLResources() Q_ASSERT(QOpenGLContext::currentContext() != NULL); if (!m_glDeleter) - m_glDeleter.reset(new OpenGLResourcesDeleter); + m_glDeleter = new OpenGLResourcesDeleter; if (m_surfaceTextureCanAttachToContext && !m_externalTex) { m_surfaceTexture->detachFromGLContext(); @@ -451,7 +457,8 @@ void QAndroidTextureVideoOutput::customEvent(QEvent *e) // This is running in the render thread (OpenGL enabled) if (!m_surfaceTextureCanAttachToContext && !m_externalTex) { glGenTextures(1, &m_externalTex); - m_glDeleter.reset(new OpenGLResourcesDeleter); // We'll use this to cleanup GL resources in the correct thread + if (!m_glDeleter) // We'll use this to cleanup GL resources in the correct thread + m_glDeleter = new OpenGLResourcesDeleter; emit readyChanged(true); } } diff --git a/src/plugins/android/src/common/qandroidvideooutput.h b/src/plugins/android/src/common/qandroidvideooutput.h index 62a936881..2a35247e9 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.h +++ b/src/plugins/android/src/common/qandroidvideooutput.h @@ -81,11 +81,13 @@ public: void deleteTexture(quint32 id) { QMetaObject::invokeMethod(this, "deleteTextureHelper", Qt::AutoConnection, Q_ARG(quint32, id)); } void deleteFbo(QOpenGLFramebufferObject *fbo) { QMetaObject::invokeMethod(this, "deleteFboHelper", Qt::AutoConnection, Q_ARG(void *, fbo)); } void deleteShaderProgram(QOpenGLShaderProgram *prog) { QMetaObject::invokeMethod(this, "deleteShaderProgramHelper", Qt::AutoConnection, Q_ARG(void *, prog)); } + void deleteThis() { QMetaObject::invokeMethod(this, "deleteThisHelper"); } private: Q_INVOKABLE void deleteTextureHelper(quint32 id); Q_INVOKABLE void deleteFboHelper(void *fbo); Q_INVOKABLE void deleteShaderProgramHelper(void *prog); + Q_INVOKABLE void deleteThisHelper(); }; class QAndroidTextureVideoOutput : public QAndroidVideoOutput @@ -126,7 +128,7 @@ private: quint32 m_externalTex; QOpenGLFramebufferObject *m_fbo; QOpenGLShaderProgram *m_program; - QScopedPointer m_glDeleter; + OpenGLResourcesDeleter *m_glDeleter; bool m_surfaceTextureCanAttachToContext; -- cgit v1.2.3