QQuickTableView: avoid building syncView children before syncView has finished

If you put two tables inside an async loader, with one being
the syncView for the other, the syncView child will start
loading items async simultaneously with the syncView.
This is unnecessary, and steals loading resources, since
the child will have to rebuild anyway once the syncView has
completed loading. So return early from the recursiveUpdateTable
call before handling the children if we detect that the parent
is not done.

Change-Id: I8c0badaf3cfa3a353a650e5f38f381bf9a7b98f9
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
This commit is contained in:
Richard Moe Gustavsen 2019-04-24 11:46:37 +02:00
parent 9e5ca92712
commit 8fb8cfd040
2 changed files with 15 additions and 9 deletions

View File

@ -1866,14 +1866,16 @@ bool QQuickTableViewPrivate::updateTableRecursive()
return false;
}
updateTable();
const bool updateComplete = updateTable();
if (!updateComplete)
return false;
for (auto syncChild : qAsConst(syncChildren)) {
auto syncChild_d = syncChild->d_func();
syncChild_d->scheduledRebuildOptions |= rebuildOptions;
const bool updated = syncChild_d->updateTableRecursive();
if (!updated)
const bool descendantUpdateComplete = syncChild_d->updateTableRecursive();
if (!descendantUpdateComplete)
return false;
}
@ -1882,11 +1884,13 @@ bool QQuickTableViewPrivate::updateTableRecursive()
return true;
}
void QQuickTableViewPrivate::updateTable()
bool QQuickTableViewPrivate::updateTable()
{
// Whenever something changes, e.g viewport moves, spacing is set to a
// new value, model changes etc, this function will end up being called. Here
// we check what needs to be done, and load/unload cells accordingly.
// If we cannot complete the update (because we need to wait for an item
// to load async), we return false.
Q_TABLEVIEW_ASSERT(!polishing, "recursive updatePolish() calls are not allowed!");
QBoolBlocker polishGuard(polishing, true);
@ -1896,25 +1900,27 @@ void QQuickTableViewPrivate::updateTable()
// as an atomic operation, which means that we don't continue doing anything else until all
// items have been received and laid out. Note that updatePolish is then called once more
// after the loadRequest has completed to handle anything that might have occurred in-between.
return;
return false;
}
if (rebuildState != RebuildState::Done) {
processRebuildTable();
return;
return rebuildState == RebuildState::Done;
}
syncWithPendingChanges();
if (rebuildState == RebuildState::Begin) {
processRebuildTable();
return;
return rebuildState == RebuildState::Done;
}
if (loadedItems.isEmpty())
return;
return !loadRequest.isActive();
loadAndUnloadVisibleEdges();
return !loadRequest.isActive();
}
void QQuickTableViewPrivate::fixup(QQuickFlickablePrivate::AxisData &data, qreal minExtent, qreal maxExtent)

View File

@ -315,7 +315,7 @@ public:
QQuickTableView *rootSyncView() const;
bool updateTableRecursive();
void updateTable();
bool updateTable();
void relayoutTable();
void relayoutTableItems();