diff options
Diffstat (limited to 'src/gui/opengl')
-rw-r--r-- | src/gui/opengl/qopenglpaintengine.cpp | 40 | ||||
-rw-r--r-- | src/gui/opengl/qopenglpaintengine_p.h | 3 | ||||
-rw-r--r-- | src/gui/opengl/qopengltextureglyphcache.cpp | 44 |
3 files changed, 57 insertions, 30 deletions
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index d248d2b8e5..555c47f265 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -624,7 +624,7 @@ void QOpenGL2PaintEngineExPrivate::transferMode(EngineMode newMode) if (newMode == mode) return; - if (mode == TextDrawingMode || mode == ImageDrawingMode || mode == ImageArrayDrawingMode) { + if (mode != BrushDrawingMode) { lastTextureUsed = GLuint(-1); } @@ -639,10 +639,12 @@ void QOpenGL2PaintEngineExPrivate::transferMode(EngineMode newMode) setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, staticTextureCoordinateArray); } - if (newMode == ImageArrayDrawingMode) { + if (newMode == ImageArrayDrawingMode || newMode == ImageOpacityArrayDrawingMode) { setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinateArray.data()); setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinateArray.data()); - setVertexAttributePointer(QT_OPACITY_ATTR, (GLfloat*)opacityArray.data()); + + if (newMode == ImageOpacityArrayDrawingMode) + setVertexAttributePointer(QT_OPACITY_ATTR, (GLfloat*)opacityArray.data()); } // This needs to change when we implement high-quality anti-aliasing... @@ -1085,7 +1087,7 @@ bool QOpenGL2PaintEngineExPrivate::prepareForCachedGlyphDraw(const QFontEngineGl bool QOpenGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) { - if (brushTextureDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode) + if (brushTextureDirty && (mode == TextDrawingMode || mode == BrushDrawingMode)) updateBrushTexture(); if (compositionModeDirty) @@ -1105,12 +1107,12 @@ bool QOpenGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) } QOpenGLEngineShaderManager::OpacityMode opacityMode; - if (mode == ImageArrayDrawingMode) { + if (mode == ImageOpacityArrayDrawingMode) { opacityMode = QOpenGLEngineShaderManager::AttributeOpacity; } else { opacityMode = stateHasOpacity ? QOpenGLEngineShaderManager::UniformOpacity : QOpenGLEngineShaderManager::NoOpacity; - if (stateHasOpacity && (mode != ImageDrawingMode)) { + if (stateHasOpacity && (mode != ImageDrawingMode && mode != ImageArrayDrawingMode)) { // Using a brush bool brushIsPattern = (currentBrush.style() >= Qt::Dense1Pattern) && (currentBrush.style() <= Qt::DiagCrossPattern); @@ -1130,7 +1132,7 @@ bool QOpenGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) matrixUniformDirty = true; } - if (brushUniformsDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode) + if (brushUniformsDirty && (mode == TextDrawingMode || mode == BrushDrawingMode)) updateBrushUniforms(); if (opacityMode == QOpenGLEngineShaderManager::UniformOpacity && opacityUniformDirty) { @@ -1602,7 +1604,10 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type if (cache->width() == 0 || cache->height() == 0) return; - transferMode(TextDrawingMode); + if (glyphType == QFontEngineGlyphCache::Raster_ARGB) + transferMode(ImageArrayDrawingMode); + else + transferMode(TextDrawingMode); int margin = fe->glyphMargin(glyphType); @@ -1698,8 +1703,10 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type #endif } - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinates->data()); - setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinates->data()); + if (glyphType != QFontEngineGlyphCache::Raster_ARGB || recreateVertexArrays) { + setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinates->data()); + setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinates->data()); + } if (!snapToPixelGrid) { snapToPixelGrid = true; @@ -1782,6 +1789,11 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glBlendFunc(GL_ONE, GL_ONE); } compositionModeDirty = true; + } else if (glyphType == QFontEngineGlyphCache::Raster_ARGB) { + currentBrush = noBrush; + shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc); + if (prepareForCachedGlyphDraw(*cache)) + shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); } else { // Greyscale/mono glyphs @@ -1792,7 +1804,11 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type QOpenGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QOpenGLTextureGlyphCache::Linear:QOpenGLTextureGlyphCache::Nearest; if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) { - funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); + if (glyphType == QFontEngineGlyphCache::Raster_ARGB) + funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); + else + funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); + if (lastMaskTextureUsed != cache->texture()) { glBindTexture(GL_TEXTURE_2D, cache->texture()); lastMaskTextureUsed = cache->texture(); @@ -1908,7 +1924,7 @@ void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFra funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); - transferMode(ImageArrayDrawingMode); + transferMode(ImageOpacityArrayDrawingMode); bool isBitmap = pixmap.isQBitmap(); bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)) && allOpaque; diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h index 9c54eae3b3..d51f0e5256 100644 --- a/src/gui/opengl/qopenglpaintengine_p.h +++ b/src/gui/opengl/qopenglpaintengine_p.h @@ -70,7 +70,8 @@ enum EngineMode { ImageDrawingMode, TextDrawingMode, BrushDrawingMode, - ImageArrayDrawingMode + ImageArrayDrawingMode, + ImageOpacityArrayDrawingMode }; QT_BEGIN_NAMESPACE diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp index b751629117..83f407575e 100644 --- a/src/gui/opengl/qopengltextureglyphcache.cpp +++ b/src/gui/opengl/qopengltextureglyphcache.cpp @@ -120,7 +120,7 @@ void QOpenGLTextureGlyphCache::createTextureData(int width, int height) m_textureResource->m_width = width; m_textureResource->m_height = height; - if (m_type == QFontEngineGlyphCache::Raster_RGBMask) { + if (m_type == QFontEngineGlyphCache::Raster_RGBMask || m_type == QFontEngineGlyphCache::Raster_ARGB) { QVarLengthArray<uchar> data(width * height * 4); for (int i = 0; i < data.size(); ++i) data[i] = 0; @@ -314,30 +314,40 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed for (int x = 0; x < maskWidth; ++x) src[x] = -src[x]; // convert 0 and 1 into 0 and 255 } - } else if (mask.format() == QImage::Format_RGB32) { - // Make the alpha component equal to the average of the RGB values. - // This is needed when drawing sub-pixel antialiased text on translucent targets. - for (int y = 0; y < maskHeight; ++y) { - quint32 *src = (quint32 *) mask.scanLine(y); - for (int x = 0; x < maskWidth; ++x) { - uchar r = src[x] >> 16; - uchar g = src[x] >> 8; - uchar b = src[x]; - quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding. + } else if (mask.depth() == 32) { + if (mask.format() == QImage::Format_RGB32 + // We need to make the alpha component equal to the average of the RGB values. + // This is needed when drawing sub-pixel antialiased text on translucent targets. +#if defined(QT_OPENGL_ES_2) + || !hasBGRA // We need to reverse the bytes +#endif + ) { + for (int y = 0; y < maskHeight; ++y) { + quint32 *src = (quint32 *) mask.scanLine(y); + for (int x = 0; x < maskWidth; ++x) { + uchar r = src[x] >> 16; + uchar g = src[x] >> 8; + uchar b = src[x]; + quint32 avg; + if (mask.format() == QImage::Format_RGB32) + avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding. + else // Format_ARGB_Premultiplied + avg = src[x] >> 24; #if defined(QT_OPENGL_ES_2) - if (!hasBGRA) { - // Reverse bytes to match GL_RGBA - src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16); - } else + if (!hasBGRA) { + // Reverse bytes to match GL_RGBA + src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16); + } else #endif - src[x] = (src[x] & 0x00ffffff) | (avg << 24); + src[x] = (src[x] & 0x00ffffff) | (avg << 24); + } } } } glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); - if (mask.format() == QImage::Format_RGB32) { + if (mask.depth() == 32) { #if defined(QT_OPENGL_ES_2) glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, hasBGRA ? GL_BGRA_EXT : GL_RGBA, GL_UNSIGNED_BYTE, mask.bits()); #else |