Fix potential crash when using text and more than 1 QQuickView
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
Mon, 6 Aug 2012 09:51:09 +0000 (11:51 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 28 Sep 2012 14:15:31 +0000 (16:15 +0200)
We need to use a resource guard for the FBO in case there is no
current context when the glyph cache is deleted.

This reverts commit b3264e2cb6a8fe87754aa1335ab9f8d5e3910c14 which
was implemented as a band-aid for this crash.

Change-Id: I5b3a09a3998da38836ea851cd0978d3ddadcd2cc
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp

index 07c17a5..d889b40 100644 (file)
 #include "qsgdefaultdistancefieldglyphcache_p.h"
 
 #include <QtGui/private/qdistancefield_p.h>
+#include <QtGui/private/qopenglcontext_p.h>
 #include <QtQuick/private/qsgdistancefieldutil_p.h>
 #include <qopenglfunctions.h>
 #include <qmath.h>
 
 QT_BEGIN_NAMESPACE
 
-
 QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font)
     : QSGDistanceFieldGlyphCache(man, c, font)
     , m_maxTextureSize(0)
     , m_maxTextureCount(3)
-    , m_fbo(0)
     , m_blitProgram(0)
+    , m_fboGuard(0)
 {
     m_blitVertexCoordinateArray[0] = -1.0f;
     m_blitVertexCoordinateArray[1] = -1.0f;
@@ -81,7 +81,10 @@ QSGDefaultDistanceFieldGlyphCache::~QSGDefaultDistanceFieldGlyphCache()
 {
     for (int i = 0; i < m_textures.count(); ++i)
         glDeleteTextures(1, &m_textures[i].texture);
-    ctx->functions()->glDeleteFramebuffers(1, &m_fbo);
+
+    if (m_fboGuard != 0)
+        m_fboGuard->free();
+
     delete m_blitProgram;
     delete m_areaAllocator;
 }
@@ -215,6 +218,11 @@ void QSGDefaultDistanceFieldGlyphCache::createTexture(TextureInfo *texInfo, int
 
 }
 
+static void freeFramebufferFunc(QOpenGLFunctions *funcs, GLuint id)
+{
+    funcs->glDeleteFramebuffers(1, &id);
+}
+
 void QSGDefaultDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int width, int height)
 {
     int oldWidth = texInfo->size.width();
@@ -242,9 +250,12 @@ void QSGDefaultDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int
 
     Q_ASSERT(m_blitProgram);
 
-    if (!m_fbo)
-        ctx->functions()->glGenFramebuffers(1, &m_fbo);
-    ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+    if (!m_fboGuard) {
+        GLuint fbo;
+        ctx->functions()->glGenFramebuffers(1, &fbo);
+        m_fboGuard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
+    }
+    ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_fboGuard->id());
 
     GLuint tmp_texture;
     glGenTextures(1, &tmp_texture);
index 2fc706c..decac2c 100644 (file)
@@ -50,6 +50,7 @@
 
 QT_BEGIN_NAMESPACE
 
+class QOpenGLSharedResourceGuard;
 class Q_QUICK_PRIVATE_EXPORT QSGDefaultDistanceFieldGlyphCache : public QSGDistanceFieldGlyphCache
 {
 public:
@@ -122,7 +123,6 @@ private:
 
     QList<TextureInfo> m_textures;
     QHash<glyph_t, TextureInfo *> m_glyphsTexture;
-    GLuint m_fbo;
     QSet<glyph_t> m_unusedGlyphs;
 
     QSGAreaAllocator *m_areaAllocator;
@@ -130,6 +130,8 @@ private:
     QOpenGLShaderProgram *m_blitProgram;
     GLfloat m_blitVertexCoordinateArray[8];
     GLfloat m_blitTextureCoordinateArray[8];
+
+    QOpenGLSharedResourceGuard *m_fboGuard;
 };
 
 QT_END_NAMESPACE
index 33de454..1d65cef 100644 (file)
@@ -2839,7 +2839,7 @@ void tst_qquicktextinput::cursorVisible()
     QCOMPARE(input.isCursorVisible(), true);
     QCOMPARE(spy.count(), 5);
 
-    QWindow alternateView;
+    QQuickView alternateView;
     alternateView.show();
     alternateView.requestActivateWindow();
     QTest::qWaitForWindowActive(&alternateView);