summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/kernel/qplatformgraphicsbufferhelper.cpp34
-rw-r--r--src/gui/kernel/qplatformgraphicsbufferhelper.h4
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp38
-rw-r--r--src/gui/painting/qplatformbackingstore.h3
4 files changed, 60 insertions, 19 deletions
diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
index 1d59c38598..7f2672bc5e 100644
--- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
+++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
@@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE
bound texture, otherwise returns false.
*/
bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer,
- bool *swizzle,
+ bool *swizzle, bool *premultiplied,
const QRect &rect)
{
if (graphicsBuffer->lock(QPlatformGraphicsBuffer::TextureAccess)) {
@@ -74,8 +74,10 @@ bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer
}
if (swizzle)
*swizzle = false;
+ if (premultiplied)
+ *premultiplied = false;
} else if (graphicsBuffer->lock(QPlatformGraphicsBuffer::SWReadAccess)) {
- if (!bindSWToTexture(graphicsBuffer, swizzle, rect)) {
+ if (!bindSWToTexture(graphicsBuffer, swizzle, premultiplied, rect)) {
qWarning("Failed to bind %sgraphicsbuffer to texture", "SW ");
return false;
}
@@ -109,7 +111,7 @@ bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer
Returns true on success, otherwise false.
*/
bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer,
- bool *swizzleRandB,
+ bool *swizzleRandB, bool *premultipliedB,
const QRect &subRect)
{
#ifndef QT_NO_OPENGL
@@ -124,14 +126,30 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
Q_ASSERT(subRect.isEmpty() || QRect(QPoint(0,0), size).contains(subRect));
bool swizzle = false;
+ bool premultiplied = false;
QImage::Format imageformat = QImage::toImageFormat(graphicsBuffer->format());
QImage image(graphicsBuffer->data(), size.width(), size.height(), graphicsBuffer->bytesPerLine(), imageformat);
if (graphicsBuffer->bytesPerLine() != (size.width() * 4)) {
image = image.convertToFormat(QImage::Format_RGBA8888);
- } else if (imageformat == QImage::Format_RGB32) {
- swizzle = true;
- } else if (imageformat != QImage::Format_RGBA8888) {
- image = image.convertToFormat(QImage::Format_RGBA8888);
+ } else {
+ switch (imageformat) {
+ case QImage::Format_ARGB32_Premultiplied:
+ premultiplied = true;
+ // no break
+ case QImage::Format_RGB32:
+ case QImage::Format_ARGB32:
+ swizzle = true;
+ break;
+ case QImage::Format_RGBA8888_Premultiplied:
+ premultiplied = true;
+ // no break
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ break;
+ default:
+ image = image.convertToFormat(QImage::Format_RGBA8888);
+ break;
+ }
}
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
@@ -170,6 +188,8 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
}
if (swizzleRandB)
*swizzleRandB = swizzle;
+ if (premultipliedB)
+ *premultipliedB = premultiplied;
return true;
diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.h b/src/gui/kernel/qplatformgraphicsbufferhelper.h
index ded7810608..cc1a4918cd 100644
--- a/src/gui/kernel/qplatformgraphicsbufferhelper.h
+++ b/src/gui/kernel/qplatformgraphicsbufferhelper.h
@@ -39,8 +39,8 @@
QT_BEGIN_NAMESPACE
namespace QPlatformGraphicsBufferHelper {
- bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, const QRect &rect = QRect());
- bool bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB = Q_NULLPTR, const QRect &rect = QRect());
+ bool lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB, bool *premultipliedB, const QRect &rect = QRect());
+ bool bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, bool *swizzleRandB = Q_NULLPTR, bool *premultipliedB = Q_NULLPTR, const QRect &rect = QRect());
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index 4b725fc79f..ef1652b48b 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -92,6 +92,7 @@ public:
mutable GLuint textureId;
mutable QSize textureSize;
mutable bool needsSwizzle;
+ mutable bool premultiplied;
QOpenGLTextureBlitter *blitter;
#endif
};
@@ -323,9 +324,6 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
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;
@@ -345,7 +343,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
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);
@@ -354,7 +352,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
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)
@@ -364,10 +362,17 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
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);
@@ -443,10 +448,26 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
QImage image = toImage();
QSize imageSize = image.size();
+ bool needConvert = 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;
+ default:
+ needConvert = true;
+ break;
+ }
if (imageSize.isEmpty()) {
*textureSize = imageSize;
return 0;
@@ -460,8 +481,7 @@ 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 (needConvert)
image = image.convertToFormat(QImage::Format_RGBA8888);
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index eac97e9cf6..9c8da0d1db 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -118,7 +118,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;