From c937f80fe5f8c13ef99882ba96b11fbea0cba156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 21 Aug 2019 15:01:30 +0200 Subject: [PATCH] widgets: Simplify QWidgetRepaintManager::qt_flush No longer static, so we can access the members directly instead of passing them as arguments. Renamed to flush() while we're at it. Otherwise no changes to the code, just moved the function. Change-Id: Id491a8628c8cecf7cf3b33d3458e7427f5bcd22e Reviewed-by: Paul Olav Tvete --- src/widgets/kernel/qwidgetrepaintmanager.cpp | 170 +++++++++---------- src/widgets/kernel/qwidgetrepaintmanager_p.h | 5 +- 2 files changed, 85 insertions(+), 90 deletions(-) diff --git a/src/widgets/kernel/qwidgetrepaintmanager.cpp b/src/widgets/kernel/qwidgetrepaintmanager.cpp index 3cdb6d9efa..65c07c7648 100644 --- a/src/widgets/kernel/qwidgetrepaintmanager.cpp +++ b/src/widgets/kernel/qwidgetrepaintmanager.cpp @@ -76,84 +76,6 @@ static bool hasPlatformWindow(QWidget *widget) return widget && widget->windowHandle() && widget->windowHandle()->handle(); } -/** - * Flushes the contents of the \a backingStore into the screen area of \a widget. - * \a region is the region to be updated in \a widget coordinates. - */ -void QWidgetRepaintManager::qt_flush(QWidget *widget, const QRegion ®ion, QBackingStore *backingStore, - QWidget *tlw, QPlatformTextureList *widgetTextures, - QWidgetRepaintManager *repaintManager) -{ -#ifdef QT_NO_OPENGL - Q_UNUSED(widgetTextures); - Q_ASSERT(!region.isEmpty()); -#else - Q_ASSERT(!region.isEmpty() || widgetTextures); -#endif - Q_ASSERT(widget); - Q_ASSERT(backingStore); - Q_ASSERT(tlw); - - if (tlw->testAttribute(Qt::WA_DontShowOnScreen) || widget->testAttribute(Qt::WA_DontShowOnScreen)) - return; - - // Foreign Windows do not have backing store content and must not be flushed - if (QWindow *widgetWindow = widget->windowHandle()) { - if (widgetWindow->type() == Qt::ForeignWindow) - return; - } - - static bool fpsDebug = qEnvironmentVariableIntValue("QT_DEBUG_FPS"); - if (fpsDebug) { - if (!repaintManager->perfFrames++) - repaintManager->perfTime.start(); - if (repaintManager->perfTime.elapsed() > 5000) { - double fps = double(repaintManager->perfFrames * 1000) / repaintManager->perfTime.restart(); - qDebug("FPS: %.1f\n", fps); - repaintManager->perfFrames = 0; - } - } - - QPoint offset; - if (widget != tlw) - offset += widget->mapTo(tlw, QPoint()); - - QRegion effectiveRegion = region; -#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; - } - // When changing the composition status, make sure the dirty region covers - // the entire widget. Just having e.g. the shown/hidden render-to-texture - // widget's area marked as dirty is incorrect when changing flush paths. - if (compositionWasActive != widget->d_func()->renderToTextureComposeActive) - effectiveRegion = widget->rect(); - - // 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); - // A window may have alpha even when the app did not request - // WA_TranslucentBackground. Therefore the compositor needs to know whether the app intends - // to rely on translucency, in order to decide if it should clear to transparent or opaque. - const bool translucentBackground = widget->testAttribute(Qt::WA_TranslucentBackground); - backingStore->handle()->composeAndFlush(widget->windowHandle(), effectiveRegion, offset, - widgetTextures, translucentBackground); - widget->window()->d_func()->sendComposeStatus(widget->window(), true); - } else -#endif - backingStore->flush(effectiveRegion, widget->windowHandle(), offset); -} - /* Moves the whole rect by (dx, dy) in widget's coordinate system. Doesn't generate any updates. @@ -913,8 +835,8 @@ void QWidgetRepaintManager::sync(QWidget *exposedWidget, const QRegion &exposedR // Nothing to repaint. if (!isDirty() && store->size().isValid()) { - QPlatformTextureList *tl = widgetTexturesFor(tlw, exposedWidget); - qt_flush(exposedWidget, tl ? QRegion() : exposedRegion, store, tlw, tl, this); + QPlatformTextureList *widgetTextures = widgetTexturesFor(tlw, exposedWidget); + flush(exposedWidget, widgetTextures ? QRegion() : exposedRegion, widgetTextures); return; } @@ -1054,7 +976,7 @@ void QWidgetRepaintManager::doSync() QTLWExtra *tlwExtra = tlw->d_func()->topData(); tlwExtra->widgetTextures.clear(); findAllTextureWidgetsRecursively(tlw, tlw); - qt_window_private(tlw->windowHandle())->compositing = false; // will get updated in qt_flush() + qt_window_private(tlw->windowHandle())->compositing = false; // will get updated in flush() #endif if (toClean.isEmpty()) { @@ -1177,7 +1099,7 @@ void QWidgetRepaintManager::flush(QWidget *widget) // Flush the region in dirtyOnScreen. if (!dirtyOnScreen.isEmpty()) { QWidget *target = widget ? widget : tlw; - qt_flush(target, dirtyOnScreen, store, tlw, widgetTexturesFor(tlw, tlw), this); + flush(target, dirtyOnScreen, widgetTexturesFor(tlw, tlw)); dirtyOnScreen = QRegion(); flushed = true; } @@ -1186,10 +1108,10 @@ void QWidgetRepaintManager::flush(QWidget *widget) if (!flushed && !hasDirtyOnScreenWidgets) { #ifndef QT_NO_OPENGL if (!tlw->d_func()->topData()->widgetTextures.empty()) { - QPlatformTextureList *tl = widgetTexturesFor(tlw, tlw); - if (tl) { + QPlatformTextureList *widgetTextures = widgetTexturesFor(tlw, tlw); + if (widgetTextures) { QWidget *target = widget ? widget : tlw; - qt_flush(target, QRegion(), store, tlw, tl, this); + flush(target, QRegion(), widgetTextures); } } #endif @@ -1202,11 +1124,87 @@ void QWidgetRepaintManager::flush(QWidget *widget) QWidgetPrivate *wd = w->d_func(); Q_ASSERT(wd->needsFlush); QPlatformTextureList *widgetTexturesForNative = wd->textureChildSeen ? widgetTexturesFor(tlw, w) : 0; - qt_flush(w, *wd->needsFlush, store, tlw, widgetTexturesForNative, this); + flush(w, *wd->needsFlush, widgetTexturesForNative); *wd->needsFlush = QRegion(); } } +/* + Flushes the contents of the backingstore into the screen area of \a widget. + + \a region is the region to be updated in \a widget coordinates. + */ +void QWidgetRepaintManager::flush(QWidget *widget, const QRegion ®ion, QPlatformTextureList *widgetTextures) +{ +#ifdef QT_NO_OPENGL + Q_UNUSED(widgetTextures); + Q_ASSERT(!region.isEmpty()); +#else + Q_ASSERT(!region.isEmpty() || widgetTextures); +#endif + Q_ASSERT(widget); + Q_ASSERT(tlw); + + if (tlw->testAttribute(Qt::WA_DontShowOnScreen) || widget->testAttribute(Qt::WA_DontShowOnScreen)) + return; + + // Foreign Windows do not have backing store content and must not be flushed + if (QWindow *widgetWindow = widget->windowHandle()) { + if (widgetWindow->type() == Qt::ForeignWindow) + return; + } + + static bool fpsDebug = qEnvironmentVariableIntValue("QT_DEBUG_FPS"); + if (fpsDebug) { + if (!perfFrames++) + perfTime.start(); + if (perfTime.elapsed() > 5000) { + double fps = double(perfFrames * 1000) / perfTime.restart(); + qDebug("FPS: %.1f\n", fps); + perfFrames = 0; + } + } + + QPoint offset; + if (widget != tlw) + offset += widget->mapTo(tlw, QPoint()); + + QRegion effectiveRegion = region; +#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; + } + // When changing the composition status, make sure the dirty region covers + // the entire widget. Just having e.g. the shown/hidden render-to-texture + // widget's area marked as dirty is incorrect when changing flush paths. + if (compositionWasActive != widget->d_func()->renderToTextureComposeActive) + effectiveRegion = widget->rect(); + + // 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); + // A window may have alpha even when the app did not request + // WA_TranslucentBackground. Therefore the compositor needs to know whether the app intends + // to rely on translucency, in order to decide if it should clear to transparent or opaque. + const bool translucentBackground = widget->testAttribute(Qt::WA_TranslucentBackground); + store->handle()->composeAndFlush(widget->windowHandle(), effectiveRegion, offset, + widgetTextures, translucentBackground); + widget->window()->d_func()->sendComposeStatus(widget->window(), true); + } else +#endif + store->flush(effectiveRegion, widget->windowHandle(), offset); +} + /*! Invalidates the backing store when the widget is resized. Static areas are never invalidated unless absolutely needed. diff --git a/src/widgets/kernel/qwidgetrepaintmanager_p.h b/src/widgets/kernel/qwidgetrepaintmanager_p.h index 482cae4020..0620ab99e2 100644 --- a/src/widgets/kernel/qwidgetrepaintmanager_p.h +++ b/src/widgets/kernel/qwidgetrepaintmanager_p.h @@ -131,10 +131,7 @@ private: void sendUpdateRequest(QWidget *widget, UpdateTime updateTime); - static void qt_flush(QWidget *widget, const QRegion ®ion, QBackingStore *backingStore, - QWidget *tlw, - QPlatformTextureList *widgetTextures, - QWidgetRepaintManager *repaintManager); + void flush(QWidget *widget, const QRegion ®ion, QPlatformTextureList *widgetTextures); void doSync(); bool bltRect(const QRect &rect, int dx, int dy, QWidget *widget);