summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-04-21 11:05:07 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-05-06 10:39:02 +0000
commit39e3977cc532bcab90410bb85b7bda664dd6bfd3 (patch)
tree5c9c59ceb6fbc963d81bba24055fb98b4535f0c2 /src/gui/painting
parent4a4faedc3d457893058a829b3dfe74eb8170085a (diff)
Add flip support to QPlatformBackingStore::toTexture()
Necessary for iOS. In addition to swizzle we also need to communicate the need for flipping, so switch to flags instead of bools. Task-number: QTBUG-40034 Change-Id: I055e591afd838878503be6f5f69aa7347965d9cf Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp62
-rw-r--r--src/gui/painting/qplatformbackingstore.h11
2 files changed, 48 insertions, 25 deletions
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index 24ea3f4cdd..14a9429c71 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -308,7 +308,11 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
textureId = d_ptr->textureId;
} else {
// Backingstore texture with the normal widgets.
- textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize, &d_ptr->needsSwizzle);
+ TextureFlags flags = 0;
+ textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize, &flags);
+ d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0;
+ if (flags & TextureFlip)
+ origin = QOpenGLTextureBlitter::OriginBottomLeft;
}
if (textureId) {
@@ -354,43 +358,55 @@ QImage QPlatformBackingStore::toImage() const
backingstore as an OpenGL texture. \a dirtyRegion is the part of the
backingstore which may have changed since the last call to this function. The
caller of this function must ensure that there is a current context.
+
The size of the texture is returned in \a textureSize.
The ownership of the texture is not transferred. The caller must not store
the return value between calls, but instead call this function before each use.
- The default implementation returns a cached texture if \a dirtyRegion is
- empty and the window has not been resized, otherwise it retrieves the
- content using toImage() and performs a texture upload.
+ The default implementation returns a cached texture if \a dirtyRegion is empty and
+ \a textureSize matches the backingstore size, otherwise it retrieves the content using
+ toImage() and performs a texture upload. This works only if the value of \a textureSize
+ is preserved between the calls to this function.
+
+ If the red and blue components have to swapped, \a flags will be set to include \c
+ TextureSwizzle. This allows creating textures from images in formats like
+ QImage::Format_RGB32 without any further image conversion. Instead, the swizzling will
+ be done in the shaders when performing composition. Other formats, that do not need
+ such swizzling due to being already byte ordered RGBA, for example
+ QImage::Format_RGBA8888, must result in having \a needsSwizzle set to false.
- If the red and blue components have to swapped, \a needsSwizzle will be set to \c true.
- This allows creating textures from images in formats like QImage::Format_RGB32 without
- any further image conversion. Instead, the swizzling will be done in the shaders when
- performing composition. Other formats, that do not need such swizzling due to being
- already byte ordered RGBA, for example QImage::Format_RGBA8888, must result in having \a
- needsSwizzle set to false.
+ If the image has to be flipped (e.g. because the texture is attached to an FBO), \a
+ flags will be set to include \c TextureFlip.
*/
-GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize, bool *needsSwizzle) const
+GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const
{
+ Q_ASSERT(textureSize);
+ Q_ASSERT(flags);
+
QImage image = toImage();
QSize imageSize = image.size();
- if (imageSize.isEmpty())
+
+ *flags = 0;
+ if (image.format() == QImage::Format_RGB32)
+ *flags |= TextureSwizzle;
+
+ if (imageSize.isEmpty()) {
+ *textureSize = imageSize;
return 0;
+ }
- bool resized = d_ptr->textureSize != imageSize;
+ // Must rely on the input only, not d_ptr.
+ // With the default composeAndFlush() textureSize is &d_ptr->textureSize.
+ bool resized = *textureSize != imageSize;
if (dirtyRegion.isEmpty() && !resized)
return d_ptr->textureId;
+ *textureSize = imageSize;
+
// Fast path for RGB32 and RGBA8888, convert everything else to RGBA8888.
- if (image.format() == QImage::Format_RGB32) {
- if (needsSwizzle)
- *needsSwizzle = true;
- } else {
- if (needsSwizzle)
- *needsSwizzle = false;
- if (image.format() != QImage::Format_RGBA8888)
- image = image.convertToFormat(QImage::Format_RGBA8888);
- }
+ if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_RGBA8888)
+ image = image.convertToFormat(QImage::Format_RGBA8888);
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
@@ -412,8 +428,6 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
const_cast<uchar*>(image.constBits()));
- if (textureSize)
- *textureSize = imageSize;
} else {
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
QRect imageRect = image.rect();
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index df98ebf51b..ae7314b6d0 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -114,7 +114,12 @@ public:
QPlatformTextureList *textures, QOpenGLContext *context,
bool translucentBackground);
virtual QImage toImage() const;
- virtual GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, bool *needsSwizzle) const;
+ enum TextureFlag {
+ TextureSwizzle = 0x01,
+ TextureFlip = 0x02
+ };
+ Q_DECLARE_FLAGS(TextureFlags, TextureFlag)
+ virtual GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const;
#endif
virtual QPlatformGraphicsBuffer *graphicsBuffer() const;
@@ -130,6 +135,10 @@ private:
QPlatformBackingStorePrivate *d_ptr;
};
+#ifndef QT_NO_OPENGL
+Q_DECLARE_OPERATORS_FOR_FLAGS(QPlatformBackingStore::TextureFlags)
+#endif
+
QT_END_NAMESPACE
#endif // QPLATFORMBACKINGSTORE_H