diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-11-25 09:27:25 (GMT) |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-11-25 18:10:12 (GMT) |
commit | aae664552f7e5fba96ab6f334ec354800ad83c06 (patch) | |
tree | 1f751ae1f2a7bab8d624c65d333fedf62f2e3079 | |
parent | dab1b98d84293e863c920add25980393fad2e9cd (diff) | |
download | Qt-aae664552f7e5fba96ab6f334ec354800ad83c06.zip Qt-aae664552f7e5fba96ab6f334ec354800ad83c06.tar.gz Qt-aae664552f7e5fba96ab6f334ec354800ad83c06.tar.bz2 |
Remove caching of QGraphicsItem::clipPath().
The cache was added in 4.5 and was useful at that time. With 4.6
it is not relevant anymore since the only use case for it is item-lookup
releated to mouse events and collision detection, so the overhead of
maintaining the cache is more pain than gain.
All existing auto tests pass.
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 165 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 32 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget.cpp | 2 |
3 files changed, 8 insertions, 191 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 710048e..a42c1c3 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -755,7 +755,6 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch case QGraphicsItem::ItemClipsChildrenToShape: flag = AncestorClipsChildren; enabled = flags & QGraphicsItem::ItemClipsChildrenToShape; - invalidateCachedClipPathRecursively(/*childrenOnly=*/true); break; case QGraphicsItem::ItemIgnoresTransformations: flag = AncestorIgnoresTransformations; @@ -1732,9 +1731,6 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->updateAncestorFlag(ItemClipsChildrenToShape); } - if ((flags & ItemClipsToShape) != (oldFlags & ItemClipsToShape)) - d_ptr->invalidateCachedClipPath(); - if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) { // Item children clipping changes. Propagate the ancestor flag to // all children. @@ -3399,7 +3395,6 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos) { Q_Q(QGraphicsItem); inSetPosHelper = 1; - updateCachedClipPathFromSetPosHelper(pos); if (scene) q->prepareGeometryChange(); QPointF oldPos = this->pos; @@ -4535,22 +4530,12 @@ bool QGraphicsItem::isClipped() const QPainterPath QGraphicsItem::clipPath() const { Q_D(const QGraphicsItem); - if (!d->dirtyClipPath) - return d->emptyClipPath ? QPainterPath() : d->cachedClipPath; - - if (!isClipped()) { - d_ptr->setCachedClipPath(QPainterPath()); - return d->cachedClipPath; - } + if (!isClipped()) + return QPainterPath(); const QRectF thisBoundingRect(boundingRect()); - if (thisBoundingRect.isEmpty()) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); + if (thisBoundingRect.isEmpty()) return QPainterPath(); - } QPainterPath clip; // Start with the item's bounding rect. @@ -4561,40 +4546,18 @@ QPainterPath QGraphicsItem::clipPath() const const QGraphicsItem *lastParent = this; // Intersect any in-between clips starting at the top and moving downwards. - bool foundValidClipPath = false; while ((parent = parent->d_ptr->parent)) { if (parent->d_ptr->flags & ItemClipsChildrenToShape) { // Map clip to the current parent and intersect with its shape/clipPath clip = lastParent->itemTransform(parent).map(clip); - if ((foundValidClipPath = !parent->d_ptr->dirtyClipPath && parent->isClipped())) { - if (parent->d_ptr->emptyClipPath) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); - return QPainterPath(); - } - clip = clip.intersected(parent->d_ptr->cachedClipPath); - if (!(parent->d_ptr->flags & ItemClipsToShape)) - clip = clip.intersected(parent->shape()); - } else { - clip = clip.intersected(parent->shape()); - } - - if (clip.isEmpty()) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); + clip = clip.intersected(parent->shape()); + if (clip.isEmpty()) return clip; - } lastParent = parent; } - if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - || foundValidClipPath) { + if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) break; - } } if (lastParent != this) { @@ -4607,7 +4570,6 @@ QPainterPath QGraphicsItem::clipPath() const if (d->flags & ItemClipsToShape) clip = clip.intersected(shape()); - d_ptr->setCachedClipPath(clip); return clip; } @@ -5029,12 +4991,12 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity) bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, bool ignoreVisibleBit, bool ignoreDirtyBit, bool ignoreOpacity) const { + Q_UNUSED(ignoreClipping); // No scene, or if the scene is updating everything, means we have nothing // to do. The only exception is if the scene tracks the growing scene rect. return !scene || (!visible && !ignoreVisibleBit && !this->ignoreVisible) || (!ignoreDirtyBit && fullUpdatePending) - || (!ignoreClipping && (childrenClippedToShape() && isClippedAway())) || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent()); } @@ -5169,109 +5131,6 @@ void QGraphicsItemPrivate::removeExtraItemCache() unsetExtra(ExtraCacheData); } -void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect) -{ - setEmptyCachedClipPath(); - - const bool checkRect = !emptyIfOutsideThisRect.isNull() - && !(flags & QGraphicsItem::ItemClipsChildrenToShape); - for (int i = 0; i < children.size(); ++i) { - if (!checkRect) { - children.at(i)->d_ptr->setEmptyCachedClipPathRecursively(); - continue; - } - - QGraphicsItem *child = children.at(i); - const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect); - if (rect.intersects(child->boundingRect())) - child->d_ptr->invalidateCachedClipPathRecursively(false, rect); - else - child->d_ptr->setEmptyCachedClipPathRecursively(rect); - } -} - -void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly, const QRectF &emptyIfOutsideThisRect) -{ - if (!childrenOnly) - invalidateCachedClipPath(); - - const bool checkRect = !emptyIfOutsideThisRect.isNull(); - for (int i = 0; i < children.size(); ++i) { - if (!checkRect) { - children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false); - continue; - } - - QGraphicsItem *child = children.at(i); - const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect); - if (rect.intersects(child->boundingRect())) - child->d_ptr->invalidateCachedClipPathRecursively(false, rect); - else - child->d_ptr->setEmptyCachedClipPathRecursively(rect); - } -} - -void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &newPos) -{ - Q_ASSERT(inSetPosHelper); - - if (inDestructor || !(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) - return; // Not clipped by any ancestor. - - // Find closest clip ancestor and transform. - Q_Q(QGraphicsItem); - // COMBINE - QTransform thisToParentTransform = QTransform::fromTranslate(newPos.x(), newPos.y()); - if (transformData) - thisToParentTransform = transformData->computedFullTransform(&thisToParentTransform); - QGraphicsItem *clipParent = parent; - while (clipParent && !clipParent->d_ptr->inDestructor && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) { - thisToParentTransform *= clipParent->d_ptr->transformToParent(); - clipParent = clipParent->d_ptr->parent; - } - - // Ensure no parents are currently being deleted. This can only - // happen if the item is moved by a dying ancestor. - QGraphicsItem *p = clipParent; - while (p) { - if (p->d_ptr->inDestructor) - return; - p = p->d_ptr->parent; - } - - // From here everything is calculated in clip parent's coordinates. - const QRectF parentBoundingRect(clipParent->boundingRect()); - const QRectF thisBoundingRect(thisToParentTransform.mapRect(q->boundingRect())); - - if (!parentBoundingRect.intersects(thisBoundingRect)) { - // Item is moved outside the clip parent's bounding rect, - // i.e. it is fully clipped and the clip path is empty. - if (flags & QGraphicsItem::ItemClipsChildrenToShape) - setEmptyCachedClipPathRecursively(); - else - setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentBoundingRect)); - return; - } - - const QPainterPath parentClip(clipParent->isClipped() ? clipParent->clipPath() : clipParent->shape()); - if (parentClip.contains(thisBoundingRect)) - return; // Item is inside the clip parent's shape. No update required. - - const QRectF parentClipRect(parentClip.controlPointRect()); - if (!parentClipRect.intersects(thisBoundingRect)) { - // Item is moved outside the clip parent's shape, - // i.e. it is fully clipped and the clip path is empty. - if (flags & QGraphicsItem::ItemClipsChildrenToShape) - setEmptyCachedClipPathRecursively(); - else - setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentClipRect)); - } else { - // Item is partially inside the clip parent's shape, - // i.e. the cached clip path must be invalidated. - invalidateCachedClipPathRecursively(false, thisToParentTransform.inverted().mapRect(parentClipRect)); - } -} - // Traverses all the ancestors up to the top-level and updates the pointer to // always point to the top-most item that has a dirty scene transform. // It then backtracks to the top-most dirty item and start calculating the @@ -7313,16 +7172,6 @@ void QGraphicsItem::prepareGeometryChange() // ### Only do this if the parent's effect applies to the entire subtree. parent->d_ptr->notifyBoundingRectChanged = 1; } - - if (d_ptr->inSetPosHelper) - return; - - if (d_ptr->flags & ItemClipsChildrenToShape - || d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { - d_ptr->invalidateCachedClipPathRecursively(); - } else { - d_ptr->invalidateCachedClipPath(); - } } /*! diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 75c8246..013fce1 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -152,8 +152,6 @@ public: dirty(0), dirtyChildren(0), localCollisionHack(0), - dirtyClipPath(1), - emptyClipPath(0), inSetPosHelper(0), needSortChildren(1), // ### can be 0 by default? allChildrenDirty(0), @@ -307,26 +305,6 @@ public: QGraphicsItemCache *extraItemCache() const; void removeExtraItemCache(); - inline void setCachedClipPath(const QPainterPath &path) - { - cachedClipPath = path; - dirtyClipPath = 0; - emptyClipPath = 0; - } - - inline void setEmptyCachedClipPath() - { - emptyClipPath = 1; - dirtyClipPath = 0; - } - - void setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect = QRectF()); - - inline void invalidateCachedClipPath() - { /*static int count = 0 ;qWarning("%i", ++count);*/ dirtyClipPath = 1; emptyClipPath = 0; } - - void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF()); - void updateCachedClipPathFromSetPosHelper(const QPointF &newPos); void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem); inline void ensureSceneTransform() { @@ -409,17 +387,12 @@ public: return true; } - inline bool isClippedAway() const - { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); } - inline bool childrenClippedToShape() const { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); } inline bool isInvisible() const { - return !visible - || (childrenClippedToShape() && isClippedAway()) - || (childrenCombineOpacity() && isFullyTransparent()); + return !visible || (childrenCombineOpacity() && isFullyTransparent()); } void setFocusHelper(Qt::FocusReason focusReason, bool climb); @@ -435,7 +408,6 @@ public: inline void sendScenePosChange(); virtual void siblingOrderChange(); - QPainterPath cachedClipPath; QRectF childrenBoundingRect; QRectF needsRepaint; QMap<QWidget *, QRect> paintedViewBoundingRects; @@ -480,8 +452,6 @@ public: quint32 dirty : 1; quint32 dirtyChildren : 1; quint32 localCollisionHack : 1; - quint32 dirtyClipPath : 1; - quint32 emptyClipPath : 1; quint32 inSetPosHelper : 1; quint32 needSortChildren : 1; quint32 allChildrenDirty : 1; diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index d9c65bb..f6c06d5 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -385,8 +385,6 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) QSizeF oldSize = size(); QGraphicsLayoutItem::setGeometry(newGeom); - wd->invalidateCachedClipPathRecursively(); - // Send resize event bool resized = newGeom.size() != oldSize; if (resized) { |