aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2012-06-08 11:19:09 +1000
committerQt by Nokia <qt-info@nokia.com>2012-06-08 06:17:54 +0200
commit762b4d90110465aeceb96f44cd06dcda229dfe89 (patch)
tree5bfba55b60b01a55ea965f0a51ad19ce6c84b004 /src/quick/items
parent9f9b2df76c7677fb3dc82ca617cf0732652b684d (diff)
Performance should always be better with cacheBuffer
Setting a cacheBuffer introduced more work for the scenegraph due to cached delegates' visibility being toggled. Changing visibility is expensive as it is proagated to all children. Introduce a cheap method of hiding a branch instead. Also avoid initiating incubation in the same frame as a completed creation. Change-Id: I573bcf37f441f96a7502d445be50ef4301f217d5 Reviewed-by: Bea Lam <bea.lam@nokia.com>
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickgridview.cpp12
-rw-r--r--src/quick/items/qquickitem.cpp12
-rw-r--r--src/quick/items/qquickitem_p.h5
-rw-r--r--src/quick/items/qquickitemview.cpp23
-rw-r--r--src/quick/items/qquickitemview_p_p.h4
-rw-r--r--src/quick/items/qquicklistview.cpp14
6 files changed, 47 insertions, 23 deletions
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 235005b758..331f23e4c8 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -534,7 +534,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
break;
if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
item->setPosition(colPos, rowPos, true);
- item->item->setVisible(!doBuffer);
+ QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
visibleItems.append(item);
if (++colNum >= columns) {
colNum = 0;
@@ -572,7 +572,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
--visibleIndex;
if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
item->setPosition(colPos, rowPos, true);
- item->item->setVisible(!doBuffer);
+ QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
visibleItems.prepend(item);
if (--colNum < 0) {
colNum = columns-1;
@@ -2013,11 +2013,11 @@ void QQuickGridView::viewportMoved()
qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size();
for (int i = 0; i < d->visibleItems.count(); ++i) {
FxGridItemSG *item = static_cast<FxGridItemSG*>(d->visibleItems.at(i));
- item->item->setVisible(item->rowPos() + d->rowSize() >= from && item->rowPos() <= to);
+ QQuickItemPrivate::get(item->item)->setCulled(item->rowPos() + d->rowSize() < from || item->rowPos() > to);
}
if (d->currentItem) {
FxGridItemSG *item = static_cast<FxGridItemSG*>(d->currentItem);
- item->item->setVisible(item->rowPos() + d->rowSize() >= from && item->rowPos() <= to);
+ QQuickItemPrivate::get(item->item)->setCulled(item->rowPos() + d->rowSize() < from || item->rowPos() > to);
}
if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
@@ -2363,7 +2363,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &
if (!item)
return false;
- item->item->setVisible(true);
+ QQuickItemPrivate::get(item->item)->setCulled(false);
visibleItems.insert(insertionIdx, item);
if (insertionIdx == 0)
insertResult->changedFirstItem = true;
@@ -2395,7 +2395,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &
if (!item)
return false;
- item->item->setVisible(true);
+ QQuickItemPrivate::get(item->item)->setCulled(false);
visibleItems.insert(index, item);
if (index == 0)
insertResult->changedFirstItem = true;
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index f5ab703890..ae912a2354 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2435,7 +2435,7 @@ QQuickItemPrivate::QQuickItemPrivate()
effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
inheritMirrorFromParent(false), inheritMirrorFromItem(false),
- isAccessible(false),
+ isAccessible(false), culled(false),
dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
@@ -4402,6 +4402,16 @@ void QQuickItemPrivate::derefFromEffectItem(bool unhide)
}
}
+void QQuickItemPrivate::setCulled(bool cull)
+{
+ if (cull == culled)
+ return;
+
+ culled = cull;
+ if ((cull && ++extra->hideRefCount == 1) || (!cull && --extra->hideRefCount == 0))
+ dirty(HideReference);
+}
+
void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
{
Q_Q(QQuickItem);
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index e7c449b975..bbff26089d 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -406,7 +406,8 @@ public:
bool inheritMirrorFromParent:1;
bool inheritMirrorFromItem:1;
bool isAccessible:1;
- // bool dummy:3
+ bool culled:1;
+ // bool dummy:2
// Bit 32
enum DirtyType {
@@ -448,6 +449,8 @@ public:
QQuickItem *nextDirtyItem;
QQuickItem**prevDirtyItem;
+ void setCulled(bool);
+
QQuickCanvas *canvas;
int canvasRefCount;
inline QSGContext *sceneGraphContext() const;
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 9ea2aad8fb..e48db3d140 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -87,7 +87,7 @@ void FxViewItem::setVisible(bool visible)
{
if (!visible && transitionableItem && transitionableItem->transitionScheduledOrRunning())
return;
- item->setVisible(visible);
+ QQuickItemPrivate::get(item)->setCulled(!visible);
}
QQuickItemViewTransitioner::TransitionType FxViewItem::scheduledTransitionType() const
@@ -1429,6 +1429,9 @@ QQuickItemViewPrivate::QQuickItemViewPrivate()
, fillCacheBuffer(false), inRequest(false), requestedAsync(false)
, runDelayedRemoveTransition(false)
{
+ bufferPause.addAnimationChangeListener(this, QAbstractAnimationJob::Completion);
+ bufferPause.setLoopCount(1);
+ bufferPause.setDuration(16);
}
QQuickItemViewPrivate::~QQuickItemViewPrivate()
@@ -1636,6 +1639,13 @@ void QQuickItemViewPrivate::mirrorChange()
emit q->effectiveLayoutDirectionChanged();
}
+void QQuickItemViewPrivate::animationFinished(QAbstractAnimationJob *)
+{
+ Q_Q(QQuickItemView);
+ fillCacheBuffer = true;
+ q->polish();
+}
+
void QQuickItemViewPrivate::refill()
{
qreal s = qMax(size(), qreal(0.));
@@ -1651,6 +1661,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
if (!isValid() || !q->isComponentComplete())
return;
+ bufferPause.stop();
currentChanges.reset();
int prevCount = itemCount;
@@ -1667,8 +1678,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
if (added) {
// We've already created a new delegate this frame.
// Just schedule a buffer refill.
- fillCacheBuffer = true;
- q->polish();
+ bufferPause.start();
} else {
if (bufferMode & BufferAfter)
fillTo = bufferTo;
@@ -2206,7 +2216,7 @@ void QQuickItemView::createdItem(int index, QQuickItem *item)
if (d->requestedIndex != index) {
item->setParentItem(contentItem());
d->unrequestedItems.insert(item, index);
- item->setVisible(false);
+ QQuickItemPrivate::get(item)->setCulled(true);
d->repositionPackageItemAt(item, index);
} else {
d->requestedIndex = -1;
@@ -2224,8 +2234,7 @@ void QQuickItemView::initItem(int index, QQuickItem *item)
item->setZ(1);
if (d->requestedIndex == index) {
if (d->requestedAsync)
- item->setVisible(false);
- item->setParentItem(contentItem());
+ QQuickItemPrivate::get(item)->setCulled(true);
d->requestedItem = d->newViewItem(index, item);
}
}
@@ -2248,7 +2257,7 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
QQuickVisualModel::ReleaseFlags flags = model->release(item->item);
if (flags == 0) {
// item was not destroyed, and we no longer reference it.
- item->item->setVisible(false);
+ QQuickItemPrivate::get(item->item)->setCulled(true);
unrequestedItems.insert(item->item, model->indexOf(item->item, q));
}
delete item;
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index c235945cbf..f68baf20f2 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -120,7 +120,7 @@ public:
};
-class QQuickItemViewPrivate : public QQuickFlickablePrivate, public QQuickItemViewTransitionChangeListener
+class QQuickItemViewPrivate : public QQuickFlickablePrivate, public QQuickItemViewTransitionChangeListener, public QAnimationJobChangeListener
{
Q_DECLARE_PUBLIC(QQuickItemView)
public:
@@ -188,6 +188,7 @@ public:
void regenerate();
void layout();
+ virtual void animationFinished(QAbstractAnimationJob *);
void refill();
void refill(qreal from, qreal to);
void mirrorChange();
@@ -266,6 +267,7 @@ public:
FxViewItem *requestedItem;
QQuickItemViewChangeSet currentChanges;
QQuickItemViewChangeSet bufferedChanges;
+ QPauseAnimationJob bufferPause;
QQmlComponent *highlightComponent;
FxViewItem *highlight;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index e2de19b498..75d4933862 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -664,13 +664,13 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
qreal pos = itemEnd;
while (modelIndex < model->count() && pos <= fillTo) {
#ifdef DEBUG_DELEGATE_LIFECYCLE
- qDebug() << "refill: append item" << modelIndex << "pos" << pos;
+ qDebug() << "refill: append item" << modelIndex << "pos" << pos << "buffer" << doBuffer;
#endif
if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, doBuffer))))
break;
if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
item->setPosition(pos, true);
- item->item->setVisible(!doBuffer);
+ QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
pos += item->size() + spacing;
visibleItems.append(item);
++modelIndex;
@@ -682,7 +682,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos > fillFrom) {
#ifdef DEBUG_DELEGATE_LIFECYCLE
- qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos;
+ qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos << "buffer" << doBuffer;
#endif
if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1, doBuffer))))
break;
@@ -690,7 +690,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
visiblePos -= item->size() + spacing;
if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
item->setPosition(visiblePos, true);
- item->item->setVisible(!doBuffer);
+ QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
visibleItems.prepend(item);
changed = true;
}
@@ -787,7 +787,7 @@ void QQuickListViewPrivate::layoutVisibleItems(int fromModelIndex)
bool fixedCurrent = currentItem && firstItem->item == currentItem->item;
qreal sum = firstItem->size();
qreal pos = firstItem->position() + firstItem->size() + spacing;
- firstItem->item->setVisible(firstItem->endPosition() >= from && firstItem->position() <= to);
+ firstItem->setVisible(firstItem->endPosition() >= from && firstItem->position() <= to);
for (int i=1; i < visibleItems.count(); ++i) {
FxListItemSG *item = static_cast<FxListItemSG*>(visibleItems.at(i));
@@ -2659,10 +2659,10 @@ void QQuickListView::viewportMoved()
qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size();
for (int i = 0; i < d->visibleItems.count(); ++i) {
FxViewItem *item = static_cast<FxListItemSG*>(d->visibleItems.at(i));
- item->item->setVisible(item->endPosition() >= from && item->position() <= to);
+ QQuickItemPrivate::get(item->item)->setCulled(item->endPosition() < from || item->position() > to);
}
if (d->currentItem)
- d->currentItem->item->setVisible(d->currentItem->endPosition() >= from && d->currentItem->position() <= to);
+ QQuickItemPrivate::get(d->currentItem->item)->setCulled(d->currentItem->endPosition() < from || d->currentItem->position() > to);
if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
d->moveReason = QQuickListViewPrivate::Mouse;