diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-06-03 12:34:54 (GMT) |
---|---|---|
committer | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-06-09 07:32:36 (GMT) |
commit | 33473417a73cafa0c0d9283c00b1e716becba0e1 (patch) | |
tree | 8bb36d6b2d94394dcd16bd35eac359283a6dc1da /src/gui/graphicsview | |
parent | 31a7de5cbecad8f5cc106c8886c79c63f07c9b5a (diff) | |
download | Qt-33473417a73cafa0c0d9283c00b1e716becba0e1.zip Qt-33473417a73cafa0c0d9283c00b1e716becba0e1.tar.gz Qt-33473417a73cafa0c0d9283c00b1e716becba0e1.tar.bz2 |
Speed up processing of dirty items when ancestor clips children.
This patch also contains a bug fix where a child item didn't
update due to a bit not being properly set. No more rendering
artifacts :)
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 33 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene_p.h | 2 |
2 files changed, 28 insertions, 7 deletions
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index f8b3b0a..ec0e87b 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5255,7 +5255,7 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b } } -void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item) +void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren) { Q_ASSERT(!item || item->d_ptr->dirty || item->d_ptr->dirtyChildren); Q_Q(QGraphicsScene); @@ -5271,7 +5271,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item) } // Process item. - if (item && item->d_ptr->dirty) { + if (item && (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint)) { const bool useCompatUpdate = views.isEmpty() || (connectedSignals & changedSignalMask); if (useCompatUpdate && !item->d_ptr->itemIsUntransformable() && qFuzzyIsNull(item->boundingRegionGranularity())) { @@ -5300,6 +5300,12 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item) break; } + if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) + viewPrivate->updateRect(item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport)); + + if (!item->d_ptr->dirty) + continue; + if (uninitializedDirtyRect) { dirtyRect = adjustedItemBoundingRect(item); if (!item->d_ptr->fullUpdatePending) { @@ -5309,9 +5315,6 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item) uninitializedDirtyRect = false; } - if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) - viewPrivate->updateRect(item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport)); - QTransform deviceTransform = item->d_ptr->sceneTransform; if (view->isTransformed()) { if (!untransformableItem) @@ -5331,17 +5334,35 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item) if (!item || item->d_ptr->dirtyChildren) { QList<QGraphicsItem *> *children = item ? &item->d_ptr->children : &topLevelItems; const bool allChildrenDirty = item && item->d_ptr->allChildrenDirty; + if (!dirtyAncestorContainsChildren) { + dirtyAncestorContainsChildren = item && item->d_ptr->fullUpdatePending + && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); + } for (int i = 0; i < children->size(); ++i) { QGraphicsItem *child = children->at(i); if (wasDirtyParentSceneTransform) child->d_ptr->dirtySceneTransform = 1; + if (allChildrenDirty) { child->d_ptr->dirty = 1; + child->d_ptr->fullUpdatePending = 1; + child->d_ptr->dirtyChildren = 1; + child->d_ptr->allChildrenDirty = 1; } else if (!child->d_ptr->dirty && !child->d_ptr->dirtyChildren) { resetDirtyItem(child); continue; } - processDirtyItemsRecursive(child); + + if (dirtyAncestorContainsChildren) { + // No need to process this child's dirty rect, hence reset the dirty state. + // However, we have to continue the recursion because it might have a dirty + // view bounding rect that needs repaint. We also have to reset the dirty + // state of its descendants. + child->d_ptr->dirty = 0; + child->d_ptr->fullUpdatePending = 0; + } + + processDirtyItemsRecursive(child, dirtyAncestorContainsChildren); } } else if (wasDirtyParentSceneTransform) { item->d_ptr->invalidateChildrenSceneTransform(); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 8bc25b6..f4964f2 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -263,7 +263,7 @@ public: QList<QGraphicsItem *> *topLevelItems = 0, qreal parentOpacity = qreal(1.0)); void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false, bool maybeDirtyClipPath = false, bool force = false, bool ignoreOpacity = false); - void processDirtyItemsRecursive(QGraphicsItem *item); + void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false); inline void resetDirtyItem(QGraphicsItem *item) { |