diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-09-29 11:12:06 (GMT) |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-09-29 13:58:23 (GMT) |
commit | a67b7d96c14eeb939de5d8a84737b55d904b4e33 (patch) | |
tree | 87cc2e3b843def288a5c26fd8141e3b236a42ed0 /src | |
parent | d49a7e382c69076de179103c9072e49a72db264d (diff) | |
download | Qt-a67b7d96c14eeb939de5d8a84737b55d904b4e33.zip Qt-a67b7d96c14eeb939de5d8a84737b55d904b4e33.tar.gz Qt-a67b7d96c14eeb939de5d8a84737b55d904b4e33.tar.bz2 |
Make texture glyph cache on OpenGL work without a paint engine
When used from outside of Qt, the OpenGL texture glyph cache would fall
back to using an image backend. This was not exactly ideal, so instead
it's rewritten to set up its own blit program etc. when the paint engine
is not available. Note that fillInPendingGlyphs() will potentially
alter the current GL state/viewport/bindings/etc., so it should be
called before setting up the actual painting.
Reviewed-by: Kim
Diffstat (limited to 'src')
-rw-r--r-- | src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 78 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h | 1 |
2 files changed, 67 insertions, 12 deletions
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index f8e34d4..d69eb39 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -41,6 +41,7 @@ #include "qtextureglyphcache_gl_p.h" #include "qpaintengineex_opengl2_p.h" +#include "private/qglengineshadersource_p.h" #if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL) #include "private/qeglcontext_p.h" @@ -56,6 +57,7 @@ QGLTextureGlyphCache::QGLTextureGlyphCache(const QGLContext *context, QFontEngin : QImageTextureGlyphCache(type, matrix) , ctx(0) , pex(0) + , m_blitProgram(0) { #ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG qDebug(" -> QGLTextureGlyphCache() %p for context %p.", this, ctx); @@ -68,6 +70,8 @@ QGLTextureGlyphCache::~QGLTextureGlyphCache() #ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG qDebug(" -> ~QGLTextureGlyphCache() %p.", this); #endif + + delete m_blitProgram; } void QGLTextureGlyphCache::setContext(const QGLContext *context) @@ -86,7 +90,7 @@ void QGLTextureGlyphCache::createTextureData(int width, int height) // create in QImageTextureGlyphCache baseclass is meant to be called // only to create the initial image and does not preserve the content, // so we don't call when this function is called from resize. - if ((pex == 0 || ctx->d_ptr->workaround_brokenFBOReadBack) && image().isNull()) + if (ctx->d_ptr->workaround_brokenFBOReadBack && image().isNull()) QImageTextureGlyphCache::createTextureData(width, height); // Make the lower glyph texture size 16 x 16. @@ -135,7 +139,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) GLuint oldTexture = glyphTexture->m_texture; createTextureData(width, height); - if (pex == 0 || ctx->d_ptr->workaround_brokenFBOReadBack) { + if (ctx->d_ptr->workaround_brokenFBOReadBack) { QImageTextureGlyphCache::resizeTextureData(width, height); Q_ASSERT(image().depth() == 8); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); @@ -164,7 +168,8 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); glBindTexture(GL_TEXTURE_2D, oldTexture); - pex->transferMode(BrushDrawingMode); + if (pex != 0) + pex->transferMode(BrushDrawingMode); glDisable(GL_STENCIL_TEST); glDisable(GL_DEPTH_TEST); @@ -173,7 +178,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) glViewport(0, 0, oldWidth, oldHeight); - GLfloat* vertexCoordinateArray = pex->staticVertexCoordinateArray; + GLfloat vertexCoordinateArray[8]; vertexCoordinateArray[0] = -1.0f; vertexCoordinateArray[1] = -1.0f; vertexCoordinateArray[2] = 1.0f; @@ -183,7 +188,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) vertexCoordinateArray[6] = -1.0f; vertexCoordinateArray[7] = 1.0f; - GLfloat* textureCoordinateArray = pex->staticTextureCoordinateArray; + GLfloat textureCoordinateArray[8]; textureCoordinateArray[0] = 0.0f; textureCoordinateArray[1] = 0.0f; textureCoordinateArray[2] = 1.0f; @@ -193,11 +198,58 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) textureCoordinateArray[6] = 0.0f; textureCoordinateArray[7] = 1.0f; - pex->setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertexCoordinateArray); - pex->setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, textureCoordinateArray); + QGLShaderProgram *blitProgram = 0; + if (pex == 0) { + if (m_blitProgram == 0) { + m_blitProgram = new QGLShaderProgram(ctx); + + { + QString source; + source.append(qglslMainWithTexCoordsVertexShader); + source.append(qglslUntransformedPositionVertexShader); + + QGLShader *vertexShader = new QGLShader(QGLShader::Vertex, m_blitProgram); + vertexShader->compileSourceCode(source); + + m_blitProgram->addShader(vertexShader); + } + + { + QString source; + source.append(qglslMainFragmentShader); + source.append(qglslImageSrcFragmentShader); + + QGLShader *fragmentShader = new QGLShader(QGLShader::Fragment, m_blitProgram); + fragmentShader->compileSourceCode(source); - pex->shaderManager->useBlitProgram(); - pex->shaderManager->blitProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT); + m_blitProgram->addShader(fragmentShader); + } + + m_blitProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + m_blitProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); + + m_blitProgram->link(); + } + + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray); + glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray); + + m_blitProgram->bind(); + QGLContextPrivate* ctx_d = const_cast<QGLContextPrivate *>(ctx->d_func()); + ctx_d->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true); + ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, true); + ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); + blitProgram = m_blitProgram; + + } else { + pex->setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertexCoordinateArray); + pex->setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, textureCoordinateArray); + + pex->shaderManager->useBlitProgram(); + blitProgram = pex->shaderManager->blitProgram(); + } + + blitProgram->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -212,8 +264,10 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); - glViewport(0, 0, pex->width, pex->height); - pex->updateClipScissorTest(); + if (pex != 0) { + glViewport(0, 0, pex->width, pex->height); + pex->updateClipScissorTest(); + } } void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) @@ -224,7 +278,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub } QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx); - if (pex == 0 || ctx->d_ptr->workaround_brokenFBOReadBack) { + if (ctx->d_ptr->workaround_brokenFBOReadBack) { QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition); glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture); diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h index ada47e9..720e30c 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h @@ -138,6 +138,7 @@ private: const QGLContext *ctx; QGL2PaintEngineExPrivate *pex; + QGLShaderProgram *m_blitProgram; }; QT_END_NAMESPACE |