summaryrefslogtreecommitdiffstats
path: root/src/opengl/gl2paintengineex
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/gl2paintengineex')
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp80
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h4
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache.cpp12
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp1
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp47
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h31
6 files changed, 56 insertions, 119 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index 0ba324d..888bac9 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -48,65 +48,54 @@
QT_BEGIN_NAMESPACE
+class QGLSharedShaderResource : public QGLContextResource
+{
+public:
+ ~QGLSharedShaderResource() {
+ qDebug() << "~QGLSharedShaderResource cleaned up" << hex << this;
+ }
-// Handling the cleanup and creation of the thread-local shader cache
-// differes from other QGLContextResources. The cache needs to be
-// cleaned up when the thread exits, or when its group context is
-// destroyed.
-
-static void qt_gl_free_shared_shaders(void *value);
+ void freeResource(void *value)
+ {
+ qDebug() << "Context destroyed:";
+ qDebug() << " -> deleting shader cache" << hex << value;
+ delete reinterpret_cast<QGLEngineSharedShaders *>(value);
+ }
+};
class QGLThreadLocalShaders
{
public:
- QGLThreadLocalShaders(const QGLContext *context, QGLEngineSharedShaders *shaders)
- : m_context(context), m_shaders(shaders)
- {
- m_resource = new QGLContextResource(qt_gl_free_shared_shaders);
- m_resource->insert(context, this);
+ QGLEngineSharedShaders *shadersForContext(const QGLContext *context) {
+ QGLEngineSharedShaders *shaders = reinterpret_cast<QGLEngineSharedShaders *>(m_resource.value(context));
+ if (!shaders) {
+ QGLShareContextScope scope(context);
+ shaders = new QGLEngineSharedShaders(context);
+ qDebug() << " -> new shader cache for context:" << hex << context << "cache:" << shaders;
+ m_resource.insert(context, shaders);
+ }
+ return shaders;
}
+
~QGLThreadLocalShaders() {
qDebug() << "Thread exit:";
qDebug() << "~QGLThreadLocalShaders() for thread:" << hex << QThread::currentThread();
- qDebug() << " -> deleting shader cache:" << hex << m_shaders;
- delete m_shaders;
- // remove the resource from the group's resource list, so that
- // the cleanup function is not called when the context is destroyed
- m_resource->remove(m_context);
- delete m_resource;
}
- const QGLContext *m_context;
- QGLEngineSharedShaders *m_shaders;
- QGLContextResource *m_resource;
-};
-static void qt_gl_free_shared_shaders(void *value)
-{
- QGLThreadLocalShaders *local = reinterpret_cast<QGLThreadLocalShaders *>(value);
- qDebug() << "Context destroyed:";
- qDebug() << " -> deleting shader cache" << hex << local->m_shaders;
- delete local->m_shaders;
- local->m_shaders = 0;
-
- // this function is called when the context group for the context
- // we have ref'ed is deleted - that means our context ptr is no
- // longer valid
- local->m_context = 0;
-}
+private:
+ QGLSharedShaderResource m_resource;
+};
class QGLShaderStorage
{
public:
QGLEngineSharedShaders *shadersForThread(const QGLContext *context) {
- QGLThreadLocalShaders *shaders = m_storage.localData();
+ QGLThreadLocalShaders *&shaders = m_storage.localData();
if (!shaders) {
- 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);
+ qDebug() << "New thread storage for:" << hex << QThread::currentThread();
+ shaders = new QGLThreadLocalShaders;
}
- return shaders->m_shaders;
+ return shaders->shadersForContext(context);
}
private:
@@ -282,15 +271,6 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
QGLEngineSharedShaders::~QGLEngineSharedShaders()
{
- cleanupBeforeDestruction();
-}
-
-
-// This might be called both when a thread exits, or when the a
-// context is destroyed
-
-void QGLEngineSharedShaders::cleanupBeforeDestruction()
-{
qDeleteAll(shaders);
shaders.clear();
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index 8d3697b..e5ababf 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -364,10 +364,6 @@ public:
// full.
void cleanupCustomStage(QGLCustomShaderStage* stage);
- // this is needed so that threads can get a foot in and have a chance to
- // clean up the shaders they've created before the thread exits
- void cleanupBeforeDestruction();
-
private:
QGLSharedResourceGuard ctxGuard;
QGLShaderProgram *blitShaderProg;
diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp
index a1495dd..a0a3f8f 100644
--- a/src/opengl/gl2paintengineex/qglgradientcache.cpp
+++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp
@@ -46,12 +46,16 @@
QT_BEGIN_NAMESPACE
-static void QGL2GradientCache_free(void *ptr)
+class QGLGradientCacheResource : public QGLContextResource
{
- delete reinterpret_cast<QGL2GradientCache *>(ptr);
-}
+public:
+ void freeResource(void *value)
+ {
+ delete reinterpret_cast<QGL2GradientCache *>(value);
+ }
+};
-Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_gradient_caches, (QGL2GradientCache_free))
+Q_GLOBAL_STATIC(QGLGradientCacheResource, qt_gradient_caches)
QGL2GradientCache *QGL2GradientCache::cacheForContext(const QGLContext *context)
{
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 634b315..260e797 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1457,6 +1457,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
(QGLTextureGlyphCache *) staticTextItem->fontEngine->glyphCache(ctx, glyphType, QTransform());
if (!cache || cache->cacheType() != glyphType) {
cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform());
+ cache->insert(ctx, cache);
staticTextItem->fontEngine->setGlyphCache(ctx, cache);
}
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
index faf4563..001a09e 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
@@ -54,45 +54,10 @@ extern Q_GUI_EXPORT bool qt_cleartype_enabled;
QGLTextureGlyphCache::QGLTextureGlyphCache(const QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix)
: QImageTextureGlyphCache(type, matrix)
- , ctx(0)
- , pex(0)
+ , ctx(context)
, m_width(0)
, m_height(0)
{
- if (context != 0)
- setContext(context);
-}
-
-QGLTextureGlyphCache::~QGLTextureGlyphCache()
-{
- cleanUpContext();
-}
-
-void QGLTextureGlyphCache::cleanUpContext()
-{
- if (ctx) {
- QGLShareContextScope scope(ctx);
-
- if (!ctx->d_ptr->workaround_brokenFBOReadBack && pex != 0)
- glDeleteFramebuffers(1, &m_fbo);
-
- if (m_width || m_height) {
- glDeleteTextures(1, &m_texture);
- m_width = 0;
- m_height = 0;
- m_h = 0;
- }
-
- ctx = 0;
- }
-}
-
-void QGLTextureGlyphCache::setContext(const QGLContext *context)
-{
- cleanUpContext();
-
- ctx = context;
-
// broken FBO readback is a bug in the SGX 1.3 and 1.4 drivers for the N900 where
// copying between FBO's is broken if the texture is either GL_ALPHA or POT. The
// workaround is to use a system-memory copy of the glyph cache for this device.
@@ -101,8 +66,12 @@ void QGLTextureGlyphCache::setContext(const QGLContext *context)
if (!ctx->d_ptr->workaround_brokenFBOReadBack && pex != 0)
glGenFramebuffers(1, &m_fbo);
- connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(contextDestroyed(const QGLContext*)));
+ fprintf(stderr, "## QGLTextureGlyphCache(): ctx: %p - this: %p\n", ctx, this);
+}
+
+QGLTextureGlyphCache::~QGLTextureGlyphCache()
+{
+ fprintf(stderr, "## ~QGLTextureGlyphCache(): context: %p - this: %p\n", ctx, this);
}
void QGLTextureGlyphCache::createTextureData(int width, int height)
@@ -161,7 +130,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
GLuint oldTexture = m_texture;
createTextureData(width, height);
-
+
if (pex == 0 || ctx->d_ptr->workaround_brokenFBOReadBack) {
QImageTextureGlyphCache::resizeTextureData(width, height);
Q_ASSERT(image().depth() == 8);
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
index d291ac3..710a12d 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
@@ -62,9 +62,8 @@ QT_BEGIN_NAMESPACE
class QGL2PaintEngineExPrivate;
-class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QImageTextureGlyphCache
+class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QGLContextResource, public QImageTextureGlyphCache
{
- Q_OBJECT
public:
QGLTextureGlyphCache(const QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix);
~QGLTextureGlyphCache();
@@ -82,33 +81,21 @@ public:
inline void setPaintEnginePrivate(QGL2PaintEngineExPrivate *p) { pex = p; }
- void setContext(const QGLContext *context);
inline const QGLContext *context() const
{
return ctx;
}
+ void freeResource(void *) {
+ qDebug() << "QGLTextureGlyphCache::freeResource():" << this << "ctx:" << ctx;
+ // At this point, the context group is made current, so it's safe to
+ // release resources without a makeCurrent() call
+ if (!ctx->d_ptr->workaround_brokenFBOReadBack)
+ glDeleteFramebuffers(1, &m_fbo);
-public Q_SLOTS:
- void contextDestroyed(const QGLContext *context) {
- if (context == ctx) {
- const QGLContext *nextCtx = qt_gl_transfer_context(ctx);
- if (!nextCtx) {
- // the context may not be current, so we cannot directly
- // destroy the fbo and texture here, but since the context
- // is about to be destroyed, the GL server will do the
- // clean up for us anyway
- m_fbo = 0;
- m_texture = 0;
- ctx = 0;
- } else {
- // since the context holding the texture is shared, and
- // about to be destroyed, we have to transfer ownership
- // of the texture to one of the share contexts
- ctx = const_cast<QGLContext *>(nextCtx);
- }
- }
+ if (m_width || m_height)
+ glDeleteTextures(1, &m_texture);
}
private: