summaryrefslogtreecommitdiffstats
path: root/src/opengl/qgl.cpp
diff options
context:
space:
mode:
authorRhys Weatherley <rhys.weatherley@nokia.com>2009-09-09 06:23:54 (GMT)
committerRhys Weatherley <rhys.weatherley@nokia.com>2009-09-09 06:23:54 (GMT)
commit6eb6920d134ee6a0cc0f27d63d65003a3d9c1fee (patch)
treee4abaa818134c282dc37e62a241d9b7b89b5fb0b /src/opengl/qgl.cpp
parent39bcbc8df52eb5df5f7e39dc4265c8a77d3881be (diff)
downloadQt-6eb6920d134ee6a0cc0f27d63d65003a3d9c1fee.zip
Qt-6eb6920d134ee6a0cc0f27d63d65003a3d9c1fee.tar.gz
Qt-6eb6920d134ee6a0cc0f27d63d65003a3d9c1fee.tar.bz2
Clean up shader programs properly
QGLShader and QGLShaderProgram used to delete the GL object id in the wrong context. But fixing this means we must keep track of when contexts are destroyed so that we don't try to access a context from a shader if it goes away. We also need to transfer ownership from one context to another when they are shared. This change introduces QGLSharedResourceGuard, which keeps track of a context and a GL object identifier. When the context goes away, ownership is passed to a shared context. When there are no more shared contexts, the identifier automatically zeroes. Reviewed-by: trustme
Diffstat (limited to 'src/opengl/qgl.cpp')
-rw-r--r--src/opengl/qgl.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index a0b2d3a..9618e5c 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1360,6 +1360,9 @@ bool operator!=(const QGLFormat& a, const QGLFormat& b)
*****************************************************************************/
QGLContextPrivate::~QGLContextPrivate()
{
+ if (!reference->deref())
+ delete reference;
+
if (!group->m_refs.deref()) {
Q_ASSERT(group->context() == q_ptr);
delete group;
@@ -5007,4 +5010,30 @@ void QGLContextResource::removeOne(const QGLContext *key)
m_resources.erase(it);
}
+QGLContextReference::QGLContextReference(const QGLContext *ctx)
+ : m_ref(1), m_ctx(ctx)
+{
+ connect(QGLSignalProxy::instance(),
+ SIGNAL(aboutToDestroyContext(const QGLContext *)),
+ this, SLOT(aboutToDestroyContext(const QGLContext *)));
+}
+
+void QGLContextReference::aboutToDestroyContext(const QGLContext *ctx)
+{
+ // Bail out if our context is not being destroyed.
+ if (ctx != m_ctx || !m_ctx)
+ return;
+
+ // Find some other context that this one is shared with to take over.
+ QList<const QGLContext *> shares = qgl_share_reg()->shares(m_ctx);
+ shares.removeAll(m_ctx);
+ if (!shares.isEmpty()) {
+ m_ctx = shares[0];
+ return;
+ }
+
+ // No more contexts sharing with this one, so the reference is now invalid.
+ m_ctx = 0;
+}
+
QT_END_NAMESPACE