Fix composition of render-to-texture widgets on big endian

Converting from QImage::Format_ARGB32 to QRhiTexture::RGBA8 requires
texture swizzling also on big endian.  But unlike on little endian it
is not a red/blue swap that is needed, but a rather rotation of the
alpha channel from the first component to the last.

Add a new swizzling mode to the backingstorecompose fragment shader,
and rename the uniform to reflect that it no longer covers only
red/blue swapping.

Pick-to: 6.4
Change-Id: I001d275abdc88faaadea16e396ebe032b34e83f0
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Marcus Comstedt 2022-07-24 23:15:42 +02:00
parent dcaa05f697
commit d2fcccd3f1
6 changed files with 23 additions and 13 deletions

View File

@ -71,9 +71,7 @@ QRhiTexture *QBackingStoreDefaultCompositor::toTexture(const QImage &sourceImage
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case QImage::Format_RGB32: case QImage::Format_RGB32:
case QImage::Format_ARGB32: case QImage::Format_ARGB32:
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
*flags |= QPlatformBackingStore::TextureSwizzle; *flags |= QPlatformBackingStore::TextureSwizzle;
#endif
break; break;
case QImage::Format_RGBA8888_Premultiplied: case QImage::Format_RGBA8888_Premultiplied:
*flags |= QPlatformBackingStore::TexturePremultiplied; *flags |= QPlatformBackingStore::TexturePremultiplied;
@ -378,14 +376,14 @@ void QBackingStoreDefaultCompositor::updatePerQuadData(PerQuadData *d, QRhiTextu
} }
void QBackingStoreDefaultCompositor::updateUniforms(PerQuadData *d, QRhiResourceUpdateBatch *resourceUpdates, void QBackingStoreDefaultCompositor::updateUniforms(PerQuadData *d, QRhiResourceUpdateBatch *resourceUpdates,
const QMatrix4x4 &target, const QMatrix3x3 &source, bool needsRedBlueSwap) const QMatrix4x4 &target, const QMatrix3x3 &source, UpdateUniformOption option)
{ {
resourceUpdates->updateDynamicBuffer(d->ubuf, 0, 64, target.constData()); resourceUpdates->updateDynamicBuffer(d->ubuf, 0, 64, target.constData());
updateMatrix3x3(resourceUpdates, d->ubuf, source); updateMatrix3x3(resourceUpdates, d->ubuf, source);
float opacity = 1.0f; float opacity = 1.0f;
resourceUpdates->updateDynamicBuffer(d->ubuf, 112, 4, &opacity); resourceUpdates->updateDynamicBuffer(d->ubuf, 112, 4, &opacity);
qint32 swapRedBlue = needsRedBlueSwap ? 1 : 0; qint32 textureSwizzle = static_cast<qint32>(option);
resourceUpdates->updateDynamicBuffer(d->ubuf, 116, 4, &swapRedBlue); resourceUpdates->updateDynamicBuffer(d->ubuf, 116, 4, &textureSwizzle);
} }
void QBackingStoreDefaultCompositor::ensureResources(QRhiSwapChain *swapchain, QRhiResourceUpdateBatch *resourceUpdates) void QBackingStoreDefaultCompositor::ensureResources(QRhiSwapChain *swapchain, QRhiResourceUpdateBatch *resourceUpdates)
@ -491,7 +489,11 @@ QPlatformBackingStore::FlushResult QBackingStoreDefaultCompositor::flush(QPlatfo
ensureResources(swapchain, resourceUpdates); ensureResources(swapchain, resourceUpdates);
const bool needsRedBlueSwap = (flags & QPlatformBackingStore::TextureSwizzle) != 0; #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
const UpdateUniformOption uniformOption = (flags & QPlatformBackingStore::TextureSwizzle) != 0? NeedsRedBlueSwap : NoOption;
#else
const UpdateUniformOption uniformOption = (flags & QPlatformBackingStore::TextureSwizzle) != 0? NeedsAlphaRotate : NoOption;
#endif
const bool premultiplied = (flags & QPlatformBackingStore::TexturePremultiplied) != 0; const bool premultiplied = (flags & QPlatformBackingStore::TexturePremultiplied) != 0;
SourceTransformOrigin origin = SourceTransformOrigin::TopLeft; SourceTransformOrigin origin = SourceTransformOrigin::TopLeft;
if (flags & QPlatformBackingStore::TextureFlip) if (flags & QPlatformBackingStore::TextureFlip)
@ -512,7 +514,7 @@ QPlatformBackingStore::FlushResult QBackingStoreDefaultCompositor::flush(QPlatfo
QMatrix4x4 target; // identity QMatrix4x4 target; // identity
if (invertTargetY) if (invertTargetY)
target.data()[5] = -1.0f; target.data()[5] = -1.0f;
updateUniforms(&m_widgetQuadData, resourceUpdates, target, source, needsRedBlueSwap); updateUniforms(&m_widgetQuadData, resourceUpdates, target, source, uniformOption);
} }
const int textureWidgetCount = textures->count(); const int textureWidgetCount = textures->count();
@ -538,7 +540,7 @@ QPlatformBackingStore::FlushResult QBackingStoreDefaultCompositor::flush(QPlatfo
m_textureQuadData[i] = createPerQuadData(t); m_textureQuadData[i] = createPerQuadData(t);
else else
updatePerQuadData(&m_textureQuadData[i], t); updatePerQuadData(&m_textureQuadData[i], t);
updateUniforms(&m_textureQuadData[i], resourceUpdates, target, source, false); updateUniforms(&m_textureQuadData[i], resourceUpdates, target, source, NoOption);
} else { } else {
m_textureQuadData[i].reset(); m_textureQuadData[i].reset();
} }

View File

@ -44,6 +44,12 @@ public:
bool translucentBackground); bool translucentBackground);
private: private:
enum UpdateUniformOption {
NoOption = 0x00,
NeedsRedBlueSwap = 0x01,
NeedsAlphaRotate = 0x02,
};
void ensureResources(QRhiSwapChain *swapchain, QRhiResourceUpdateBatch *resourceUpdates); void ensureResources(QRhiSwapChain *swapchain, QRhiResourceUpdateBatch *resourceUpdates);
QRhiTexture *toTexture(const QImage &image, QRhiTexture *toTexture(const QImage &image,
QRhi *rhi, QRhi *rhi,
@ -80,7 +86,7 @@ private:
PerQuadData createPerQuadData(QRhiTexture *texture); PerQuadData createPerQuadData(QRhiTexture *texture);
void updatePerQuadData(PerQuadData *d, QRhiTexture *texture); void updatePerQuadData(PerQuadData *d, QRhiTexture *texture);
void updateUniforms(PerQuadData *d, QRhiResourceUpdateBatch *resourceUpdates, void updateUniforms(PerQuadData *d, QRhiResourceUpdateBatch *resourceUpdates,
const QMatrix4x4 &target, const QMatrix3x3 &source, bool needsRedBlueSwap); const QMatrix4x4 &target, const QMatrix3x3 &source, UpdateUniformOption option);
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -7,7 +7,7 @@ layout(std140, binding = 0) uniform buf {
mat4 vertexTransform; mat4 vertexTransform;
mat3 textureTransform; mat3 textureTransform;
float opacity; float opacity;
int swapRedBlue; int textureSwizzle;
}; };
layout(binding = 1) uniform sampler2D textureSampler; layout(binding = 1) uniform sampler2D textureSampler;
@ -16,8 +16,10 @@ void main()
{ {
vec4 tmpFragColor = texture(textureSampler, v_texcoord); vec4 tmpFragColor = texture(textureSampler, v_texcoord);
tmpFragColor.a *= opacity; tmpFragColor.a *= opacity;
if (swapRedBlue == 0) if (textureSwizzle == 0)
fragColor = tmpFragColor; fragColor = tmpFragColor;
else if(textureSwizzle == 2)
fragColor.argb = tmpFragColor;
else else
fragColor = tmpFragColor.bgra; fragColor.bgra = tmpFragColor;
} }

View File

@ -9,7 +9,7 @@ layout(std140, binding = 0) uniform buf {
mat4 vertexTransform; mat4 vertexTransform;
mat3 textureTransform; mat3 textureTransform;
float opacity; float opacity;
int swapRedBlue; int textureSwizzle;
}; };
void main() void main()