diff options
author | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-09-09 06:23:54 (GMT) |
---|---|---|
committer | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-09-09 06:23:54 (GMT) |
commit | 6eb6920d134ee6a0cc0f27d63d65003a3d9c1fee (patch) | |
tree | e4abaa818134c282dc37e62a241d9b7b89b5fb0b /src/opengl/qgl.cpp | |
parent | 39bcbc8df52eb5df5f7e39dc4265c8a77d3881be (diff) | |
download | Qt-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.cpp | 29 |
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 |