From 2672a9a767909eab04ec6706bdef8a891a8f3d21 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 7 Oct 2018 20:36:05 +0200 Subject: [PATCH] QWidget: set brushOrigin in paintBackground() only when really needed When painting the background for a QAbstractScrollArea, the brushOrigin was calculated for every brush type although it was not needed. Since this can be very time consuming (e.g for a QTreeView with non-uniform row sizes) it should be avoided when possible. Therefore check if the brush is a texture and skip the calculation if it is not the case. Also do not restore the old brushOrigin since the painter is not used at all afterwards. Task-number: QTBUG-61763 Change-Id: I66cbe1b796cb5cad4c78e656fb86d199d8e4bde9 Reviewed-by: Eirik Aavitsland Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 31 +++++++++++++++++-------------- src/widgets/kernel/qwidget_p.h | 1 + 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 6753c35cfc..ca4f958c14 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -2416,29 +2416,34 @@ static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrus } } -void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const +bool QWidgetPrivate::updateBrushOrigin(QPainter *painter, const QBrush &brush) const { - Q_Q(const QWidget); - #if QT_CONFIG(scrollarea) - bool resetBrushOrigin = false; - QPointF oldBrushOrigin; + Q_Q(const QWidget); //If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture + if (brush.style() == Qt::NoBrush || brush.style() == Qt::SolidPattern) + return false; QAbstractScrollArea *scrollArea = qobject_cast(parent); if (scrollArea && scrollArea->viewport() == q) { QObjectData *scrollPrivate = static_cast(scrollArea)->d_ptr.data(); QAbstractScrollAreaPrivate *priv = static_cast(scrollPrivate); - oldBrushOrigin = painter->brushOrigin(); - resetBrushOrigin = true; painter->setBrushOrigin(-priv->contentsOffset()); - } #endif // QT_CONFIG(scrollarea) + return true; +} +void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const +{ + Q_Q(const QWidget); + + bool brushOriginSet = false; const QBrush autoFillBrush = q->palette().brush(q->backgroundRole()); if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) { const QBrush bg = q->palette().brush(QPalette::Window); + if (!brushOriginSet) + brushOriginSet = updateBrushOrigin(painter, bg); if (!(flags & DontSetCompositionMode)) { //copy alpha straight in QPainter::CompositionMode oldMode = painter->compositionMode(); @@ -2450,8 +2455,11 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int } } - if (q->autoFillBackground()) + if (q->autoFillBackground()) { + if (!brushOriginSet) + brushOriginSet = updateBrushOrigin(painter, autoFillBrush); fillRegion(painter, rgn, autoFillBrush); + } if (q->testAttribute(Qt::WA_StyledBackground)) { painter->setClipRegion(rgn); @@ -2459,11 +2467,6 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int opt.initFrom(q); q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q); } - -#if QT_CONFIG(scrollarea) - if (resetBrushOrigin) - painter->setBrushOrigin(oldBrushOrigin); -#endif // QT_CONFIG(scrollarea) } /* diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 20c4a682ed..c8eaabf8e2 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -400,6 +400,7 @@ public: void setUpdatesEnabled_helper(bool ); + bool updateBrushOrigin(QPainter *, const QBrush &brush) const; void paintBackground(QPainter *, const QRegion &, int flags = DrawAsRoot) const; bool isAboutToShow() const; QRegion prepareToRender(const QRegion ®ion, QWidget::RenderFlags renderFlags);