From e03363dfd1aeddd085c4c86d9a1964da769d7980 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 6 Aug 2012 11:51:09 +0200 Subject: Fix potential crash when using text and more than 1 QQuickView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../qsgdefaultdistancefieldglyphcache.cpp | 23 ++++++++++++++++------ .../qsgdefaultdistancefieldglyphcache_p.h | 4 +++- .../quick/qquicktextinput/tst_qquicktextinput.cpp | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp index 07c17a5791..d889b4028b 100644 --- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp @@ -42,19 +42,19 @@ #include "qsgdefaultdistancefieldglyphcache_p.h" #include +#include #include #include #include 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); diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h index 2fc706cff5..decac2cc0f 100644 --- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h +++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE +class QOpenGLSharedResourceGuard; class Q_QUICK_PRIVATE_EXPORT QSGDefaultDistanceFieldGlyphCache : public QSGDistanceFieldGlyphCache { public: @@ -122,7 +123,6 @@ private: QList m_textures; QHash m_glyphsTexture; - GLuint m_fbo; QSet 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 diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 33de454530..1d65cef99b 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -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); -- cgit v1.2.3