From 1937a4e8b9b729e62426ce3018cc0a96a0c40972 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 23 May 2016 12:41:01 +0200 Subject: Add a workaround for render-to-texture widgets in fullscreen windows The performance optimization of falling back to flushing windows the normal (raster) way once no render-to-texture widgets are visible has issues with fullscreen windows, presumably due to the compositor's special handling of such windows. Disable our smartness and stick with composeAndFlush for ever in case the window is fullscreen. Change-Id: Ifb31e0d36bd0a3933fcfe55a9a7d502513d6e3cf Task-number: QTBUG-53515 Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidgetbackingstore.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/widgets/kernel/qwidgetbackingstore.cpp') diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 8269bd13f6..049ed248de 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1000,8 +1000,18 @@ static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget) static bool switchableWidgetComposition = QGuiApplicationPrivate::instance()->platformIntegration() ->hasCapability(QPlatformIntegration::SwitchableWidgetComposition); - if (!switchableWidgetComposition) + if (!switchableWidgetComposition +// The Windows compositor handles fullscreen OpenGL window specially. Besides +// having trouble with popups, it also has issues with flip-flopping between +// OpenGL-based and normal flushing. Therefore, stick with GL for fullscreen +// windows. (QTBUG-53515) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) + || tlw->windowState().testFlag(Qt::WindowFullScreen) +#endif + ) + { return qt_dummy_platformTextureList(); + } } return 0; -- cgit v1.2.3 From 00061b968d23d34cdbd43e0930463be06a2775b3 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Mon, 25 Apr 2016 15:43:57 +0200 Subject: Fix opaque texture-based widgets not being always shown. Whenever a regular QWidget contains a child render-to-texture widget (like a QOpenGLWidget) that is opaque (attribute Qt::WA_OpaquePaintEvent is set) and completely covers the parent geometry, the child widget would not be shown. This happens because QWidgetBackingStore::doSync contains a check to see if an opaque child completely covers its parent, in which case it does not draw the parent, and only draws the child. This is an issue if the widget is actually a texture-based one, because for it to be seen on screen, the parent widget has to be redrawn with a proper blending mask, so that the rtt widget gets properly composed into the place where the mask is. The fix consists in keeping the parent widget being marked dirty, in case it has an opaque texture-based child that completely covers it. This will force a redraw of the parent widget with a proper blending mask. Change-Id: If1feec04b86bff2c49158b8d72f175cec252dea1 Task-number: QTBUG-52123 Reviewed-by: Allan Sandfeld Jensen --- src/widgets/kernel/qwidgetbackingstore.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/widgets/kernel/qwidgetbackingstore.cpp') diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 049ed248de..5d13fb926b 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1211,10 +1211,20 @@ void QWidgetBackingStore::doSync() // We know for sure that the widget isn't overlapped if 'isMoved' is true. if (!wd->isMoved) wd->subtractOpaqueSiblings(wd->dirty, &hasDirtySiblingsAbove); + + // Make a copy of the widget's dirty region, to restore it in case there is an opaque + // render-to-texture child that completely covers the widget, because otherwise the + // render-to-texture child won't be visible, due to its parent widget not being redrawn + // with a proper blending mask. + const QRegion dirtyBeforeSubtractedOpaqueChildren = wd->dirty; + // Scrolled and moved widgets must draw all children. if (!wd->isScrolled && !wd->isMoved) wd->subtractOpaqueChildren(wd->dirty, w->rect()); + if (wd->dirty.isEmpty() && wd->textureChildSeen) + wd->dirty = dirtyBeforeSubtractedOpaqueChildren; + if (wd->dirty.isEmpty()) { resetWidget(w); continue; -- cgit v1.2.3