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>
bb10
Tor Arne Vestbø 2014-12-08 16:41:33 +01:00 committed by Tor Arne Vestbø
parent 384388f2cd
commit dfccd78aa6
2 changed files with 38 additions and 8 deletions

View File

@ -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 &image;
@ -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();

View File

@ -139,4 +139,24 @@ save
setClipPath clip
setPen black
repeat_block text_drawing
restore
translate 150 0
save
setPen black
setFont "sansserif" 10 normal
drawText 0 20 "testing glyph cache textures"
# Important that this gradient doesn't match any earlier
# gradients, so that it's not cached from before.
gradient_clearStops
gradient_appendStop 0 blue
gradient_appendStop 0.5 #00ff00
gradient_appendStop 1 red
gradient_setLinear 0 0 100 0
setPen nopen
drawRect 0 30 100 20
setPen black
drawText 0 70 "testing glyph cache textures"
restore