aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2011-11-24 17:22:31 +1000
committerQt by Nokia <qt-info@nokia.com>2011-11-24 23:51:11 +0100
commitfa031fa3f540516e681b3bb6d6dde84f3aa28b1a (patch)
treef89fa6e93b34e255e0fd293454a912c176f0dc3f /src/declarative
parent95a982475d6778bb8745270f3eaa1f4bfe2545b7 (diff)
Improve performance on touch event delivery.
We continuously constructed and sorted the paint ordered items for every touch event (and paint), even though the list in most cases is identical to the childItems list, and when it is different it rarely changes. Detect when we can just use the childItems list directly, and otherwise cache the ordered items list. Change-Id: I5db0f19fc021d0c95aa6f8372ae47e6ce138d5ad Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/items/qquickitem.cpp42
-rw-r--r--src/declarative/items/qquickitem_p.h12
2 files changed, 47 insertions, 7 deletions
diff --git a/src/declarative/items/qquickitem.cpp b/src/declarative/items/qquickitem.cpp
index 294edad842..e020a0088c 100644
--- a/src/declarative/items/qquickitem.cpp
+++ b/src/declarative/items/qquickitem.cpp
@@ -1903,6 +1903,7 @@ void QQuickItem::stackBefore(const QQuickItem *sibling)
parentPrivate->childItems.insert(siblingIndex, this);
parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
+ parentPrivate->markSortedChildrenDirty(this);
for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
@@ -1933,6 +1934,7 @@ void QQuickItem::stackAfter(const QQuickItem *sibling)
parentPrivate->childItems.insert(siblingIndex + 1, this);
parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
+ parentPrivate->markSortedChildrenDirty(this);
for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
@@ -1965,11 +1967,27 @@ static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
{
- // XXX todo - optimize, don't sort and return items that are
- // ignored anyway, like invisible or disabled items.
- QList<QQuickItem *> items = childItems;
- qStableSort(items.begin(), items.end(), itemZOrder_sort);
- return items;
+ if (sortedChildItems)
+ return *sortedChildItems;
+
+ // If none of the items have set Z then the paint order list is the same as
+ // the childItems list. This is by far the most common case.
+ bool haveZ = false;
+ for (int i = 0; i < childItems.count(); ++i) {
+ if (QQuickItemPrivate::get(childItems.at(i))->z != 0.) {
+ haveZ = true;
+ break;
+ }
+ }
+ if (haveZ) {
+ sortedChildItems = new QList<QQuickItem*>(childItems);
+ qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
+ return *sortedChildItems;
+ }
+
+ sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
+
+ return childItems;
}
void QQuickItemPrivate::addChild(QQuickItem *child)
@@ -1980,6 +1998,7 @@ void QQuickItemPrivate::addChild(QQuickItem *child)
childItems.append(child);
+ markSortedChildrenDirty(child);
dirty(QQuickItemPrivate::ChildrenChanged);
itemChange(QQuickItem::ItemChildAddedChange, child);
@@ -1996,6 +2015,7 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
childItems.removeOne(child);
Q_ASSERT(!childItems.contains(child));
+ markSortedChildrenDirty(child);
dirty(QQuickItemPrivate::ChildrenChanged);
itemChange(QQuickItem::ItemChildRemovedChange, child);
@@ -2191,7 +2211,7 @@ QQuickItemPrivate::QQuickItemPrivate()
inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
- canvas(0), parentItem(0),
+ canvas(0), parentItem(0), sortedChildItems(&childItems),
subFocusItem(0),
@@ -2210,6 +2230,12 @@ QQuickItemPrivate::QQuickItemPrivate()
{
}
+QQuickItemPrivate::~QQuickItemPrivate()
+{
+ if (sortedChildItems != &childItems)
+ delete sortedChildItems;
+}
+
void QQuickItemPrivate::init(QQuickItem *parent)
{
#ifndef QT_NO_DEBUG
@@ -3518,8 +3544,10 @@ void QQuickItem::setZ(qreal v)
d->z = v;
d->dirty(QQuickItemPrivate::ZValue);
- if (d->parentItem)
+ if (d->parentItem) {
QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
+ QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
+ }
emit zChanged();
}
diff --git a/src/declarative/items/qquickitem_p.h b/src/declarative/items/qquickitem_p.h
index 47f86c48aa..38e5d154f8 100644
--- a/src/declarative/items/qquickitem_p.h
+++ b/src/declarative/items/qquickitem_p.h
@@ -139,6 +139,7 @@ public:
static const QQuickItemPrivate* get(const QQuickItem *item) { return item->d_func(); }
QQuickItemPrivate();
+ ~QQuickItemPrivate();
void init(QQuickItem *parent);
QDeclarativeListProperty<QObject> data();
@@ -262,11 +263,22 @@ public:
QQuickItem *parentItem;
QList<QQuickItem *> childItems;
+ mutable QList<QQuickItem *> *sortedChildItems;
QList<QQuickItem *> paintOrderChildItems() const;
void addChild(QQuickItem *);
void removeChild(QQuickItem *);
void siblingOrderChanged();
+ inline void markSortedChildrenDirty(QQuickItem *child) {
+ // If sortedChildItems == &childItems then all in childItems have z == 0
+ // and we don't need to invalidate if the changed item also has z == 0.
+ if (child->z() != 0. || sortedChildItems != &childItems) {
+ if (sortedChildItems != &childItems)
+ delete sortedChildItems;
+ sortedChildItems = 0;
+ }
+ }
+
class InitializationState {
public:
QQuickItem *getFocusScope(QQuickItem *item);