Commit 26ffdc55 authored by Val Doroshchuk's avatar Val Doroshchuk Committed by VaL Doroshchuk
Browse files

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: default avatarOliver Wolff <oliver.wolff@qt.io>
Reviewed-by: default avatarJoerg Bornemann <joerg.bornemann@qt.io>
parent 3c2e902e
No related merge requests found
Showing with 17 additions and 8 deletions
......@@ -82,6 +82,10 @@ void OpenGLResourcesDeleter::deleteShaderProgramHelper(void *prog)
delete reinterpret_cast<QOpenGLShaderProgram *>(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);
}
}
......
......@@ -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<OpenGLResourcesDeleter, QScopedPointerDeleteLater> m_glDeleter;
OpenGLResourcesDeleter *m_glDeleter;
bool m_surfaceTextureCanAttachToContext;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment