From f5c5e20ab20f016c07351330d03432e4912f20b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20R=C3=B8dal?= <samuel.rodal@nokia.com>
Date: Mon, 28 Jun 2010 15:56:33 +0200
Subject: Fixed missing clip when computing the graphics item effect source
 rect.

If item clips children to shape we should take that into account when
computing the source rect, to avoid creating unnecessary large source
pixmaps which might have a significant performance impact.

Task-number: QT-3551
Reviewed-by: Gunnar
Reviewed-by: Trond
---
 src/gui/graphicsview/qgraphicsitem.cpp             | 27 +++++++++++++++++++---
 src/gui/graphicsview/qgraphicsitem_p.h             | 14 +++++++----
 .../tst_qgraphicseffectsource.cpp                  | 15 ++++++++++++
 3 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 074e571..88e9952 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1205,8 +1205,14 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q
 
     Returns the bounding rect of this item's children (excluding itself).
 */
-void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect)
+void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, bool doClip)
 {
+    Q_Q(QGraphicsItem);
+
+    QRectF childrenRect;
+    QRectF *result = rect;
+    rect = &childrenRect;
+
     for (int i = 0; i < children.size(); ++i) {
         QGraphicsItem *child = children.at(i);
         QGraphicsItemPrivate *childd = child->d_ptr.data();
@@ -1228,6 +1234,15 @@ void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rec
                 childd->childrenBoundingRectHelper(x, rect);
         }
     }
+
+    if (doClip && (flags & QGraphicsItem::ItemClipsChildrenToShape)){
+        if (x)
+            *rect &= x->mapRect(q->boundingRect());
+        else
+            *rect &= q->boundingRect();
+    }
+
+    *result |= *rect;
 }
 
 void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
@@ -10816,8 +10831,14 @@ QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem syste
     }
 
     QRectF rect = item->boundingRect();
-    if (!item->d_ptr->children.isEmpty())
-        rect |= item->childrenBoundingRect();
+    if (!item->d_ptr->children.isEmpty()) {
+        if (dirtyChildrenBoundingRect) {
+            childrenBoundingRect = QRectF();
+            item->d_ptr->childrenBoundingRectHelper(0, &childrenBoundingRect, true);
+            dirtyChildrenBoundingRect = false;
+        }
+        rect |= childrenBoundingRect;
+    }
 
     if (deviceCoordinates) {
         Q_ASSERT(info->painter);
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index e737773..ead240b 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -239,7 +239,7 @@ public:
     void removeChild(QGraphicsItem *child);
     void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant,
                              const QVariant *thisPointerVariant);
-    void childrenBoundingRectHelper(QTransform *x, QRectF *rect);
+    void childrenBoundingRectHelper(QTransform *x, QRectF *rect, bool doClip = true);
     void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
                          const QRegion &exposedRegion, bool allItems = false) const;
     QRectF effectiveBoundingRect() const;
@@ -580,7 +580,7 @@ class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate
 {
 public:
     QGraphicsItemEffectSourcePrivate(QGraphicsItem *i)
-        : QGraphicsEffectSourcePrivate(), item(i), info(0)
+        : QGraphicsEffectSourcePrivate(), dirtyChildrenBoundingRect(true), item(i), info(0)
     {}
 
     inline void detach()
@@ -631,6 +631,9 @@ public:
                    QGraphicsEffect::PixmapPadMode mode) const;
     QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = 0) const;
 
+    mutable bool dirtyChildrenBoundingRect;
+    mutable QRectF childrenBoundingRect;
+
     QGraphicsItem *item;
     QGraphicsItemPaintInfo *info;
     QTransform lastEffectTransform;
@@ -788,9 +791,12 @@ inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect)
 #ifndef QT_NO_GRAPHICSEFFECT
         if (parentp->graphicsEffect) {
             if (updateBoundingRect) {
+                QGraphicsItemEffectSourcePrivate *sourcep =
+                    static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
+                                                                    ->source->d_func());
+                parentp->dirtyChildrenBoundingRect = 1;
                 parentp->notifyInvalidated = 1;
-                static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
-                                                                ->source->d_func())->invalidateCache();
+                sourcep->invalidateCache();
             }
             if (parentp->graphicsEffect->isEnabled()) {
                 parentp->dirty = 1;
diff --git a/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp b/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp
index 49f110e..49a76fa 100644
--- a/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp
+++ b/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp
@@ -161,6 +161,7 @@ private slots:
     void draw();
     void update();
     void boundingRect();
+    void clippedBoundingRect();
     void deviceRect();
     void pixmap();
 
@@ -282,6 +283,20 @@ void tst_QGraphicsEffectSource::boundingRect()
     QTRY_COMPARE(effect->source()->boundingRect(), itemBoundingRect);
 }
 
+void tst_QGraphicsEffectSource::clippedBoundingRect()
+{
+    QRectF itemBoundingRect = item->boundingRect();
+    item->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
+
+    QGraphicsRectItem *child = new QGraphicsRectItem(-1000, -1000, 2000, 2000);
+    child->setBrush(Qt::red);
+    child->setParentItem(item);
+
+    effect->storeDeviceDependentStuff = true;
+    effect->source()->update();
+    QTRY_COMPARE(effect->source()->boundingRect(Qt::LogicalCoordinates), itemBoundingRect);
+}
+
 void tst_QGraphicsEffectSource::deviceRect()
 {
     effect->storeDeviceDependentStuff = true;
-- 
cgit v0.12


From ce4ed8fa50a72927d68c4c68c04a28d783546c07 Mon Sep 17 00:00:00 2001
From: axis <qt-info@nokia.com>
Date: Fri, 2 Jul 2010 16:55:00 +0200
Subject: Removed missing symbols from DEF files.

RevBy:    Jason Barron
---
 src/s60installs/bwins/QtGuiu.def | 2 +-
 src/s60installs/eabi/QtGuiu.def  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def
index 3368e4c..cde0b60 100644
--- a/src/s60installs/bwins/QtGuiu.def
+++ b/src/s60installs/bwins/QtGuiu.def
@@ -2645,7 +2645,7 @@ EXPORTS
 	?childItems@QGraphicsItem@@QBE?AV?$QList@PAVQGraphicsItem@@@@XZ @ 2644 NONAME ; class QList<class QGraphicsItem *> QGraphicsItem::childItems(void) const
 	?children@QGraphicsItem@@QBE?AV?$QList@PAVQGraphicsItem@@@@XZ @ 2645 NONAME ; class QList<class QGraphicsItem *> QGraphicsItem::children(void) const
 	?childrenBoundingRect@QGraphicsItem@@QBE?AVQRectF@@XZ @ 2646 NONAME ; class QRectF QGraphicsItem::childrenBoundingRect(void) const
-	?childrenBoundingRectHelper@QGraphicsItemPrivate@@QAEXPAVQTransform@@PAVQRectF@@@Z @ 2647 NONAME ; void QGraphicsItemPrivate::childrenBoundingRectHelper(class QTransform *, class QRectF *)
+	?childrenBoundingRectHelper@QGraphicsItemPrivate@@QAEXPAVQTransform@@PAVQRectF@@@Z @ 2647 NONAME ABSENT ; void QGraphicsItemPrivate::childrenBoundingRectHelper(class QTransform *, class QRectF *)
 	?childrenCheckState@QTreeWidgetItem@@ABE?AVQVariant@@H@Z @ 2648 NONAME ; class QVariant QTreeWidgetItem::childrenCheckState(int) const
 	?childrenClippedToShape@QGraphicsItemPrivate@@QBE_NXZ @ 2649 NONAME ; bool QGraphicsItemPrivate::childrenClippedToShape(void) const
 	?childrenCollapsible@QSplitter@@QBE_NXZ @ 2650 NONAME ; bool QSplitter::childrenCollapsible(void) const
diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def
index cfe2630..4c57c03 100644
--- a/src/s60installs/eabi/QtGuiu.def
+++ b/src/s60installs/eabi/QtGuiu.def
@@ -4675,7 +4675,7 @@ EXPORTS
 	_ZN20QGraphicsItemPrivate20removeExtraItemCacheEv @ 4674 NONAME
 	_ZN20QGraphicsItemPrivate23appendGraphicsTransformEP18QGraphicsTransform @ 4675 NONAME
 	_ZN20QGraphicsItemPrivate25movableAncestorIsSelectedEPK13QGraphicsItem @ 4676 NONAME
-	_ZN20QGraphicsItemPrivate26childrenBoundingRectHelperEP10QTransformP6QRectF @ 4677 NONAME
+	_ZN20QGraphicsItemPrivate26childrenBoundingRectHelperEP10QTransformP6QRectF @ 4677 NONAME ABSENT
 	_ZN20QGraphicsItemPrivate26invalidateDepthRecursivelyEv @ 4678 NONAME
 	_ZN20QGraphicsItemPrivate28ensureSequentialSiblingIndexEv @ 4679 NONAME
 	_ZN20QGraphicsItemPrivate29ensureSceneTransformRecursiveEPP13QGraphicsItem @ 4680 NONAME
-- 
cgit v0.12