diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-01-26 11:27:37 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2016-01-26 11:27:37 +0000 |
commit | 0a1af55a9b69f7fd58dbce43a0d4c1faf0143838 (patch) | |
tree | 26da168e740734d168be37803abec2f8739b213d /src/gui/painting | |
parent | b8fb0ee999d32401157be8d86e5a03185aadbb9e (diff) | |
parent | 158a3a4159bdc5a49caecd63e021dacbc06cf23c (diff) |
Merge "Merge remote-tracking branch 'origin/5.6' into dev" into refs/staging/dev
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qplatformbackingstore.cpp | 80 | ||||
-rw-r--r-- | src/gui/painting/qplatformbackingstore.h | 3 |
2 files changed, 66 insertions, 17 deletions
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index b527ef6ab2..640792c6ec 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -63,6 +63,12 @@ #ifndef GL_UNPACK_ROW_LENGTH #define GL_UNPACK_ROW_LENGTH 0x0CF2 #endif +#ifndef GL_RGB10_A2 +#define GL_RGB10_A2 0x8059 +#endif +#ifndef GL_UNSIGNED_INT_2_10_10_10_REV +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#endif QT_BEGIN_NAMESPACE @@ -98,6 +104,7 @@ public: mutable GLuint textureId; mutable QSize textureSize; mutable bool needsSwizzle; + mutable bool premultiplied; QOpenGLTextureBlitter *blitter; #endif }; @@ -329,9 +336,6 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset); } - funcs->glEnable(GL_BLEND); - funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - // Backingstore texture with the normal widgets. GLuint textureId = 0; QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft; @@ -351,7 +355,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle)) { + if (QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle, &d_ptr->premultiplied)) { d_ptr->textureSize = graphicsBuffer->size(); } else { d_ptr->textureSize = QSize(0,0); @@ -360,7 +364,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i graphicsBuffer->unlock(); } else if (!region.isEmpty()){ funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); - QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle); + QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle, &d_ptr->premultiplied); } if (graphicsBuffer->origin() == QPlatformGraphicsBuffer::OriginBottomLeft) @@ -370,10 +374,17 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i TextureFlags flags = 0; textureId = toTexture(deviceRegion(region, window, offset), &d_ptr->textureSize, &flags); d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0; + d_ptr->premultiplied = (flags & TexturePremultiplied) != 0; if (flags & TextureFlip) origin = QOpenGLTextureBlitter::OriginBottomLeft; } + funcs->glEnable(GL_BLEND); + if (d_ptr->premultiplied) + funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + else + funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + if (textureId) { if (d_ptr->needsSwizzle) d_ptr->blitter->setSwizzleRB(true); @@ -449,10 +460,50 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu QImage image = toImage(); QSize imageSize = image.size(); + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + GLenum internalFormat = GL_RGBA; + GLuint pixelType = GL_UNSIGNED_BYTE; + + bool needsConversion = false; *flags = 0; - if (image.format() == QImage::Format_RGB32) + switch (image.format()) { + case QImage::Format_ARGB32_Premultiplied: + *flags |= TexturePremultiplied; + // no break + case QImage::Format_RGB32: + case QImage::Format_ARGB32: *flags |= TextureSwizzle; - + break; + case QImage::Format_RGBA8888_Premultiplied: + *flags |= TexturePremultiplied; + // no break + case QImage::Format_RGBX8888: + case QImage::Format_RGBA8888: + break; + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { + pixelType = GL_UNSIGNED_INT_2_10_10_10_REV; + internalFormat = GL_RGB10_A2; + *flags |= TexturePremultiplied; + } else { + needsConversion = true; + } + break; + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { + pixelType = GL_UNSIGNED_INT_2_10_10_10_REV; + internalFormat = GL_RGB10_A2; + *flags |= TextureSwizzle | TexturePremultiplied; + } else { + needsConversion = true; + } + break; + default: + needsConversion = true; + break; + } if (imageSize.isEmpty()) { *textureSize = imageSize; return 0; @@ -466,17 +517,15 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu *textureSize = imageSize; - // Fast path for RGB32 and RGBA8888, convert everything else to RGBA8888. - if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_RGBA8888) + if (needsConversion) image = image.convertToFormat(QImage::Format_RGBA8888); - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctions *funcs = ctx->functions(); if (resized) { if (d_ptr->textureId) funcs->glDeleteTextures(1, &d_ptr->textureId); funcs->glGenTextures(1, &d_ptr->textureId); funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); - QOpenGLContext *ctx = QOpenGLContext::currentContext(); if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); @@ -486,17 +535,16 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, imageSize.width(), imageSize.height(), 0, GL_RGBA, pixelType, const_cast<uchar*>(image.constBits())); } else { funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); QRect imageRect = image.rect(); QRect rect = dirtyRegion.boundingRect() & imageRect; - QOpenGLContext *ctx = QOpenGLContext::currentContext(); if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width()); - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.constScanLine(rect.y()) + rect.x() * 4); funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } else { @@ -511,10 +559,10 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu // OpenGL instead of copying, since there's no gap between scanlines if (rect.width() == imageRect.width()) { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.constScanLine(rect.y())); } else { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.copy(rect).constBits()); } } diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index 2148fe0e7e..9b09620cce 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -124,7 +124,8 @@ public: virtual QImage toImage() const; enum TextureFlag { TextureSwizzle = 0x01, - TextureFlip = 0x02 + TextureFlip = 0x02, + TexturePremultiplied = 0x04, }; Q_DECLARE_FLAGS(TextureFlags, TextureFlag) virtual GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const; |