From b8c5be40ddd2a6a0c54d02293e2c27e990df1736 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 17 Nov 2011 14:25:24 +0100 Subject: [PATCH] Fixes crash in QSGDefaultDistanceFieldGlyphCache::resizeTexture() The blit shader was not valid anymore after deleting and recreating a QQuickCanvas. Task-number: QTBUG-22783 Change-Id: Id13578006b89859b862685b3a695eb8b59a48c56 Reviewed-by: Kent Hansen --- .../qsgdefaultdistancefieldglyphcache.cpp | 94 ++++------------------ .../qsgdefaultdistancefieldglyphcache_p.h | 61 +++++++++++++- 2 files changed, 73 insertions(+), 82 deletions(-) diff --git a/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp index 7a03cde..112fc5f 100644 --- a/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp +++ b/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp @@ -42,94 +42,26 @@ #include "qsgdefaultdistancefieldglyphcache_p.h" #include -#include -#include #include -class TextureBlitHelper -{ -public: - TextureBlitHelper() - { - m_vertexCoordinateArray[0] = -1.0f; - m_vertexCoordinateArray[1] = -1.0f; - m_vertexCoordinateArray[2] = 1.0f; - m_vertexCoordinateArray[3] = -1.0f; - m_vertexCoordinateArray[4] = 1.0f; - m_vertexCoordinateArray[5] = 1.0f; - m_vertexCoordinateArray[6] = -1.0f; - m_vertexCoordinateArray[7] = 1.0f; - - m_textureCoordinateArray[0] = 0.0f; - m_textureCoordinateArray[1] = 0.0f; - m_textureCoordinateArray[2] = 1.0f; - m_textureCoordinateArray[3] = 0.0f; - m_textureCoordinateArray[4] = 1.0f; - m_textureCoordinateArray[5] = 1.0f; - m_textureCoordinateArray[6] = 0.0f; - m_textureCoordinateArray[7] = 1.0f; - - m_blitProgram = new QOpenGLShaderProgram; - { - QString source; - source.append(QLatin1String(qopenglslMainWithTexCoordsVertexShader)); - source.append(QLatin1String(qopenglslUntransformedPositionVertexShader)); - - QOpenGLShader *vertexShader = new QOpenGLShader(QOpenGLShader::Vertex, m_blitProgram); - vertexShader->compileSourceCode(source); - - m_blitProgram->addShader(vertexShader); - } - { - QString source; - source.append(QLatin1String(qopenglslMainFragmentShader)); - source.append(QLatin1String(qopenglslImageSrcFragmentShader)); - - QOpenGLShader *fragmentShader = new QOpenGLShader(QOpenGLShader::Fragment, m_blitProgram); - fragmentShader->compileSourceCode(source); - - m_blitProgram->addShader(fragmentShader); - } - m_blitProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); - m_blitProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); - m_blitProgram->link(); - } - - ~TextureBlitHelper() - { - delete m_blitProgram; - } - - QOpenGLShaderProgram *blitProgram() { return m_blitProgram; } - const GLfloat *blitVertexArray() const { return &m_vertexCoordinateArray[0]; } - const GLfloat *blitTextureArray() const { return &m_textureCoordinateArray[0]; } - -private: - QOpenGLShaderProgram *m_blitProgram; - GLfloat m_vertexCoordinateArray[8]; - GLfloat m_textureCoordinateArray[8]; -}; - -static TextureBlitHelper *g_textureBlitHelper = 0; - QHash QSGDefaultDistanceFieldGlyphCache::m_textures_data; -QSGDefaultDistanceFieldGlyphCache::DistanceFieldTextureData *QSGDefaultDistanceFieldGlyphCache::textureData() +QSGDefaultDistanceFieldGlyphCache::DistanceFieldTextureData *QSGDefaultDistanceFieldGlyphCache::textureData(QOpenGLContext *c) { QString key = QString::fromLatin1("%1_%2_%3_%4") .arg(font().familyName()) .arg(font().styleName()) .arg(font().weight()) .arg(font().style()); - return m_textures_data[key].value(QOpenGLContext::currentContext()); + return m_textures_data[key].value(c); } QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font) : QSGDistanceFieldGlyphCache(man, c, font) , m_maxTextureSize(0) { - m_textureData = textureData(); + m_textureData = textureData(c); } void QSGDefaultDistanceFieldGlyphCache::requestGlyphs(const QVector &glyphs) @@ -288,8 +220,10 @@ void QSGDefaultDistanceFieldGlyphCache::resizeTexture(int width, int height) return; } - if (!g_textureBlitHelper) - g_textureBlitHelper = new TextureBlitHelper; + if (!m_textureData->blitProgram) + m_textureData->createBlitProgram(); + + Q_ASSERT(m_textureData->blitProgram); if (!m_textureData->fbo) ctx->functions()->glGenFramebuffers(1, &m_textureData->fbo); @@ -332,14 +266,14 @@ void QSGDefaultDistanceFieldGlyphCache::resizeTexture(int width, int height) glViewport(0, 0, oldWidth, oldHeight); - ctx->functions()->glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, g_textureBlitHelper->blitVertexArray()); - ctx->functions()->glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, g_textureBlitHelper->blitTextureArray()); + ctx->functions()->glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureData->blitVertexCoordinateArray); + ctx->functions()->glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureData->blitTextureCoordinateArray); - g_textureBlitHelper->blitProgram()->bind(); - g_textureBlitHelper->blitProgram()->enableAttributeArray(int(QT_VERTEX_COORDS_ATTR)); - g_textureBlitHelper->blitProgram()->enableAttributeArray(int(QT_TEXTURE_COORDS_ATTR)); - g_textureBlitHelper->blitProgram()->disableAttributeArray(int(QT_OPACITY_ATTR)); - g_textureBlitHelper->blitProgram()->setUniformValue("imageTexture", GLuint(0)); + m_textureData->blitProgram->bind(); + m_textureData->blitProgram->enableAttributeArray(int(QT_VERTEX_COORDS_ATTR)); + m_textureData->blitProgram->enableAttributeArray(int(QT_TEXTURE_COORDS_ATTR)); + m_textureData->blitProgram->disableAttributeArray(int(QT_OPACITY_ATTR)); + m_textureData->blitProgram->setUniformValue("imageTexture", GLuint(0)); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); diff --git a/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache_p.h index aed8d72..2886091 100644 --- a/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache_p.h +++ b/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache_p.h @@ -44,6 +44,8 @@ #include #include +#include +#include QT_BEGIN_NAMESPACE @@ -76,29 +78,84 @@ private: int currY; QImage image; + QOpenGLShaderProgram *blitProgram; + GLfloat blitVertexCoordinateArray[8]; + GLfloat blitTextureCoordinateArray[8]; + DistanceFieldTextureData(QOpenGLContext *ctx) : QOpenGLSharedResource(ctx->shareGroup()) , texture(0) , fbo(0) , currX(0) , currY(0) - {} + , blitProgram(0) + { + blitVertexCoordinateArray[0] = -1.0f; + blitVertexCoordinateArray[1] = -1.0f; + blitVertexCoordinateArray[2] = 1.0f; + blitVertexCoordinateArray[3] = -1.0f; + blitVertexCoordinateArray[4] = 1.0f; + blitVertexCoordinateArray[5] = 1.0f; + blitVertexCoordinateArray[6] = -1.0f; + blitVertexCoordinateArray[7] = 1.0f; + + blitTextureCoordinateArray[0] = 0.0f; + blitTextureCoordinateArray[1] = 0.0f; + blitTextureCoordinateArray[2] = 1.0f; + blitTextureCoordinateArray[3] = 0.0f; + blitTextureCoordinateArray[4] = 1.0f; + blitTextureCoordinateArray[5] = 1.0f; + blitTextureCoordinateArray[6] = 0.0f; + blitTextureCoordinateArray[7] = 1.0f; + } void invalidateResource() { texture = 0; fbo = 0; size = QSize(); + delete blitProgram; + blitProgram = 0; } void freeResource(QOpenGLContext *ctx) { glDeleteTextures(1, &texture); ctx->functions()->glDeleteFramebuffers(1, &fbo); + delete blitProgram; + blitProgram = 0; + } + + void createBlitProgram() + { + blitProgram = new QOpenGLShaderProgram; + { + QString source; + source.append(QLatin1String(qopenglslMainWithTexCoordsVertexShader)); + source.append(QLatin1String(qopenglslUntransformedPositionVertexShader)); + + QOpenGLShader *vertexShader = new QOpenGLShader(QOpenGLShader::Vertex, blitProgram); + vertexShader->compileSourceCode(source); + + blitProgram->addShader(vertexShader); + } + { + QString source; + source.append(QLatin1String(qopenglslMainFragmentShader)); + source.append(QLatin1String(qopenglslImageSrcFragmentShader)); + + QOpenGLShader *fragmentShader = new QOpenGLShader(QOpenGLShader::Fragment, blitProgram); + fragmentShader->compileSourceCode(source); + + blitProgram->addShader(fragmentShader); + } + blitProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + blitProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); + blitProgram->link(); } }; - DistanceFieldTextureData *textureData(); + DistanceFieldTextureData *textureData(QOpenGLContext *c); DistanceFieldTextureData *m_textureData; static QHash m_textures_data; }; -- 2.7.4