summaryrefslogtreecommitdiffstats
path: root/src/widgets/kernel
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2016-06-22 10:08:28 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2016-06-28 06:48:39 +0000
commit2a7cee47e5e84c73e32a6953e145771196645f1a (patch)
tree29b34b1f84170afc6cd099fcba8cd32ce7e54f9f /src/widgets/kernel
parentfe9ca6ede8ee9817868ae5aac8c3f8b4480e9aea (diff)
Avoid artifacts when hiding or closing a QOpenGLWidget or QQuickWidget child
windows and xcb enables SwitchableWidgetComposition meaning that widget backing stores will fall back to the normal flush path when no render-to-texture widgets are visible anymore in the window. This switch however can lead to artifacts with the image of the rtt widget remaining visible until the next full bacinkgstore sync. The safe and simple way around this is to do the switch only in the next flush, keeping the flush where the switch is discovered on the OpenGL-based composition path still. Task-number: QTBUG-54241 Change-Id: I1d3f10999f69c58efa791dd724891add56949dee Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r--src/widgets/kernel/qwidget.cpp1
-rw-r--r--src/widgets/kernel/qwidget_p.h1
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp18
3 files changed, 18 insertions, 2 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 0376ab88ac..57148eb811 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -274,6 +274,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
#endif
#ifndef QT_NO_OPENGL
, renderToTextureReallyDirty(1)
+ , renderToTextureComposeActive(0)
#endif
#if defined(Q_OS_WIN)
, noPaintOnScreen(0)
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 9d4bdc7f89..9681cb03ec 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -744,6 +744,7 @@ public:
#endif
#ifndef QT_NO_OPENGL
uint renderToTextureReallyDirty : 1;
+ uint renderToTextureComposeActive : 1;
#endif
// *************************** Platform specific ************************************
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 5d13fb926b..7473dd1dfb 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -61,6 +61,8 @@ QT_BEGIN_NAMESPACE
extern QRegion qt_dirtyRegion(QWidget *);
+Q_GLOBAL_STATIC(QPlatformTextureList, qt_dummy_platformTextureList)
+
/**
* Flushes the contents of the \a backingStore into the screen area of \a widget.
* \a tlwOffset is the position of the top level widget relative to the window surface.
@@ -103,6 +105,20 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion &region, QBack
offset += widget->mapTo(tlw, QPoint());
#ifndef QT_NO_OPENGL
+ const bool compositionWasActive = widget->d_func()->renderToTextureComposeActive;
+ if (!widgetTextures) {
+ widget->d_func()->renderToTextureComposeActive = false;
+ // Detect the case of falling back to the normal flush path when no
+ // render-to-texture widgets are visible anymore. We will force one
+ // last flush to go through the OpenGL-based composition to prevent
+ // artifacts. The next flush after this one will use the normal path.
+ if (compositionWasActive)
+ widgetTextures = qt_dummy_platformTextureList;
+ } else {
+ widget->d_func()->renderToTextureComposeActive = true;
+ }
+
+ // re-test since we may have been forced to this path via the dummy texture list above
if (widgetTextures) {
qt_window_private(tlw->windowHandle())->compositing = true;
widget->window()->d_func()->sendComposeStatus(widget->window(), false);
@@ -978,8 +994,6 @@ static void findAllTextureWidgetsRecursively(QWidget *tlw, QWidget *widget)
}
}
-Q_GLOBAL_STATIC(QPlatformTextureList, qt_dummy_platformTextureList)
-
static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget)
{
foreach (QPlatformTextureList *tl, QWidgetPrivate::get(tlw)->topData()->widgetTextures) {