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>bb10
parent
4a4faedc3d
commit
39e3977cc5
|
|
@ -308,7 +308,11 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i
|
|||
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 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 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 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())
|
||||
return 0;
|
||||
|
||||
bool resized = d_ptr->textureSize != imageSize;
|
||||
*flags = 0;
|
||||
if (image.format() == QImage::Format_RGB32)
|
||||
*flags |= TextureSwizzle;
|
||||
|
||||
if (imageSize.isEmpty()) {
|
||||
*textureSize = imageSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue