aboutsummaryrefslogtreecommitdiffstats
path: root/src/imports
diff options
context:
space:
mode:
authorRobin Burchell <robin.burchell@viroteck.net>2016-07-08 13:25:02 +0200
committerJani Heikkinen <jani.heikkinen@qt.io>2016-11-30 08:31:52 +0000
commit3b4f00ecb54432f514f184c251a316896a88f91a (patch)
treef39299a24451d8e7f7beb17eb314247d5481c2fc /src/imports
parent39496a40748be1d60c909ba679c45c788ec6412f (diff)
Layouts: Use QQuickItemChangeListener for more things
Signal connections are expensive: even with qmlobject_connect, there's a bunch of memory allocation. By avoiding the signal connections, we can do the same thing essentially, a little faster. This gives me another 15-20 RowLayout instances per frame when testing with RowLayout containing 5 Rectangles on qmlbench (from ~139 to ~155 ops/frame). Change-Id: I4448a28128dc251e40b6b06d642bae716af212f4 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src/imports')
-rw-r--r--src/imports/layouts/qquicklayout.cpp32
-rw-r--r--src/imports/layouts/qquicklayout_p.h4
-rw-r--r--src/imports/layouts/qquicklinearlayout.cpp54
-rw-r--r--src/imports/layouts/qquicklinearlayout_p.h9
4 files changed, 51 insertions, 48 deletions
diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp
index 07ada75a5f..3786d21727 100644
--- a/src/imports/layouts/qquicklayout.cpp
+++ b/src/imports/layouts/qquicklayout.cpp
@@ -763,18 +763,14 @@ void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value)
{
if (change == ItemChildAddedChange) {
QQuickItem *item = value.item;
- qmlobject_connect(item, QQuickItem, SIGNAL(implicitWidthChanged()), this, QQuickLayout, SLOT(invalidateSenderItem()));
- qmlobject_connect(item, QQuickItem, SIGNAL(implicitHeightChanged()), this, QQuickLayout, SLOT(invalidateSenderItem()));
qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem()));
- QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::SiblingOrder);
+ QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility);
if (isReady())
updateLayoutItems();
} else if (change == ItemChildRemovedChange) {
QQuickItem *item = value.item;
- qmlobject_disconnect(item, QQuickItem, SIGNAL(implicitWidthChanged()), this, QQuickLayout, SLOT(invalidateSenderItem()));
- qmlobject_disconnect(item, QQuickItem, SIGNAL(implicitHeightChanged()), this, QQuickLayout, SLOT(invalidateSenderItem()));
qmlobject_disconnect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem()));
- QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::SiblingOrder);
+ QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility);
if (isReady())
updateLayoutItems();
}
@@ -812,6 +808,30 @@ void QQuickLayout::itemSiblingOrderChanged(QQuickItem *item)
updateLayoutItems();
}
+void QQuickLayout::itemImplicitWidthChanged(QQuickItem *item)
+{
+ if (!isReady() || item->signalsBlocked())
+ return;
+ invalidate(item);
+}
+
+void QQuickLayout::itemImplicitHeightChanged(QQuickItem *item)
+{
+ if (!isReady() || item->signalsBlocked())
+ return;
+ invalidate(item);
+}
+
+void QQuickLayout::itemDestroyed(QQuickItem *item)
+{
+ Q_UNUSED(item);
+}
+
+void QQuickLayout::itemVisibilityChanged(QQuickItem *item)
+{
+ Q_UNUSED(item);
+}
+
void QQuickLayout::rearrange(const QSizeF &/*size*/)
{
m_dirty = false;
diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h
index c7f04c1fed..eece6f8658 100644
--- a/src/imports/layouts/qquicklayout_p.h
+++ b/src/imports/layouts/qquicklayout_p.h
@@ -99,6 +99,10 @@ public:
/* QQuickItemChangeListener */
void itemSiblingOrderChanged(QQuickItem *item) Q_DECL_OVERRIDE;
+ void itemImplicitWidthChanged(QQuickItem *item) Q_DECL_OVERRIDE;
+ void itemImplicitHeightChanged(QQuickItem *item) Q_DECL_OVERRIDE;
+ void itemDestroyed(QQuickItem *item) Q_DECL_OVERRIDE;
+ void itemVisibilityChanged(QQuickItem *item) Q_DECL_OVERRIDE;
protected:
void updatePolish() Q_DECL_OVERRIDE;
diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp
index 7fad395a29..13fdd496c2 100644
--- a/src/imports/layouts/qquicklinearlayout.cpp
+++ b/src/imports/layouts/qquicklinearlayout.cpp
@@ -303,17 +303,13 @@ QQuickGridLayoutBase::~QQuickGridLayoutBase()
{
Q_D(QQuickGridLayoutBase);
- /* Avoid messy deconstruction, should give:
- * Faster deconstruction
- * Less risk of signals reaching already deleted objects
- */
+ // Remove item listeners so we do not act on signalling unnecessarily
+ // (there is no point, as the layout will be torn down anyway).
for (int i = 0; i < itemCount(); ++i) {
QQuickItem *item = itemAt(i);
- qmlobject_disconnect(item, QQuickItem, SIGNAL(destroyed()), this, QQuickGridLayoutBase, SLOT(onItemDestroyed()));
- qmlobject_disconnect(item, QQuickItem, SIGNAL(visibleChanged()), this, QQuickGridLayoutBase, SLOT(onItemVisibleChanged()));
- qmlobject_disconnect(item, QQuickItem, SIGNAL(implicitWidthChanged()), this, QQuickGridLayoutBase, SLOT(invalidateSenderItem()));
- qmlobject_disconnect(item, QQuickItem, SIGNAL(implicitHeightChanged()), this, QQuickGridLayoutBase, SLOT(invalidateSenderItem()));
+ QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility);
}
+
delete d->styleInfo;
}
@@ -436,23 +432,6 @@ int QQuickGridLayoutBase::itemCount() const
return d->engine.itemCount();
}
-void QQuickGridLayoutBase::itemChange(ItemChange change, const ItemChangeData &value)
-{
- if (change == ItemChildAddedChange) {
- quickLayoutDebug() << "ItemChildAddedChange";
- QQuickItem *item = value.item;
- qmlobject_connect(item, QQuickItem, SIGNAL(destroyed()), this, QQuickGridLayoutBase, SLOT(onItemDestroyed()));
- qmlobject_connect(item, QQuickItem, SIGNAL(visibleChanged()), this, QQuickGridLayoutBase, SLOT(onItemVisibleChanged()));
- } else if (change == ItemChildRemovedChange) {
- quickLayoutDebug() << "ItemChildRemovedChange";
- QQuickItem *item = value.item;
- qmlobject_disconnect(item, QQuickItem, SIGNAL(destroyed()), this, QQuickGridLayoutBase, SLOT(onItemDestroyed()));
- qmlobject_disconnect(item, QQuickItem, SIGNAL(visibleChanged()), this, QQuickGridLayoutBase, SLOT(onItemVisibleChanged()));
- }
-
- QQuickLayout::itemChange(change, value);
-}
-
void QQuickGridLayoutBase::removeGridItem(QGridLayoutItem *gridItem)
{
Q_D(QQuickGridLayoutBase);
@@ -461,28 +440,29 @@ void QQuickGridLayoutBase::removeGridItem(QGridLayoutItem *gridItem)
d->engine.removeRows(index, 1, d->orientation);
}
-void QQuickGridLayoutBase::onItemVisibleChanged()
-{
- if (!isReady())
- return;
- quickLayoutDebug() << "QQuickGridLayoutBase::onItemVisibleChanged";
- updateLayoutItems();
-}
-
-void QQuickGridLayoutBase::onItemDestroyed()
+void QQuickGridLayoutBase::itemDestroyed(QQuickItem *item)
{
if (!isReady())
return;
Q_D(QQuickGridLayoutBase);
- quickLayoutDebug() << "QQuickGridLayoutBase::onItemDestroyed";
- QQuickItem *inDestruction = static_cast<QQuickItem *>(sender());
- if (QQuickGridLayoutItem *gridItem = d->engine.findLayoutItem(inDestruction)) {
+ quickLayoutDebug() << "QQuickGridLayoutBase::itemDestroyed";
+ if (QQuickGridLayoutItem *gridItem = d->engine.findLayoutItem(item)) {
removeGridItem(gridItem);
delete gridItem;
invalidate();
}
}
+void QQuickGridLayoutBase::itemVisibilityChanged(QQuickItem *item)
+{
+ Q_UNUSED(item);
+
+ if (!isReady())
+ return;
+ quickLayoutDebug() << "QQuickGridLayoutBase::itemVisibilityChanged";
+ updateLayoutItems();
+}
+
void QQuickGridLayoutBase::rearrange(const QSizeF &size)
{
Q_D(QQuickGridLayoutBase);
diff --git a/src/imports/layouts/qquicklinearlayout_p.h b/src/imports/layouts/qquicklinearlayout_p.h
index 86404f8d79..c289416540 100644
--- a/src/imports/layouts/qquicklinearlayout_p.h
+++ b/src/imports/layouts/qquicklinearlayout_p.h
@@ -77,6 +77,10 @@ public:
Qt::LayoutDirection effectiveLayoutDirection() const;
void setAlignment(QQuickItem *item, Qt::Alignment align) Q_DECL_OVERRIDE;
+ /* QQuickItemChangeListener */
+ void itemDestroyed(QQuickItem *item) Q_DECL_OVERRIDE;
+ void itemVisibilityChanged(QQuickItem *item) Q_DECL_OVERRIDE;
+
protected:
void updateLayoutItems() Q_DECL_OVERRIDE;
QQuickItem *itemAt(int index) const Q_DECL_OVERRIDE;
@@ -84,15 +88,10 @@ protected:
void rearrange(const QSizeF &size) Q_DECL_OVERRIDE;
virtual void insertLayoutItems() {}
- void itemChange(ItemChange change, const ItemChangeData &data) Q_DECL_OVERRIDE;
signals:
Q_REVISION(1) void layoutDirectionChanged();
-protected slots:
- void onItemVisibleChanged();
- void onItemDestroyed();
-
private:
void removeGridItem(QGridLayoutItem *gridItem);
Q_DECLARE_PRIVATE(QQuickGridLayoutBase)