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->flag & NODE_MUTED) && (!node_only_value(node))) { /* viewers we execute, for feedback to user */ if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) node->typeinfo->execfunc(thd->rd, node, nsin, nsout); else node_compo_pass_on(node, nsin, nsout); } else 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; }
bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread) { bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ bNodeExec *nodeexec; bNode *node; int n; /* nodes are presorted, so exec is in order of list */ for (n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { node = nodeexec->node; if (node->need_exec) { node_get_stack(node, nts->stack, nsin, nsout); /* Handle muted nodes... * If the mute func is not set, assume the node should never be muted, * and hence execute it! */ // if (node->typeinfo->compatibility == NODE_NEW_SHADING) // return false; if (node->typeinfo->execfunc) node->typeinfo->execfunc(callerdata, thread, node, &nodeexec->data, nsin, nsout); } } /* signal to that all went OK, for render */ return true; }
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; }
void ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread) { bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ bNodeExec *nodeexec; bNode *node; int n; /* nodes are presorted, so exec is in order of list */ for(n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { node = nodeexec->node; if(node->need_exec) { node_get_stack(node, nts->stack, nsin, nsout); if(node->typeinfo->execfunc) node->typeinfo->execfunc(callerdata, node, nsin, nsout); else if (node->typeinfo->newexecfunc) node->typeinfo->newexecfunc(callerdata, thread, node, nodeexec->data, nsin, nsout); } } }
void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs, short compatibility) { bNodeExec *nodeexec; bNode *node; int n; bNodeStack *stack; bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ GPUNodeStack gpuin[MAX_SOCKET + 1], gpuout[MAX_SOCKET + 1]; bool do_it; stack = exec->stack; for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { node = nodeexec->node; do_it = false; /* for groups, only execute outputs for edited group */ if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) { if (node->typeinfo->compatibility & compatibility) if (do_outputs && (node->flag & NODE_DO_OUTPUT)) do_it = true; } else { do_it = true; } if (do_it) { if (node->typeinfo->gpufunc) { node_get_stack(node, stack, nsin, nsout); gpu_stack_from_data_list(gpuin, &node->inputs, nsin); gpu_stack_from_data_list(gpuout, &node->outputs, nsout); if (node->typeinfo->gpufunc(mat, node, &nodeexec->data, gpuin, gpuout)) data_from_gpu_stack_list(&node->outputs, nsout, gpuout); } } } }
/* 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; }