summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTrond Kjernåsen <trond.kjernasen@nokia.com>2010-04-09 15:52:38 (GMT)
committerTrond Kjernåsen <trond.kjernasen@nokia.com>2010-07-02 10:24:56 (GMT)
commit7e464e38009f2492a41e9972a75f868cf88d353a (patch)
treebb647b29481a696ebedad1d88ff64798fbe5524f /src
parentac2818bef95f1347e80be8ce847f2557339b76e0 (diff)
downloadQt-7e464e38009f2492a41e9972a75f868cf88d353a.zip
Qt-7e464e38009f2492a41e9972a75f868cf88d353a.tar.gz
Qt-7e464e38009f2492a41e9972a75f868cf88d353a.tar.bz2
Simplify how the QGLEngineSharedShaders object is cleaned up.
There are two things that needs to be done when cleaning up those objects: 1) if the context is destroyed before the specific thread exits, the shaders that is allocated within that context needs to be cleanup before the context is destroyed. 2) if the thread exits before the context is destroyed, the thread needs to clean up the shaders and then delete the QGLEngineSharedShaders object. We can't use a QGLContextResouce for that because a) we don't know if our context ptrs are valid, b) QGLContextResource doesn't remove themselves from the QGLContextGroups internal list when destroyed, so we might get a free() call *after* the resource had been destroyed. Use the contextDestroyed() signal from QGLSignalProxy() instead, which is cleaner and actually works..
Diffstat (limited to 'src')
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp67
1 files changed, 32 insertions, 35 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index 5330706..7d6d8a6 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -46,66 +46,61 @@
#include <QMetaEnum>
#endif
-
QT_BEGIN_NAMESPACE
-static void qt_shared_shaders_free(void *data)
+class QGLThreadLocalShaders : public QObject
{
- qDebug() << "qt_shared_shaders_free() for thread:" << hex << QThread::currentThread();
- delete reinterpret_cast<QGLEngineSharedShaders *>(data);
-}
-
-
-class QGLThreadLocalShaders {
+ Q_OBJECT
public:
- QGLThreadLocalShaders(QGLContextResource *resource) : m_resource(resource), m_shaders(0) {}
+ QGLThreadLocalShaders(const QGLContext *context, QGLEngineSharedShaders *shaders)
+ : m_context(context), m_shaders(shaders)
+ {
+ connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)),
+ SLOT(contextDestroyed(const QGLContext*)));
+ }
~QGLThreadLocalShaders() {
- if (m_shaders) {
- qDebug() << "~QGLThreadLocalShaders() for thread:" << hex << QThread::currentThread();
+ qDebug() << "~QGLThreadLocalShaders() for thread:" << hex << QThread::currentThread();
+ qDebug() << " -> deleting shader cache:" << hex << m_shaders;
+ delete m_shaders;
+ }
+ const QGLContext *m_context;
+ QGLEngineSharedShaders *m_shaders;
+
+private slots:
+ void contextDestroyed(const QGLContext * context) {
+ if (context == m_context) {
+ qDebug() << "QGLThreadLocalShaders::contextDestroyed():";
+ qDebug() << " -> cleaning up shader cache for thread:" << hex << QThread::currentThread();
+ qDebug() << " -> shaders:" << hex << m_shaders;
m_shaders->cleanupBeforeDestruction();
}
}
- QGLContextResource *m_resource;
- QGLEngineSharedShaders *m_shaders;
};
-class QGLThreadShaders
+class QGLShaderStorage
{
public:
- QGLContextResource *shadersForThread() {
+ QGLEngineSharedShaders *shadersForThread(const QGLContext *context) {
QGLThreadLocalShaders *shaders = m_storage.localData();
if (!shaders) {
- // The QGLContextResource is needed because the shaders need to be cleaned up
- // when the context is destroyed, not just when a thread exits
- QGLContextResource *resource = new QGLContextResource(qt_shared_shaders_free);
- qDebug() << "new local resource for thread:" << hex << QThread::currentThread() << resource;
- shaders = new QGLThreadLocalShaders(resource);
+ qDebug() << "new shader cache for thread:" << hex << QThread::currentThread();
+ QGLShareContextScope scope(context);
+ shaders = new QGLThreadLocalShaders(context, new QGLEngineSharedShaders(context));
+ qDebug() << " -> context:" << context;
m_storage.setLocalData(shaders);
}
- return shaders->m_resource;
- }
-
- void setShadersForThread(const QGLContext *context, QGLEngineSharedShaders *sharedShaders) {
- shadersForThread()->insert(context, sharedShaders);
- m_storage.localData()->m_shaders = sharedShaders;
- qDebug() << " -> context:" << context;
+ return shaders->m_shaders;
}
private:
QThreadStorage<QGLThreadLocalShaders *> m_storage;
};
-Q_GLOBAL_STATIC(QGLThreadShaders, qt_shared_shaders);
+Q_GLOBAL_STATIC(QGLShaderStorage, qt_shader_storage);
QGLEngineSharedShaders *QGLEngineSharedShaders::shadersForContext(const QGLContext *context)
{
- QGLEngineSharedShaders *shaders = reinterpret_cast<QGLEngineSharedShaders *>(qt_shared_shaders()->shadersForThread()->value(context));
- if (!shaders) {
- QGLShareContextScope scope(context);
- shaders = new QGLEngineSharedShaders(context);
- qt_shared_shaders()->setShadersForThread(context, shaders);
- }
- return shaders;
+ return reinterpret_cast<QGLEngineSharedShaders *>(qt_shader_storage()->shadersForThread(context));
}
const char* QGLEngineSharedShaders::qShaderSnippets[] = {
@@ -845,3 +840,5 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
}
QT_END_NAMESPACE
+
+#include "qglengineshadermanager.moc"