diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-09-30 14:09:39 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-10-01 17:02:14 +0300 |
commit | 5c79f2d0fba7360488e591922f91aa858bd8d603 (patch) | |
tree | 4b1550dec65baa6b404447fd1cde57d3125305a4 /source/blender/blenkernel/intern/node.c | |
parent | cba1bdc40071cbdb90122db121a643f761edeb36 (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.c | 51 |
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) |