diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2017-10-17 16:54:22 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2017-11-25 06:21:04 +0000 |
commit | efe1926598c69a09c9365673bba6961a83936d49 (patch) | |
tree | c944b5e30f90ea1e1a5525b3974b67e6f8da1ad6 /src/qml/qml/qqmlengine.cpp | |
parent | c5567cc706afb954ff6f679f35fe96a078bd4f46 (diff) |
More fine-grained deferred property execution
This allows Qt Quick Controls 2 to defer the execution of certain
building blocks until needed. For example, a button control can
defer its background item so that the default background is not
executed at all when replaced by a custom background.
First of all, this gives a massive performance boost for customized
controls. Secondly, this avoids the most burning issue in QQC2,
problems with asynchronous incubation ("Object destroyed during
incubation").
Task-number: QTBUG-50992
Change-Id: If3616c9dac70e3a474a20070ad0452874d267164
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlengine.cpp')
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index d99bec4c52..612c3439c1 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1639,13 +1639,40 @@ void QQmlData::NotifyList::layout() todo = 0; } +void QQmlData::deferData(int objectIndex, QV4::CompiledData::CompilationUnit *compilationUnit, QQmlContextData *context) +{ + QQmlData::DeferredData *deferData = new QQmlData::DeferredData; + deferData->deferredIdx = objectIndex; + deferData->compilationUnit = compilationUnit; + deferData->compilationUnit->addref(); + deferData->context = context; + + const QV4::CompiledData::Object *compiledObject = compilationUnit->objectAt(objectIndex); + const QV4::CompiledData::BindingPropertyData &propertyData = compilationUnit->bindingPropertyDataPerObject.at(objectIndex); + + const QV4::CompiledData::Binding *binding = compiledObject->bindingTable(); + for (quint32 i = 0; i < compiledObject->nBindings; ++i, ++binding) { + const QQmlPropertyData *property = propertyData.at(i); + if (property && binding->flags & QV4::CompiledData::Binding::IsDeferredBinding) + deferData->bindings.insert(property->coreIndex(), binding); + } + + deferredData.append(deferData); +} + void QQmlData::releaseDeferredData() { - for (DeferredData *deferData : qAsConst(deferredData)) { - deferData->compilationUnit->release(); - delete deferData; + auto it = deferredData.begin(); + while (it != deferredData.end()) { + DeferredData *deferData = *it; + if (deferData->bindings.isEmpty()) { + deferData->compilationUnit->release(); + delete deferData; + it = deferredData.erase(it); + } else { + ++it; + } } - deferredData.clear(); } void QQmlData::addNotify(int index, QQmlNotifierEndpoint *endpoint) |