summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2023-05-12 14:52:28 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2023-06-01 12:02:26 +0200
commit8c0b657c9a119cf60d96d36351ccf553e21ff3fc (patch)
tree30958de99b825511cbc90405b5e2640b2ce067de /src/widgets
parentda4de6b6e361879993f834ed4c157d5bdba2c050 (diff)
Refine the rhi-based flush logic
Amends 244daf4cfc44587c8c7c87e481688e840cc21c77 Fixes: QTBUG-113557 Fixes: QTBUG-113652 Task-number: QTBUG-108277 Pick-to: 6.5 Change-Id: I9e369b0e1261ea37eb2dedd80083f82f5df97b30 Reviewed-by: Andy Nichols <andy.nichols@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/kernel/qwidgetrepaintmanager.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/widgets/kernel/qwidgetrepaintmanager.cpp b/src/widgets/kernel/qwidgetrepaintmanager.cpp
index 718f904f93..3cc043ca42 100644
--- a/src/widgets/kernel/qwidgetrepaintmanager.cpp
+++ b/src/widgets/kernel/qwidgetrepaintmanager.cpp
@@ -1033,7 +1033,36 @@ void QWidgetRepaintManager::flush(QWidget *widget, const QRegion &region, QPlatf
if (widget != tlw)
offset += widget->mapTo(tlw, QPoint());
- if (tlw->d_func()->usesRhiFlush) {
+ // Use a condition that tries to keep both QTBUG-108344 and QTBUG-113557
+ // happy, i.e. support both (A) "native rhi-based child in a rhi-based
+ // toplevel" and (B) "native raster child in a rhi-based toplevel".
+ //
+ // If the tlw and the backingstore are RHI-based, then there are two cases
+ // to consider:
+ //
+ // (1) widget is not a native child, i.e. the QWindow for widget and tlw are
+ // the same,
+ //
+ // (2) widget is a native child which we now attempt to flush with tlw's
+ // backingstore to widget's native window. This is the interesting one.
+ //
+ // Using the condition tlw->usesRhiFlush on its own is insufficient since
+ // it fails to capture the case of a raster-based native child widget
+ // within tlw. (which must hit the non-rhi flush path)
+ //
+ // Extending the condition with tlw->windowHandle() == widget->windowHandle()
+ // would be logical but wrong, when it comes to (A) since flushing a
+ // RHI-based native child with a given 3D API using a RHI-based
+ // tlw/backingstore with the same 3D API needs to be supported still. (this
+ // happens when e.g. someone calls winId() on a QOpenGLWidget)
+ //
+ // Different 3D APIs do not need to be supported since we do not allow to
+ // do things like having a QQuickWidget with Vulkan and a QOpenGLWidget in
+ // the same toplevel, regardless of the widgets being native children or
+ // not. Hence comparing the surfaceType() instead. This satisfies both (A)
+ // and (B) given that an RHI-based toplevel cannot be RasterSurface.
+ //
+ if (tlw->d_func()->usesRhiFlush && tlw->windowHandle()->surfaceType() == widget->windowHandle()->surfaceType()) {
QRhi *rhi = store->handle()->rhi();
qCDebug(lcWidgetPainting) << "Flushing" << region << "of" << widget
<< "with QRhi" << rhi