diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2014-12-08 16:41:33 +0100 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com> | 2014-12-13 01:49:24 +0100 |
commit | dfccd78aa671364346bc9c4d1203dcb54d008a07 (patch) | |
tree | 2d96a64e83420ea6b84993658abf0df51bebf0af /src/gui/opengl | |
parent | 384388f2cd739fd1416e4016588c79fd9788e898 (diff) |
Ensure that GL::updateBrushTexture() activates and binds properly
Calling QOpenGL2GradientCache::getBuffer() will generate the texture the
first time, calling glBindTexture in the process. We did this without
first ensuring that the right texture unit was active, resulting in the
generated gradient texture binding onto the glyph cache mask unit.
We now provide a specialization of bindTexture for a QGradient, which
ensures that the right unit is active before calling getBuffer().
Unfortunately we have no way of knowing if the result of getBuffer()
was a texture that was already bound, or if we need to bind the result,
which means we have to do an unconditional bindTexture of the resulting
texture ID. This means double-bind for the initial texture generation,
but this was already an issue in the original code.
Task-number: QTBUG-43039
Task-number: QTBUG-41244
Change-Id: I20c9b795c8c14f8d58be2b60a284c5a060705ec0
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
Diffstat (limited to 'src/gui/opengl')
-rw-r--r-- | src/gui/opengl/qopenglpaintengine.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index 48a2ceaa55..a854715f70 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -223,6 +223,20 @@ GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QPixmap &pixmap) return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); } +template<> +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QGradient &gradient) +{ + // We apply global opacity in the fragment shaders, so we always pass 1.0 + // for opacity to the cache. + GLuint textureId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(gradient, 1.0); + + // QOpenGL2GradientCache::getBuffer() may bind and generate a new texture if it + // hasn't been cached yet, but will otherwise return an unbound texture id. To + // be sure that the texture is bound, we unfortunately have to bind again, + // which results in the initial generation of the texture doing two binds. + return bindTexture(textureId); +} + struct ImageWithBindOptions { const QImage ℑ @@ -253,19 +267,15 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture() else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) { // Gradiant brush: All the gradiants use the same texture - const QGradient* g = currentBrush.gradient(); - - // We apply global opacity in the fragment shaders, so we always pass 1.0 - // for opacity to the cache. - GLuint textureId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0); + const QGradient *gradient = currentBrush.gradient(); GLenum wrapMode = GL_CLAMP_TO_EDGE; - if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient) + if (gradient->spread() == QGradient::RepeatSpread || gradient->type() == QGradient::ConicalGradient) wrapMode = GL_REPEAT; - else if (g->spread() == QGradient::ReflectSpread) + else if (gradient->spread() == QGradient::ReflectSpread) wrapMode = GL_MIRRORED_REPEAT; - updateTexture(QT_BRUSH_TEXTURE_UNIT, textureId, wrapMode, filterMode, ForceUpdate); + updateTexture(QT_BRUSH_TEXTURE_UNIT, *gradient, wrapMode, filterMode, ForceUpdate); } else if (style == Qt::TexturePattern) { currentBrushImage = currentBrush.textureImage(); |