diff options
Diffstat (limited to 'src/opengl/qopenglpaintengine.cpp')
-rw-r--r-- | src/opengl/qopenglpaintengine.cpp | 103 |
1 files changed, 58 insertions, 45 deletions
diff --git a/src/opengl/qopenglpaintengine.cpp b/src/opengl/qopenglpaintengine.cpp index 451b808101..972e276370 100644 --- a/src/opengl/qopenglpaintengine.cpp +++ b/src/opengl/qopenglpaintengine.cpp @@ -160,10 +160,14 @@ template<typename T> void QOpenGL2PaintEngineExPrivate::updateTexture(GLenum textureUnit, const T &texture, GLenum wrapMode, GLenum filterMode, TextureUpdateMode updateMode) { static const GLenum target = GL_TEXTURE_2D; + bool newTextureCreated = false; activateTextureUnit(textureUnit); - GLuint textureId = bindTexture(texture); + GLuint textureId = bindTexture(texture, &newTextureCreated); + + if (newTextureCreated) + lastTextureUsed = GLuint(-1); if (updateMode == UpdateIfNeeded && textureId == lastTextureUsed) return; @@ -192,8 +196,11 @@ void QOpenGL2PaintEngineExPrivate::activateTextureUnit(GLenum textureUnit) } template<> -GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const GLuint &textureId) +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const GLuint &textureId, bool *newTextureCreated) { + if (newTextureCreated) + *newTextureCreated = false; + if (textureId != lastTextureUsed) funcs.glBindTexture(GL_TEXTURE_2D, textureId); @@ -201,19 +208,25 @@ GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const GLuint &textureId) } template<> -GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QImage &image) +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QImage &image, bool *newTextureCreated) { - return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image); + QOpenGLTextureCache::BindResult result = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image); + if (newTextureCreated) + *newTextureCreated = result.flags.testFlag(QOpenGLTextureCache::BindResultFlag::NewTexture); + return result.id; } template<> -GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QPixmap &pixmap) +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QPixmap &pixmap, bool *newTextureCreated) { - return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); + QOpenGLTextureCache::BindResult result = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); + if (newTextureCreated) + *newTextureCreated = result.flags.testFlag(QOpenGLTextureCache::BindResultFlag::NewTexture); + return result.id; } template<> -GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QGradient &gradient) +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QGradient &gradient, bool *newTextureCreated) { // We apply global opacity in the fragment shaders, so we always pass 1.0 // for opacity to the cache. @@ -223,7 +236,7 @@ GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QGradient &gradient) // 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); + return bindTexture(textureId, newTextureCreated); } struct ImageWithBindOptions @@ -233,9 +246,14 @@ struct ImageWithBindOptions }; template<> -GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const ImageWithBindOptions &imageWithOptions) +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const ImageWithBindOptions &imageWithOptions, bool *newTextureCreated) { - return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, imageWithOptions.image, imageWithOptions.options); + QOpenGLTextureCache::BindResult result = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, + imageWithOptions.image, + imageWithOptions.options); + if (newTextureCreated) + *newTextureCreated = result.flags.testFlag(QOpenGLTextureCache::BindResultFlag::NewTexture); + return result.id; } inline static bool isPowerOfTwo(int x) @@ -606,18 +624,10 @@ static inline void setCoords(GLfloat *coords, const QOpenGLRect &rect) coords[7] = rect.bottom; } -void QOpenGL2PaintEngineExPrivate::drawTexture(const QOpenGLRect& dest, const QOpenGLRect& src, const QSize &textureSize, bool opaque, bool pattern) +void Q_TRACE_INSTRUMENT(qtopengl) QOpenGL2PaintEngineExPrivate::drawTexture(const QOpenGLRect& dest, const QOpenGLRect& src, const QSize &textureSize, bool opaque, bool pattern) { - Q_TRACE_SCOPE(QOpenGL2PaintEngineExPrivate_drawTexture, - dest.left, - dest.top, - dest.right, - dest.bottom, - src.left, - src.top, - src.right, - src.bottom, - textureSize, opaque); + Q_TRACE_PARAM_REPLACE(QOpenGLRect, QRectF); + Q_TRACE_SCOPE(QOpenGL2PaintEngineExPrivate_drawTexture, dest, src, textureSize, opaque, pattern); // Setup for texture drawing currentBrush = noBrush; @@ -735,11 +745,11 @@ void QOpenGL2PaintEngineExPrivate::resetGLState() float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; funcs.glVertexAttrib4fv(3, color); } - if (vao.isCreated()) { + if (vao.isCreated()) vao.release(); - funcs.glBindBuffer(GL_ARRAY_BUFFER, 0); - funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } + + funcs.glBindBuffer(GL_ARRAY_BUFFER, 0); + funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } void QOpenGL2PaintEngineEx::endNativePainting() @@ -2141,6 +2151,10 @@ void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFra transferMode(ImageOpacityArrayDrawingMode); + uploadData(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinateArray.data(), vertexCoordinateArray.vertexCount() * 2); + uploadData(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinateArray.data(), textureCoordinateArray.vertexCount() * 2); + uploadData(QT_OPACITY_ATTR, (GLfloat*)opacityArray.data(), opacityArray.size()); + GLenum filterMode = q->state()->renderHints & QPainter::SmoothPixmapTransform ? GL_LINEAR : GL_NEAREST; updateTexture(QT_IMAGE_TEXTURE_UNIT, pixmap, GL_CLAMP_TO_EDGE, filterMode); @@ -2207,28 +2221,27 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) bool created = d->vao.create(); // If we managed to create it then we have a profile that supports VAOs - if (created) { + if (created) d->vao.bind(); + } - // Generate a new Vertex Buffer Object if we don't have one already - if (!d->vertexBuffer.isCreated()) { - d->vertexBuffer.create(); - // Set its usage to StreamDraw, we will use this buffer only a few times before refilling it - d->vertexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); - } - if (!d->texCoordBuffer.isCreated()) { - d->texCoordBuffer.create(); - d->texCoordBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); - } - if (!d->opacityBuffer.isCreated()) { - d->opacityBuffer.create(); - d->opacityBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); - } - if (!d->indexBuffer.isCreated()) { - d->indexBuffer.create(); - d->indexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); - } - } + // Generate a new Vertex Buffer Object if we don't have one already + if (!d->vertexBuffer.isCreated()) { + d->vertexBuffer.create(); + // Set its usage to StreamDraw, we will use this buffer only a few times before refilling it + d->vertexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); + } + if (!d->texCoordBuffer.isCreated()) { + d->texCoordBuffer.create(); + d->texCoordBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); + } + if (!d->opacityBuffer.isCreated()) { + d->opacityBuffer.create(); + d->opacityBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); + } + if (!d->indexBuffer.isCreated()) { + d->indexBuffer.create(); + d->indexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); } for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) |