From 207fb45ce7bac66ab53a0770d2bfb50d8d1997d8 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 25 Oct 2011 15:58:49 +0200 Subject: Fix possible crash in glyph cache when deleting and creating contexts The freeResource(), used in the glyph cache as a notifier of when the owner context of the cache disappears, is never called if the context is in a group with other contexts that share its resources. This implements a second notifier function instead which can be used to invalidate the glyph cache when its context is destroyed. Task-number: QTBUG-22324 Reviewed-by: Samuel --- src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h | 4 ++++ src/opengl/qgl.cpp | 11 ++++++++++- src/opengl/qgl_p.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h index 83ca06d..1a8bb0b 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h @@ -144,6 +144,10 @@ public: void clear(); + void contextDeleted(const QGLContext *context) { + if (ctx == context) + ctx = 0; + } void freeResource(void *) { ctx = 0; } private: diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 423fa08..eaaf9a8 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -5722,6 +5722,11 @@ void QGLContextGroupResourceBase::cleanup(const QGLContext *ctx) } } +void QGLContextGroupResourceBase::contextDeleted(const QGLContext *ctx) +{ + Q_UNUSED(ctx); +} + void QGLContextGroupResourceBase::cleanup(const QGLContext *ctx, void *value) { #ifdef QT_GL_CONTEXT_RESOURCE_DEBUG @@ -5737,12 +5742,16 @@ void QGLContextGroupResourceBase::cleanup(const QGLContext *ctx, void *value) void QGLContextGroup::cleanupResources(const QGLContext *context) { + // Notify all resources that a context has been deleted + QHash::ConstIterator it; + for (it = m_resources.begin(); it != m_resources.end(); ++it) + it.key()->contextDeleted(context); + // If there are still shares, then no cleanup to be done yet. if (m_shares.size() > 1) return; // Iterate over all resources and free each in turn. - QHash::ConstIterator it; for (it = m_resources.begin(); it != m_resources.end(); ++it) it.key()->cleanup(context, it.value()); } diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index de349a7..b6fc96a 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -725,6 +725,7 @@ public: void cleanup(const QGLContext *context); void cleanup(const QGLContext *context, void *value); virtual void freeResource(void *value) = 0; + virtual void contextDeleted(const QGLContext *ctx); protected: QList m_groups; -- cgit v0.12