summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2019-03-08 16:15:29 +0200
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2019-03-20 08:48:32 +0000
commit961f7e783670be0627ddb21c1379ebfec0c3c944 (patch)
tree1e0f2ea839868d7333fdd1ddcd0b3e0141948875
parentae044e6ee37b228e109b19c7c13be5c260c0bb64 (diff)
Improve scene translation push efficiencywip/runtime2
There is no need to remove all scene content and recreate the layers every time anything changes in the scene. Change-Id: I16d9401f1977d5bcc4ac27d864800eb1db1d972e Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Antti Määttä <antti.maatta@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r--src/Authoring/Studio/Render/Q3DSTranslation.cpp29
-rw-r--r--src/Authoring/Studio/Render/Q3DSTranslation.h2
-rw-r--r--src/Authoring/Studio/Render/Q3DSTranslators.cpp67
3 files changed, 78 insertions, 20 deletions
diff --git a/src/Authoring/Studio/Render/Q3DSTranslation.cpp b/src/Authoring/Studio/Render/Q3DSTranslation.cpp
index 311fac57..3e102481 100644
--- a/src/Authoring/Studio/Render/Q3DSTranslation.cpp
+++ b/src/Authoring/Studio/Render/Q3DSTranslation.cpp
@@ -608,8 +608,14 @@ void Q3DSTranslation::markPropertyDirty(qt3dsdm::Qt3DSDMInstanceHandle instance,
void Q3DSTranslation::releaseTranslation(qt3dsdm::Qt3DSDMInstanceHandle instance)
{
THandleTranslatorPairList &theTranslators = getTranslatorsForInstance(instance);
- for (int idx = 0, end = theTranslators.size(); idx < end; ++idx)
- m_releaseSet.insert(*theTranslators[idx].second);
+ for (int idx = 0, end = theTranslators.size(); idx < end; ++idx) {
+ // We want to release translators immediately, otherwise it is difficult to ensure
+ // correct order of operations when multiple commands affecting same objects occur
+ // within the same frame.
+ auto translator = theTranslators[idx].second;
+ translator->releaseGraphObjectsRecursive(*this);
+ releaseTranslator(translator);
+ }
m_studioRenderer.RequestRender();
}
@@ -1025,24 +1031,18 @@ void Q3DSTranslation::releaseTranslator(Q3DSGraphObjectTranslator *translator)
m_instanceIdHash.remove(instance);
m_translatorMap.remove(instance);
m_presentation->unlinkObject(graphObject);
+ m_dirtySet.remove(*translator);
delete translator;
delete graphObject;
}
void Q3DSTranslation::clearDirtySet()
{
- for (unsigned int idx = 0; idx < m_releaseSet.size(); ++idx) {
- Q3DSGraphObjectTranslator *translator = m_releaseSet[idx];
- translator->releaseGraphObjectsRecursive(*this);
- releaseTranslator(translator);
- }
for (unsigned int idx = 0; idx < m_dirtySet.size(); ++idx) {
- if (m_reader.IsInstance(m_dirtySet[idx]->instanceHandle())
- && m_dirtySet[idx]->dirty()) {
- m_dirtySet[idx]->pushTranslation(*this);
- }
+ Q3DSGraphObjectTranslator *translator = m_dirtySet[idx];
+ if (m_reader.IsInstance(translator->instanceHandle()) && translator->dirty())
+ translator->pushTranslation(*this);
}
- m_releaseSet.clear();
m_dirtySet.clear();
updateForegroundLayerProperties();
@@ -2360,4 +2360,9 @@ void Q3DSTranslation::editCameraZoomToFit()
m_editCameraInfo.m_position = center - m_editCameraInfo.front() * 600.f;
}
+bool Q3DSTranslation::isHelperLayer(const Q3DSGraphObject *obj) const
+{
+ return m_backgroundLayer == obj || m_foregroundLayer == obj || m_foregroundPickingLayer == obj;
+}
+
}
diff --git a/src/Authoring/Studio/Render/Q3DSTranslation.h b/src/Authoring/Studio/Render/Q3DSTranslation.h
index a15c7036..ad4dbe59 100644
--- a/src/Authoring/Studio/Render/Q3DSTranslation.h
+++ b/src/Authoring/Studio/Render/Q3DSTranslation.h
@@ -182,7 +182,6 @@ private:
// All translator related containers must come after the allocator
TInstanceToTranslatorMap m_translatorMap;
TTranslatorDirtySet m_dirtySet;
- TTranslatorDirtySet m_releaseSet;
Q3DSPresentationData m_presentation_data;
Q3DSScene *m_scene;
Q3DStudio::CGraphIterator m_graphIterator;
@@ -320,6 +319,7 @@ public:
void rotateAlongWidget(const QPoint &inOriginalCoords, const QPoint &inMouseCoords,
CUpdateableDocumentEditor &inEditor);
void editCameraZoomToFit();
+ bool isHelperLayer(const Q3DSGraphObject *obj) const;
};
}
diff --git a/src/Authoring/Studio/Render/Q3DSTranslators.cpp b/src/Authoring/Studio/Render/Q3DSTranslators.cpp
index 752caffb..2db4a74a 100644
--- a/src/Authoring/Studio/Render/Q3DSTranslators.cpp
+++ b/src/Authoring/Studio/Render/Q3DSTranslators.cpp
@@ -815,16 +815,69 @@ void Q3DSSceneTranslator::pushTranslation(Q3DSTranslation &inContext)
Q3DSTranslatorDataModelParser theParser(inContext, instanceHandle());
Q3DSPropertyChangeList list;
ITERATE_Q3DS_SCENE_PROPERTIES
- theItem.removeAllChildNodes();
- int childCount = inContext.assetGraph().GetChildCount(instanceHandle());
+
+ // Check if there are any changes to layer children
+ // First collect a set of existing child objects of the scene, excluding helper layers
+ int oldChildCount = theItem.childCount();
+ QVector<Q3DSGraphObject *> oldChildren;
+ oldChildren.reserve(oldChildCount);
+ for (int i = 0; i < oldChildCount; ++i) {
+ Q3DSGraphObject *obj = theItem.childAtIndex(i);
+ if (!inContext.isHelperLayer(obj))
+ oldChildren << obj;
+ }
+ oldChildCount = oldChildren.size();
+
+ // Collect current children in asset graph
+ int newChildCount = inContext.assetGraph().GetChildCount(instanceHandle());
QVector<Q3DSGraphObjectTranslator *> translators;
- for (long idx = 0; idx < childCount; ++idx) {
- qt3dsdm::Qt3DSDMInstanceHandle child =
- inContext.assetGraph().GetChild(instanceHandle(), idx);
+ translators.reserve(newChildCount);
+ QVector<Q3DSGraphObject *> newChildren;
+ newChildren.reserve(newChildCount);
+ for (long i = 0; i < newChildCount; ++i) {
+ qt3dsdm::Qt3DSDMInstanceHandle child
+ = inContext.assetGraph().GetChild(instanceHandle(), i);
Q3DSGraphObjectTranslator *translator = inContext.getOrCreateTranslator(child);
- theItem.appendChildNode(&translator->graphObject());
- translators << translator;
+ if (translator) { // Script items do not get translators
+ translators << translator;
+ newChildren << &translator->graphObject();
+ }
+ }
+
+ // Remove nodes that have been reordered
+ newChildCount = newChildren.size();
+ for (int newIdx = 0, oldIdx = 0; newIdx < newChildCount && oldIdx < oldChildCount;) {
+ auto newChild = newChildren[newIdx];
+ auto oldChild = oldChildren[oldIdx];
+ if (!oldChildren.contains(newChild)) {
+ ++newIdx;
+ } else {
+ if (oldChild != newChild) {
+ theItem.removeChildNode(oldChild);
+ ++oldIdx;
+ } else {
+ ++oldIdx;
+ ++newIdx;
+ }
+ }
}
+
+ // Now insert new and moved nodes back to correct positions
+ Q3DSGraphObject *nextChild = theItem.firstChild();
+ while (nextChild && inContext.isHelperLayer(nextChild))
+ nextChild = nextChild->nextSibling();
+ for (int newIdx = 0; newIdx < newChildCount; ++newIdx) {
+ auto child = newChildren[newIdx];
+ if (nextChild != child) {
+ if (!nextChild)
+ theItem.appendChildNode(child);
+ else
+ theItem.insertChildNodeBefore(child, nextChild);
+ } else if (nextChild) {
+ nextChild = nextChild->nextSibling();
+ }
+ }
+
theItem.resolveReferences(*inContext.presentation());
for (auto t : qAsConst(translators))
t->pushTranslationIfDirty(inContext);