From 528106b2ffa39b8f0a2bc4d1b4e23419eaf454ca Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Mon, 31 Aug 2009 10:44:26 +1000 Subject: Remove QGLShader from its QGLShaderProgram when it is destroyed Reviewed-by: Samuel --- src/opengl/qglshaderprogram.cpp | 24 ++++++++++++++++++++---- src/opengl/qglshaderprogram.h | 3 +++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index b07fb3b..6e3ea88 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -701,6 +701,7 @@ public: , linked(false) , inited(false) , hasPartialShaders(false) + , removingShaders(false) , vertexShader(0) , fragmentShader(0) { @@ -716,6 +717,7 @@ public: bool linked; bool inited; bool hasPartialShaders; + bool removingShaders; QString log; QList shaders; QList anonShaders; @@ -813,6 +815,7 @@ bool QGLShaderProgram::addShader(QGLShader *shader) } d->linked = false; // Program needs to be relinked. d->shaders.append(shader); + connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed())); return true; } else { return false; @@ -917,12 +920,14 @@ bool QGLShaderProgram::addShaderFromFile */ void QGLShaderProgram::removeShader(QGLShader *shader) { - if (d->program && shader && shader->d->shader) { + if (d->program && shader && shader->d->shader) glDetachShader(d->program, shader->d->shader); - d->linked = false; // Program needs to be relinked. + d->linked = false; // Program needs to be relinked. + if (shader) { + d->shaders.removeAll(shader); + d->anonShaders.removeAll(shader); + disconnect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed())); } - d->shaders.removeAll(shader); - d->anonShaders.removeAll(shader); } /*! @@ -946,6 +951,7 @@ QList QGLShaderProgram::shaders() const */ void QGLShaderProgram::removeAllShaders() { + d->removingShaders = true; foreach (QGLShader *shader, d->shaders) { if (d->program && shader && shader->d->shader) glDetachShader(d->program, shader->d->shader); @@ -957,6 +963,7 @@ void QGLShaderProgram::removeAllShaders() d->shaders.clear(); d->anonShaders.clear(); d->linked = false; // Program needs to be relinked. + d->removingShaders = false; } #if defined(QT_OPENGL_ES_2) @@ -2977,6 +2984,15 @@ bool QGLShaderProgram::hasShaderPrograms(const QGLContext *context) #endif } +/*! + \internal +*/ +void QGLShaderProgram::shaderDestroyed() +{ + QGLShader *shader = qobject_cast(sender()); + if (shader && !d->removingShaders) + removeShader(shader); +} #endif diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h index d747679..8d6efab 100644 --- a/src/opengl/qglshaderprogram.h +++ b/src/opengl/qglshaderprogram.h @@ -282,6 +282,9 @@ public: static bool hasShaderPrograms(const QGLContext *context = 0); +private Q_SLOTS: + void shaderDestroyed(); + private: QGLShaderProgramPrivate *d; -- cgit v0.12