diff options
Diffstat (limited to 'source/blender/nodes/composite/node_composite_tree.c')
-rw-r--r-- | source/blender/nodes/composite/node_composite_tree.c | 436 |
1 files changed, 1 insertions, 435 deletions
diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 03462738d58..a6592b47e87 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -51,7 +51,6 @@ #include "BKE_tracking.h" #include "node_common.h" -#include "node_exec.h" #include "node_util.h" #include "PIL_time.h" @@ -95,9 +94,6 @@ static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node) for (sock= node->outputs.first; sock; sock= sock->next) { if (sock->cache) { -#ifdef WITH_COMPOSITOR_LEGACY - free_compbuf(sock->cache); -#endif sock->cache= NULL; } } @@ -161,9 +157,6 @@ static void localize(bNodeTree *localtree, bNodeTree *ntree) for (sock= node->outputs.first; sock; sock= sock->next) { sock->new_sock->cache= sock->cache; -#ifdef WITH_COMPOSITOR_LEGACY - compbuf_set_node(sock->new_sock->cache, node->new_node); -#endif sock->cache= NULL; sock->new_sock->new_sock= sock; } @@ -239,9 +232,6 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree) for (lsock= lnode->outputs.first; lsock; lsock= lsock->next) { if (ntreeOutputExists(lnode->new_node, lsock->new_sock)) { lsock->new_sock->cache= lsock->cache; -#ifdef WITH_COMPOSITOR_LEGACY - compbuf_set_node(lsock->new_sock->cache, lnode->new_node); -#endif lsock->cache= NULL; lsock->new_sock= NULL; } @@ -277,421 +267,6 @@ bNodeTreeType ntreeType_Composite = { }; -/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes. - * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees. - */ -struct bNodeTreeExec *ntreeCompositBeginExecTree(bNodeTree *ntree, int use_tree_data) -{ - bNodeTreeExec *exec; - bNode *node; - bNodeSocket *sock; - - if (use_tree_data) { - /* XXX hack: prevent exec data from being generated twice. - * this should be handled by the renderer! - */ - if (ntree->execdata) - return ntree->execdata; - } - - /* ensures only a single output node is enabled */ - ntreeSetOutput(ntree); - - exec = ntree_exec_begin(ntree); - - for (node= exec->nodetree->nodes.first; node; node= node->next) { - /* initialize needed for groups */ - node->exec= 0; - - for (sock= node->outputs.first; sock; sock= sock->next) { - bNodeStack *ns= node_get_socket_stack(exec->stack, sock); - if (ns && sock->cache) { - ns->data= sock->cache; - sock->cache= NULL; - } - } - /* cannot initialize them while using in threads */ - if (ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) { - curvemapping_initialize(node->storage); - if (node->type==CMP_NODE_CURVE_RGB) - curvemapping_premultiply(node->storage, 0); - } - } - - if (use_tree_data) { - /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes, - * which only store the ntree pointer. Should be fixed at some point! - */ - ntree->execdata = exec; - } - - return exec; -} - -/* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes. - * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees. - */ -void ntreeCompositEndExecTree(bNodeTreeExec *exec, int use_tree_data) -{ - if (exec) { - bNodeTree *ntree= exec->nodetree; - bNode *node; - bNodeStack *ns; - - for (node= exec->nodetree->nodes.first; node; node= node->next) { - bNodeSocket *sock; - - for (sock= node->outputs.first; sock; sock= sock->next) { - ns = node_get_socket_stack(exec->stack, sock); - if (ns && ns->data) { - sock->cache= ns->data; - ns->data= NULL; - } - } - if (node->type==CMP_NODE_CURVE_RGB) - curvemapping_premultiply(node->storage, 1); - - node->need_exec= 0; - } - - ntree_exec_end(exec); - - if (use_tree_data) { - /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */ - ntree->execdata = NULL; - } - } -} - -#ifdef WITH_COMPOSITOR -#ifdef WITH_COMPOSITOR_LEGACY - -/* ***************************** threaded version for execute composite nodes ************* */ -/* these are nodes without input, only giving values */ -/* or nodes with only value inputs */ -static int node_only_value(bNode *node) -{ - bNodeSocket *sock; - - if (ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB)) - return 1; - - /* doing this for all node types goes wrong. memory free errors */ - if (node->inputs.first && node->type==CMP_NODE_MAP_VALUE) { - int retval= 1; - for (sock= node->inputs.first; sock; sock= sock->next) { - if (sock->link) - retval &= node_only_value(sock->link->fromnode); - } - return retval; - } - return 0; -} - -/* not changing info, for thread callback */ -typedef struct ThreadData { - bNodeStack *stack; - RenderData *rd; -} ThreadData; - -static void *exec_composite_node(void *nodeexec_v) -{ - bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ - bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ - bNodeExec *nodeexec= nodeexec_v; - bNode *node= nodeexec->node; - ThreadData *thd= (ThreadData *)node->threaddata; - - node_get_stack(node, thd->stack, nsin, nsout); - - if (node->typeinfo->execfunc) - node->typeinfo->execfunc(thd->rd, node, nsin, nsout); - else if (node->typeinfo->newexecfunc) - node->typeinfo->newexecfunc(thd->rd, 0, node, nodeexec->data, nsin, nsout); - - node->exec |= NODE_READY; - return NULL; -} - -/* return total of executable nodes, for timecursor */ -static int setExecutableNodes(bNodeTreeExec *exec, ThreadData *thd) -{ - bNodeTree *ntree = exec->nodetree; - bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ - bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ - bNodeExec *nodeexec; - bNode *node; - bNodeSocket *sock; - int n, totnode= 0, group_edit= 0; - - /* if we are in group edit, viewer nodes get skipped when group has viewer */ - for (node= ntree->nodes.first; node; node= node->next) - if (node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT)) - if (ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER)) - group_edit= 1; - - /* NB: using the exec data list here to have valid dependency sort */ - for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { - int a; - node = nodeexec->node; - - node_get_stack(node, exec->stack, nsin, nsout); - - /* test the outputs */ - /* skip value-only nodes (should be in type!) */ - if (!node_only_value(node)) { - for (a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { - if (nsout[a]->data==NULL && nsout[a]->hasoutput) { - node->need_exec= 1; - break; - } - } - } - - /* test the inputs */ - for (a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { - /* skip viewer nodes in bg render or group edit */ - if ( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit)) - node->need_exec= 0; - /* is sock in use? */ - else if (sock->link) { - bNodeLink *link= sock->link; - - /* this is the test for a cyclic case */ - if (link->fromnode==NULL || link->tonode==NULL); - else if (link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) { - if (link->fromnode->need_exec) { - node->need_exec= 1; - break; - } - } - else { - node->need_exec= 0; - printf("Node %s skipped, cyclic dependency\n", node->name); - } - } - } - - if (node->need_exec) { - - /* free output buffers */ - for (a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { - if (nsout[a]->data) { - free_compbuf(nsout[a]->data); - nsout[a]->data= NULL; - } - } - totnode++; - /* printf("node needs exec %s\n", node->name); */ - - /* tag for getExecutableNode() */ - node->exec= 0; - } - else { - /* tag for getExecutableNode() */ - node->exec= NODE_READY|NODE_FINISHED|NODE_SKIPPED; - - } - } - - /* last step: set the stack values for only-value nodes */ - /* just does all now, compared to a full buffer exec this is nothing */ - if (totnode) { - for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { - node = nodeexec->node; - if (node->need_exec==0 && node_only_value(node)) { - if (node->typeinfo->execfunc) { - node_get_stack(node, exec->stack, nsin, nsout); - node->typeinfo->execfunc(thd->rd, node, nsin, nsout); - } - } - } - } - - return totnode; -} - -/* while executing tree, free buffers from nodes that are not needed anymore */ -static void freeExecutableNode(bNodeTreeExec *exec) -{ - /* node outputs can be freed when: - * - not a render result or image node - * - when node outputs go to nodes all being set NODE_FINISHED - */ - bNodeTree *ntree = exec->nodetree; - bNodeExec *nodeexec; - bNode *node; - bNodeSocket *sock; - int n; - - /* set exec flag for finished nodes that might need freed */ - for (node= ntree->nodes.first; node; node= node->next) { - if (node->type!=CMP_NODE_R_LAYERS) - if (node->exec & NODE_FINISHED) - node->exec |= NODE_FREEBUFS; - } - /* clear this flag for input links that are not done yet. - * Using the exec data for valid dependency sort. - */ - for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { - node = nodeexec->node; - if ((node->exec & NODE_FINISHED)==0) { - for (sock= node->inputs.first; sock; sock= sock->next) - if (sock->link) - sock->link->fromnode->exec &= ~NODE_FREEBUFS; - } - } - /* now we can free buffers */ - for (node= ntree->nodes.first; node; node= node->next) { - if (node->exec & NODE_FREEBUFS) { - for (sock= node->outputs.first; sock; sock= sock->next) { - bNodeStack *ns= node_get_socket_stack(exec->stack, sock); - if (ns && ns->data) { - free_compbuf(ns->data); - ns->data= NULL; - // printf("freed buf node %s\n", node->name); - } - } - } - } -} - -static bNodeExec *getExecutableNode(bNodeTreeExec *exec) -{ - bNodeExec *nodeexec; - bNodeSocket *sock; - int n; - - for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { - if (nodeexec->node->exec==0) { - /* input sockets should be ready */ - for (sock= nodeexec->node->inputs.first; sock; sock= sock->next) { - if (sock->link && sock->link->fromnode) - if ((sock->link->fromnode->exec & NODE_READY)==0) - break; - } - if (sock==NULL) - return nodeexec; - } - } - return NULL; -} - -/* check if texture nodes need exec or end */ -static void ntree_composite_texnode(bNodeTree *ntree, int init) -{ - bNode *node; - - for (node= ntree->nodes.first; node; node= node->next) { - if (node->type==CMP_NODE_TEXTURE && node->id) { - Tex *tex= (Tex *)node->id; - if (tex->nodetree && tex->use_nodes) { - /* has internal flag to detect it only does it once */ - if (init) { - if (!tex->nodetree->execdata) - tex->nodetree->execdata = ntreeTexBeginExecTree(tex->nodetree, 1); - } - else - ntreeTexEndExecTree(tex->nodetree->execdata, 1); - tex->nodetree->execdata = NULL; - } - } - } - -} - -/* optimized tree execute test for compositing */ -static void ntreeCompositExecTreeOld(bNodeTree *ntree, RenderData *rd, int do_preview) -{ - bNodeExec *nodeexec; - bNode *node; - ListBase threads; - ThreadData thdata; - int totnode, curnode, rendering = TRUE, n; - bNodeTreeExec *exec = ntree->execdata; - - if (do_preview) - ntreeInitPreview(ntree, 0, 0); - - if (!ntree->execdata) { - /* XXX this is the top-level tree, so we use the ntree->execdata pointer. */ - exec = ntreeCompositBeginExecTree(ntree, 1); - } - ntree_composite_texnode(ntree, 1); - - /* prevent unlucky accidents */ - if (G.background) - rd->scemode &= ~R_COMP_CROP; - - /* setup callerdata for thread callback */ - thdata.rd= rd; - thdata.stack= exec->stack; - - /* fixed seed, for example noise texture */ - BLI_srandom(rd->cfra); - - /* sets need_exec tags in nodes */ - curnode = totnode= setExecutableNodes(exec, &thdata); - - BLI_init_threads(&threads, exec_composite_node, rd->threads); - - while (rendering) { - - if (BLI_available_threads(&threads)) { - nodeexec= getExecutableNode(exec); - if (nodeexec) { - node = nodeexec->node; - if (ntree->progress && totnode) - ntree->progress(ntree->prh, (1.0f - curnode/(float)totnode)); - if (ntree->stats_draw) { - char str[128]; - BLI_snprintf(str, sizeof(str), "Compositing %d %s", curnode, node->name); - ntree->stats_draw(ntree->sdh, str); - } - curnode--; - - node->threaddata = &thdata; - node->exec= NODE_PROCESSING; - BLI_insert_thread(&threads, nodeexec); - } - else - PIL_sleep_ms(50); - } - else - PIL_sleep_ms(50); - - rendering= 0; - /* test for ESC */ - if (ntree->test_break && ntree->test_break(ntree->tbh)) { - for (node= ntree->nodes.first; node; node= node->next) - node->exec |= NODE_READY; - } - - /* check for ready ones, and if we need to continue */ - for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { - node = nodeexec->node; - if (node->exec & NODE_READY) { - if ((node->exec & NODE_FINISHED)==0) { - BLI_remove_thread(&threads, nodeexec); /* this waits for running thread to finish btw */ - node->exec |= NODE_FINISHED; - - /* freeing unused buffers */ - if (rd->scemode & R_COMP_FREE) - freeExecutableNode(exec); - } - } - else rendering= 1; - } - } - - BLI_end_threads(&threads); - - /* XXX top-level tree uses the ntree->execdata pointer */ - ntreeCompositEndExecTree(exec, 1); -} -#endif /* WITH_COMPOSITOR_LEGACY */ -#endif /* WITH_COMPOSITOR */ - void *COM_linker_hack = NULL; void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int rendering, int do_preview, @@ -699,16 +274,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int rendering, int const ColorManagedDisplaySettings *display_settings) { #ifdef WITH_COMPOSITOR -#ifdef WITH_COMPOSITOR_LEGACY - if (G.debug_value == 200) - { - ntreeCompositExecTreeOld(ntree, rd, do_preview); - } - else -#endif - { - COM_execute(rd, ntree, rendering, view_settings, display_settings); - } + COM_execute(rd, ntree, rendering, view_settings, display_settings); #else (void)ntree, (void)rd, (void)rendering, (void)do_preview; (void)view_settings, (void)display_settings; |