diff options
author | Martin Jones <martin.jones@nokia.com> | 2012-06-08 11:19:09 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-06-08 06:17:54 +0200 |
commit | 762b4d90110465aeceb96f44cd06dcda229dfe89 (patch) | |
tree | 5bfba55b60b01a55ea965f0a51ad19ce6c84b004 /src/quick/items | |
parent | 9f9b2df76c7677fb3dc82ca617cf0732652b684d (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.cpp | 12 | ||||
-rw-r--r-- | src/quick/items/qquickitem.cpp | 12 | ||||
-rw-r--r-- | src/quick/items/qquickitem_p.h | 5 | ||||
-rw-r--r-- | src/quick/items/qquickitemview.cpp | 23 | ||||
-rw-r--r-- | src/quick/items/qquickitemview_p_p.h | 4 | ||||
-rw-r--r-- | src/quick/items/qquicklistview.cpp | 14 |
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; |