Fix alpha channel logic in QRhiBackingStore

Mirror what other platforms such as Windows or xcb do.

Those all unconditionally upgrade a non-alpha format such as RGB32 to
something like ARGB32_Premultiplied (or whatever
qt_maybeAlphaVersionWithSameDepth returns).

Without this, there is a discrepancy between macOS and the other
platforms when using QOpenGLWidget or QQuickWidget (which trigger
the usage of QRhiBackingStore).

For example, attempting to have semi-transparent raster widget content
over the RHI-based widgets will render incorrectly. This is visible in
6.7 (dev) with the cuberhiwidget example as well: the red
semi-transparent overlay is rendered incorrectly on macOS since
QRhiBackingStore sticking with a QImage of RGB32 has far-reaching
consequences.

Upgrading to an alpha format is also required by the "hole punching"
mechanism the texture-based widget system relies on, although there is
a suspicion that that just happens to look correct with RGB32 as well
since there is an alpha channel technically with that format, and alpha
writes may not be masked out, depending on painting internals, ending
up with RGBA content in practice.
But in other cases, like in the report and the one mentioned above
this clearly breaks down.

Fixes: QTBUG-118553
Pick-to: 6.5
Change-Id: I4b5b7a4f720377d64903e948b866f8d1c443a2d2
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit aa4fe3286d50e05bf7d521ad8d579062f250bd0a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Laszlo Agocs 2023-10-27 11:09:18 +02:00 committed by Qt Cherry-pick Bot
parent b808b7004c
commit aecd210c75
2 changed files with 15 additions and 0 deletions

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qrhibackingstore_p.h"
#include <private/qimage_p.h>
QT_BEGIN_NAMESPACE
@ -43,4 +44,17 @@ void QRhiBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
rhiFlush(window, window->devicePixelRatio(), region, offset, &emptyTextureList, translucentBackground);
}
QImage::Format QRhiBackingStore::format() const
{
QImage::Format fmt = QRasterBackingStore::format();
// With render-to-texture widgets and QRhi-based flushing the backingstore
// image must have an alpha channel. Hence upgrading the format. Matches
// what other platforms (Windows, xcb) do.
if (QImage::toPixelFormat(fmt).alphaUsage() != QPixelFormat::UsesAlpha)
fmt = qt_maybeAlphaVersionWithSameDepth(fmt);
return fmt;
}
QT_END_NAMESPACE

View File

@ -26,6 +26,7 @@ public:
~QRhiBackingStore();
void flush(QWindow *window, const QRegion &region, const QPoint &offset) override;
QImage::Format format() const override;
};
QT_END_NAMESPACE