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:
Diffstat (limited to 'source/blender/blenkernel/intern/node.c')
-rw-r--r--source/blender/blenkernel/intern/node.c197
1 files changed, 174 insertions, 23 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index a1f0c4095e2..3e99f83a8f6 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -38,6 +38,7 @@
#include "BKE_blender.h"
#include "BKE_colortools.h"
#include "BKE_global.h"
+#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -282,7 +283,7 @@ static void group_verify_own_indices(bNodeTree *ngroup)
if(sock->own_index==0 && sock->intern==0)
sock->own_index= ++(ngroup->cur_index);
}
- printf("internal index %d\n", ngroup->cur_index);
+// printf("internal index %d\n", ngroup->cur_index);
}
@@ -776,8 +777,10 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
sock->own_index= 0;
duplicatelist(&nnode->outputs, &node->outputs);
- for(sock= nnode->outputs.first; sock; sock= sock->next)
+ for(sock= nnode->outputs.first; sock; sock= sock->next) {
sock->own_index= 0;
+ sock->ns.data= NULL;
+ }
if(nnode->id)
nnode->id->us++;
@@ -850,8 +853,10 @@ static void node_unlink_node(bNodeTree *ntree, bNode *node)
for(link= ntree->links.first; link; link= next) {
next= link->next;
- if(link->fromnode==node)
+ if(link->fromnode==node) {
lb= &node->outputs;
+ NodeTagChanged(ntree, link->tonode);
+ }
else if(link->tonode==node)
lb= &node->inputs;
else
@@ -869,6 +874,16 @@ static void node_unlink_node(bNodeTree *ntree, bNode *node)
}
}
+static void composit_free_sockets(bNode *node)
+{
+ bNodeSocket *sock;
+
+ for(sock= node->outputs.first; sock; sock= sock->next) {
+ if(sock->ns.data)
+ free_compbuf(sock->ns.data);
+ }
+}
+
void nodeFreeNode(bNodeTree *ntree, bNode *node)
{
node_unlink_node(ntree, node);
@@ -877,6 +892,8 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
if(node->id)
node->id->us--;
+ if(ntree->type==NTREE_COMPOSIT)
+ composit_free_sockets(node);
BLI_freelistN(&node->inputs);
BLI_freelistN(&node->outputs);
@@ -1207,6 +1224,22 @@ void ntreeSolveOrder(bNodeTree *ntree)
might be different for editor or for "real" use... */
}
+/* should be callback! */
+void NodeTagChanged(bNodeTree *ntree, bNode *node)
+{
+ if(ntree->type==NTREE_COMPOSIT) {
+ bNodeSocket *sock;
+
+ for(sock= node->outputs.first; sock; sock= sock->next) {
+ if(sock->ns.data) {
+ free_compbuf(sock->ns.data);
+ sock->ns.data= NULL;
+ }
+ }
+ node->need_exec= 1;
+ }
+}
+
#pragma mark /* *************** preview *********** */
/* if node->preview, then we assume the rect to exist */
@@ -1362,6 +1395,54 @@ static int ntree_begin_exec_tree(bNodeTree *ntree)
return index;
}
+/* copy socket compbufs to stack */
+static void composit_begin_exec(bNodeTree *ntree)
+{
+ bNode *node;
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ bNodeSocket *sock;
+ for(sock= node->outputs.first; sock; sock= sock->next) {
+ if(sock->ns.data) {
+ bNodeStack *ns= ntree->stack + sock->stack_index;
+
+ ns->data= sock->ns.data;
+ sock->ns.data= NULL;
+ }
+ }
+ }
+}
+
+/* copy stack compbufs to sockets */
+static void composit_end_exec(bNodeTree *ntree)
+{
+ extern void print_compbuf(char *str, struct CompBuf *cbuf);
+ bNode *node;
+ bNodeStack *ns;
+ int a;
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ bNodeSocket *sock;
+
+ for(sock= node->outputs.first; sock; sock= sock->next) {
+ ns= ntree->stack + sock->stack_index;
+ if(ns->data) {
+ sock->ns.data= ns->data;
+ ns->data= NULL;
+ }
+ }
+ node->need_exec= 0;
+ }
+
+ for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++) {
+ if(ns->data) {
+ print_compbuf("error: buf hanging in stack", ns->data);
+ free_compbuf(ns->data);
+ }
+ }
+
+}
+
/* stack indices make sure all nodes only write in allocated data, for making it thread safe */
/* only root tree gets the stack, to enable instances to have own stack entries */
/* only two threads now! */
@@ -1385,7 +1466,8 @@ void ntreeBeginExecTree(bNodeTree *ntree)
/* tag inputs, the get_stack() gives own socket stackdata if not in use */
for(a=0; a<ntree->stacksize; a++, ns++) ns->hasinput= 1;
- /* tag outputs, so we know when we can skip operations */
+ /* tag used outputs, so we know when we can skip operations */
+ /* hrms... groups... */
for(node= ntree->nodes.first; node; node= node->next) {
bNodeSocket *sock;
for(sock= node->inputs.first; sock; sock= sock->next) {
@@ -1395,8 +1477,10 @@ void ntreeBeginExecTree(bNodeTree *ntree)
}
}
}
-
- ntree->stack1= MEM_dupallocN(ntree->stack);
+ if(ntree->type==NTREE_COMPOSIT)
+ composit_begin_exec(ntree);
+ else
+ ntree->stack1= MEM_dupallocN(ntree->stack);
}
ntree->init |= NTREE_EXEC_INIT;
@@ -1407,25 +1491,17 @@ void ntreeEndExecTree(bNodeTree *ntree)
if(ntree->init & NTREE_EXEC_INIT) {
- if(ntree->stack) {
-
- /* another callback candidate! */
- if(ntree->type==NTREE_COMPOSIT) {
- bNodeStack *ns;
- int a;
-
- for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++)
- if(ns->data)
- free_compbuf(ns->data);
- for(ns= ntree->stack1, a=0; a<ntree->stacksize; a++, ns++)
- if(ns->data)
- free_compbuf(ns->data);
- }
+ /* another callback candidate! */
+ if(ntree->type==NTREE_COMPOSIT)
+ composit_end_exec(ntree);
+
+ if(ntree->stack)
MEM_freeN(ntree->stack);
- ntree->stack= NULL;
+ ntree->stack= NULL;
+
+ if(ntree->stack1)
MEM_freeN(ntree->stack1);
- ntree->stack1= NULL;
- }
+ ntree->stack1= NULL;
ntree->init &= ~NTREE_EXEC_INIT;
}
@@ -1477,3 +1553,78 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
}
}
+/* optimized tree execute test for compositing */
+void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
+{
+ bNode *node;
+ bNodeSocket *sock;
+ bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
+ bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
+ bNodeStack *stack;
+ int totnode;
+
+ if(ntree==NULL) return;
+
+ totnode= BLI_countlist(&ntree->nodes);
+
+ if(do_preview)
+ ntreeInitPreview(ntree, 0, 0);
+
+ ntreeBeginExecTree(ntree);
+
+ stack= ntree->stack;
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->typeinfo->execfunc) {
+ int a;
+
+ node_get_stack(node, stack, nsin, nsout);
+
+ /* test the inputs */
+ for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
+ /* is sock in use? */
+ if(sock->link) {
+ if(nsin[a]->data==NULL || sock->link->fromnode->need_exec) {
+ node->need_exec= 1;
+ break;
+ }
+ }
+ }
+
+ /* test the outputs */
+ 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;
+ }
+ }
+ 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;
+ }
+ }
+ if(ntree->timecursor)
+ ntree->timecursor(totnode);
+
+ printf("exec node %s\n", node->name);
+ node->typeinfo->execfunc(rd, node, nsin, nsout);
+ }
+ }
+ else if(node->type==NODE_GROUP && node->id) {
+ node_get_stack(node, stack, nsin, nsout);
+ node_group_execute(stack, rd, node, nsin, nsout);
+ }
+ totnode--;
+ }
+
+
+ ntreeEndExecTree(ntree);
+
+ free_unused_animimages();
+
+}
+