From 23c73210fc79055f4bac44de0e43f9917f8d0e7f Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Tue, 24 Mar 2009 15:50:26 +0100 Subject: Fixes: Discard update requests if possible. AutoTest: Still pass. Details: Update requests can be discarded if the item itself is clipped away and the item clips all its children to shape. This cut-off is extremely effective (and aggressive:)) --- src/gui/graphicsview/qgraphicsitem.cpp | 39 +++++++++++++++++++++++++--------- src/gui/graphicsview/qgraphicsitem_p.h | 6 ++++++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 327b352..23787a7 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1102,10 +1102,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent) } // Resolve opacity. - if (QGraphicsItem *p = d_ptr->parent) - d_ptr->resolveEffectiveOpacity(p->effectiveOpacity()); - else - d_ptr->resolveEffectiveOpacity(1.0); + d_ptr->updateEffectiveOpacity(); // Resolve depth. d_ptr->resolveDepth(parent ? parent->d_ptr->depth : -1); @@ -1246,12 +1243,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) // Reresolve effective opacity if the opacity flags change. static const quint32 opacityFlagsMask = ItemIgnoresParentOpacity | ItemDoesntPropagateOpacityToChildren; - if ((flags & opacityFlagsMask) != (oldFlags & opacityFlagsMask)) { - if (QGraphicsItem *p = d_ptr->parent) - d_ptr->resolveEffectiveOpacity(p->effectiveOpacity()); - else - d_ptr->resolveEffectiveOpacity(1.0); - } + if ((flags & opacityFlagsMask) != (oldFlags & opacityFlagsMask)) + d_ptr->updateEffectiveOpacity(); if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) { // Clear focus on the item if it has focus when the focusable flag @@ -3693,6 +3686,32 @@ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyCl dirtyChildren = 1; } +static inline bool allChildrenCombineOpacity(QGraphicsItem *parent) +{ + Q_ASSERT(parent); + if (parent->flags() & QGraphicsItem::ItemDoesntPropagateOpacityToChildren) + return false; + + const QList children(parent->childItems()); + for (int i = 0; i < children.size(); ++i) { + if (children.at(i)->flags() & QGraphicsItem::ItemIgnoresParentOpacity) + return false; + } + return true; +} + +void QGraphicsItemPrivate::updateEffectiveOpacity() +{ + Q_Q(QGraphicsItem); + if (parent) { + resolveEffectiveOpacity(parent->effectiveOpacity()); + parent->d_ptr->allChildrenCombineOpacity = ::allChildrenCombineOpacity(parent); + } else { + resolveEffectiveOpacity(1.0); + } + allChildrenCombineOpacity = ::allChildrenCombineOpacity(q); +} + /*! \internal diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index dabbe53..c795915 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -141,6 +141,7 @@ public: dirtyClipPath(1), emptyClipPath(0), inSetPosHelper(0), + allChildrenCombineOpacity(1), globalStackingOrder(-1), sceneTransformIndex(-1), q_ptr(0) @@ -166,6 +167,7 @@ public: void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false); void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false); + void updateEffectiveOpacity(); void resolveEffectiveOpacity(qreal effectiveParentOpacity); void resolveDepth(int parentDepth); void invalidateSceneTransformCache(); @@ -264,6 +266,9 @@ public: && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0))); } + inline bool childrenCombineOpacity() const + { return allChildrenCombineOpacity || children.isEmpty(); } + inline bool isClippedAway() const { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); } @@ -308,6 +313,7 @@ public: quint32 dirtyClipPath : 1; quint32 emptyClipPath : 1; quint32 inSetPosHelper : 1; + quint32 allChildrenCombineOpacity : 1; // Optional stacking order int globalStackingOrder; -- cgit v0.12