From c0f16df6d8ddc66afd3528f18f20c65130df3de6 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sun, 6 Sep 2020 19:31:35 +0200 Subject: Shapes: only call update() when something changed Shapes has an unusual setup where changing properties (or properties of the Path objects) does not lead to calling update() on the Shape item. That's why it was done in updatePolish() but that can be made less heavy by only doing it when the shape found that something got changed. Task-number: QTBUG-86089 Change-Id: I74f708a960a29f26eb003ac160d2b1258b9ae50f Reviewed-by: Andy Nichols --- src/quickshapes/qquickshape.cpp | 16 +++++++++++----- src/quickshapes/qquickshape_p_p.h | 2 +- src/quickshapes/qquickshapegenericrenderer.cpp | 5 ++++- src/quickshapes/qquickshapegenericrenderer_p.h | 2 +- src/quickshapes/qquickshapesoftwarerenderer.cpp | 5 ++++- src/quickshapes/qquickshapesoftwarerenderer_p.h | 2 +- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/quickshapes/qquickshape.cpp b/src/quickshapes/qquickshape.cpp index 4600e3ead7..db51a33a47 100644 --- a/src/quickshapes/qquickshape.cpp +++ b/src/quickshapes/qquickshape.cpp @@ -938,8 +938,6 @@ void QQuickShape::updatePolish() // when the item is visible. if (isVisible() || d->effectRefCount > 0) d->sync(); - - update(); } void QQuickShape::itemChange(ItemChange change, const ItemChangeData &data) @@ -1038,7 +1036,7 @@ void QQuickShapePrivate::asyncShapeReady(void *data) void QQuickShapePrivate::sync() { - syncTimingTotalDirty = 0; + int totalDirty = 0; syncTimingActive = QQSHAPE_LOG_TIME_DIRTY_SYNC().isDebugEnabled(); if (syncTimingActive) syncTimer.start(); @@ -1050,12 +1048,13 @@ void QQuickShapePrivate::sync() } const int count = sp.count(); - renderer->beginSync(count); + bool countChanged = false; + renderer->beginSync(count, &countChanged); for (int i = 0; i < count; ++i) { QQuickShapePath *p = sp[i]; int &dirty(QQuickShapePathPrivate::get(p)->dirty); - syncTimingTotalDirty |= dirty; + totalDirty |= dirty; if (dirty & QQuickShapePathPrivate::DirtyPath) renderer->setPath(i, p); @@ -1079,6 +1078,7 @@ void QQuickShapePrivate::sync() dirty = 0; } + syncTimingTotalDirty = totalDirty; if (syncTimingTotalDirty) ++syncTimeCounter; else @@ -1092,6 +1092,12 @@ void QQuickShapePrivate::sync() qDebug("[Shape %p] [%d] [dirty=0x%x] update took %lld ms", q_func(), syncTimeCounter, syncTimingTotalDirty, syncTimer.elapsed()); } + + // Must dirty the QQuickItem if something got changed, nothing + // else does this for us. + Q_Q(QQuickShape); + if (totalDirty || countChanged) + q->update(); } // ***** gradient support ***** diff --git a/src/quickshapes/qquickshape_p_p.h b/src/quickshapes/qquickshape_p_p.h index 3a76f0996b..82aafade87 100644 --- a/src/quickshapes/qquickshape_p_p.h +++ b/src/quickshapes/qquickshape_p_p.h @@ -86,7 +86,7 @@ public: virtual ~QQuickAbstractPathRenderer() { } // Gui thread - virtual void beginSync(int totalCount) = 0; + virtual void beginSync(int totalCount, bool *countChanged) = 0; virtual void endSync(bool async) = 0; virtual void setAsyncCallback(void (*)(void *), void *) { } virtual Flags flags() const { return {}; } diff --git a/src/quickshapes/qquickshapegenericrenderer.cpp b/src/quickshapes/qquickshapegenericrenderer.cpp index 16831d59d3..c1cadb82ef 100644 --- a/src/quickshapes/qquickshapegenericrenderer.cpp +++ b/src/quickshapes/qquickshapegenericrenderer.cpp @@ -122,11 +122,14 @@ QQuickShapeGenericRenderer::~QQuickShapeGenericRenderer() // sync, and so triangulation too, happens on the gui thread // - except when async is set, in which case triangulation is moved to worker threads -void QQuickShapeGenericRenderer::beginSync(int totalCount) +void QQuickShapeGenericRenderer::beginSync(int totalCount, bool *countChanged) { if (m_sp.count() != totalCount) { m_sp.resize(totalCount); m_accDirty |= DirtyList; + *countChanged = true; + } else { + *countChanged = false; } for (ShapePathData &d : m_sp) d.syncDirty = 0; diff --git a/src/quickshapes/qquickshapegenericrenderer_p.h b/src/quickshapes/qquickshapegenericrenderer_p.h index 16b3dd9430..9cdf44546e 100644 --- a/src/quickshapes/qquickshapegenericrenderer_p.h +++ b/src/quickshapes/qquickshapegenericrenderer_p.h @@ -88,7 +88,7 @@ public: { } ~QQuickShapeGenericRenderer(); - void beginSync(int totalCount) override; + void beginSync(int totalCount, bool *countChanged) override; void setPath(int index, const QQuickPath *path) override; void setStrokeColor(int index, const QColor &color) override; void setStrokeWidth(int index, qreal w) override; diff --git a/src/quickshapes/qquickshapesoftwarerenderer.cpp b/src/quickshapes/qquickshapesoftwarerenderer.cpp index d6a9d85643..dc9ccb340d 100644 --- a/src/quickshapes/qquickshapesoftwarerenderer.cpp +++ b/src/quickshapes/qquickshapesoftwarerenderer.cpp @@ -42,11 +42,14 @@ QT_BEGIN_NAMESPACE -void QQuickShapeSoftwareRenderer::beginSync(int totalCount) +void QQuickShapeSoftwareRenderer::beginSync(int totalCount, bool *countChanged) { if (m_sp.count() != totalCount) { m_sp.resize(totalCount); m_accDirty |= DirtyList; + *countChanged = true; + } else { + *countChanged = false; } } diff --git a/src/quickshapes/qquickshapesoftwarerenderer_p.h b/src/quickshapes/qquickshapesoftwarerenderer_p.h index 11e658b4b7..dcee8daa8c 100644 --- a/src/quickshapes/qquickshapesoftwarerenderer_p.h +++ b/src/quickshapes/qquickshapesoftwarerenderer_p.h @@ -72,7 +72,7 @@ public: DirtyList = 0x10 }; - void beginSync(int totalCount) override; + void beginSync(int totalCount, bool *countChanged) override; void setPath(int index, const QQuickPath *path) override; void setStrokeColor(int index, const QColor &color) override; void setStrokeWidth(int index, qreal w) override; -- cgit v1.2.3