Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2019-09-30 14:09:39 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-10-01 17:02:14 +0300
commit5c79f2d0fba7360488e591922f91aa858bd8d603 (patch)
tree4b1550dec65baa6b404447fd1cde57d3125305a4 /source/blender/blenkernel/intern/node.c
parentcba1bdc40071cbdb90122db121a643f761edeb36 (diff)
Fix T70325 EEVEE: Performance regression with large nodetrees
This was caused by nodeChainIter which is not linear complexity. Introduce nodeChainIterBackwards to iterate backwards faster.
Diffstat (limited to 'source/blender/blenkernel/intern/node.c')
-rw-r--r--source/blender/blenkernel/intern/node.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 92c15e05aee..0ef35bd3d06 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -947,6 +947,57 @@ void nodeChainIter(const bNodeTree *ntree,
}
}
+static void iter_backwards_ex(const bNodeTree *ntree,
+ const bNode *node_start,
+ bool (*callback)(bNode *, bNode *, void *),
+ void *userdata)
+{
+ LISTBASE_FOREACH (bNodeSocket *, sock, &node_start->inputs) {
+ bNodeLink *link = sock->link;
+ if (link == NULL) {
+ continue;
+ }
+ if ((link->flag & NODE_LINK_VALID) == 0) {
+ /* Skip links marked as cyclic. */
+ continue;
+ }
+ if (link->fromnode->iter_flag) {
+ /* Only iter on nodes once. */
+ continue;
+ }
+ else {
+ link->fromnode->iter_flag = 1;
+ }
+
+ if (!callback(link->fromnode, link->tonode, userdata)) {
+ return;
+ }
+ iter_backwards_ex(ntree, link->fromnode, callback, userdata);
+ }
+}
+
+/**
+ * Iterate over a chain of nodes, starting with \a node_start, executing
+ * \a callback for each node (which can return false to end iterator).
+ *
+ * Faster than nodeChainIter. Iter only once per node.
+ *
+ * \note Needs updated socket links (ntreeUpdateTree).
+ * \note Recursive
+ */
+void nodeChainIterBackwards(const bNodeTree *ntree,
+ const bNode *node_start,
+ bool (*callback)(bNode *, bNode *, void *),
+ void *userdata)
+{
+ /* Reset flag. */
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ node->iter_flag = 0;
+ }
+
+ iter_backwards_ex(ntree, node_start, callback, userdata);
+}
+
/**
* Iterate over all parents of \a node, executing \a callback for each parent
* (which can return false to end iterator)