diff options
author | Ton Roosendaal <ton@blender.org> | 2006-01-02 22:09:37 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-01-02 22:09:37 +0300 |
commit | 0943a0249cc04fbf0f6bddc3df3f83569b5eb7c0 (patch) | |
tree | 51dec78905a3d076291b04fbc6a63e7dc2719ae4 /source/blender | |
parent | c1a4e42a75d16f50972007cf9608998fa207dc21 (diff) |
Orange: enabled thread render for node trees.
Works with groups too! But, discovered a bug with texture nodes inside
of groups... will do that next.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 80 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node_shaders.c | 3 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 9 |
5 files changed, 56 insertions, 39 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 488c64e0a18..f6dcebe86f4 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -99,7 +99,7 @@ void ntreeSocketUseFlags(struct bNodeTree *ntree); void ntreeSolveOrder(struct bNodeTree *ntree); void ntreeBeginExecTree(struct bNodeTree *ntree); -void ntreeExecTree(struct bNodeTree *ntree); +void ntreeExecTree(struct bNodeTree *ntree, void *callerdata, int thread); void ntreeEndExecTree(struct bNodeTree *ntree); void ntreeInitPreview(struct bNodeTree *, int xsize, int ysize); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 1e18fcae0c7..c729fb094ad 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -212,9 +212,6 @@ void ntreeVerifyTypes(bNodeTree *ntree) #pragma mark /* ************** Group stuff ********** */ -/* prototype */ -static void node_group_exec_func(void *data, bNode *node, bNodeStack **in, bNodeStack **out); - bNodeType node_group_typeinfo= { /* type code */ NODE_GROUP, /* name */ "Group", @@ -223,7 +220,7 @@ bNodeType node_group_typeinfo= { /* input sock */ NULL, /* output sock */ NULL, /* storage */ "", - /* execfunc */ node_group_exec_func, + /* execfunc */ NULL, }; @@ -1195,7 +1192,7 @@ static void group_node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in } } -static void node_group_exec_func(void *data, bNode *gnode, bNodeStack **in, bNodeStack **out) +static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNodeStack **in, bNodeStack **out) { bNode *node; bNodeTree *ntree= (bNodeTree *)gnode->id; @@ -1204,21 +1201,20 @@ static void node_group_exec_func(void *data, bNode *gnode, bNodeStack **in, bNod if(ntree==NULL) return; - if(ntree->init & NTREE_EXEC_INIT) { - for(node= ntree->nodes.first; node; node= node->next) { - if(node->typeinfo->execfunc) { - group_node_get_stack(node, ntree->stack, nsin, nsout, in, out); - node->typeinfo->execfunc(data, node, nsin, nsout); - } + stack+= gnode->stack_index; + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->typeinfo->execfunc) { + group_node_get_stack(node, stack, nsin, nsout, in, out); + node->typeinfo->execfunc(data, node, nsin, nsout); } } } -/* stack indices make sure all nodes only write in allocated data, for making it thread safe */ -/* per tree (and per group) unique indices are created */ -/* the index_ext we need to be able to map from groups to the group-node own stack */ - -void ntreeBeginExecTree(bNodeTree *ntree) +/* recursively called for groups */ +/* we set all trees on own local indices, but put a total counter + in the groups, so each instance of a group has own stack */ +static int ntree_begin_exec_tree(bNodeTree *ntree, int totindex) { bNode *node; bNodeSocket *sock; @@ -1226,8 +1222,6 @@ void ntreeBeginExecTree(bNodeTree *ntree) if((ntree->init & NTREE_TYPE_INIT)==0) ntreeInitTypes(ntree); - if(ntree->init & NTREE_EXEC_INIT) - return; /* create indices for stack, check preview */ for(node= ntree->nodes.first; node; node= node->next) { @@ -1246,7 +1240,8 @@ void ntreeBeginExecTree(bNodeTree *ntree) if(node->type==NODE_GROUP) { if(node->id) { - ntreeBeginExecTree((bNodeTree *)node->id); + node->stack_index= totindex; + totindex+= ntree_begin_exec_tree((bNodeTree *)node->id, totindex); /* copy internal data from internal nodes to own input sockets */ for(sock= node->inputs.first; sock; sock= sock->next) { @@ -1257,12 +1252,31 @@ void ntreeBeginExecTree(bNodeTree *ntree) } } } + + return totindex + index; +} + +/* 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! */ +/* per tree (and per group) unique indices are created */ +/* the index_ext we need to be able to map from groups to the group-node own stack */ + +void ntreeBeginExecTree(bNodeTree *ntree) +{ + int index; + + /* goes recursive over all groups */ + index= ntree_begin_exec_tree(ntree, 0); + if(index) { bNodeStack *ns; int a; ns=ntree->stack= MEM_callocN(index*sizeof(bNodeStack), "node stack"); for(a=0; a<index; a++, ns++) ns->hasinput= 1; + + ntree->stack1= MEM_dupallocN(ntree->stack); } ntree->init |= NTREE_EXEC_INIT; @@ -1270,23 +1284,16 @@ void ntreeBeginExecTree(bNodeTree *ntree) void ntreeEndExecTree(bNodeTree *ntree) { - bNode *node; if(ntree->init & NTREE_EXEC_INIT) { if(ntree->stack) { MEM_freeN(ntree->stack); ntree->stack= NULL; + MEM_freeN(ntree->stack1); + ntree->stack1= NULL; } ntree->init &= ~NTREE_EXEC_INIT; - - for(node= ntree->nodes.first; node; node= node->next) { - if(node->type==NODE_GROUP) { - if(node->id) { - ntreeEndExecTree((bNodeTree *)node->id); - } - } - } } } @@ -1308,18 +1315,29 @@ static void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNod } /* nodes are presorted, so exec is in order of list */ -void ntreeExecTree(bNodeTree *ntree) +void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread) { bNode *node; bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeStack *stack; /* only when initialized */ if(ntree->init & NTREE_EXEC_INIT) { + + if(thread) + stack= ntree->stack1; + else + stack= ntree->stack; + for(node= ntree->nodes.first; node; node= node->next) { if(node->typeinfo->execfunc) { - node_get_stack(node, ntree->stack, nsin, nsout); - node->typeinfo->execfunc(ntree->data, node, nsin, nsout); + node_get_stack(node, stack, nsin, nsout); + node->typeinfo->execfunc(callerdata, node, nsin, nsout); + } + else if(node->type==NODE_GROUP && node->id) { + node_get_stack(node, stack, nsin, nsout); + node_group_execute(stack, callerdata, node, nsin, nsout); } } } diff --git a/source/blender/blenkernel/intern/node_shaders.c b/source/blender/blenkernel/intern/node_shaders.c index fc9356dce94..22375158b84 100644 --- a/source/blender/blenkernel/intern/node_shaders.c +++ b/source/blender/blenkernel/intern/node_shaders.c @@ -618,9 +618,8 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr) /* convert caller data to struct */ scd.shi= shi; scd.shr= shr; - ntree->data= &scd; - ntreeExecTree(ntree); + ntreeExecTree(ntree, &scd, shi->ys & 1); /* threads */ } /* go over all used Geometry and Texture nodes, and return a texco flag */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9c53766cfc4..970d0306fd6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1258,7 +1258,6 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) bNodeLink *link; ntree->init= 0; /* to set callbacks */ - ntree->data= NULL; /* safety only */ ntree->owntype= NULL; link_list(fd, &ntree->nodes); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index c20022b48ef..9ebadb6b86d 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -106,7 +106,8 @@ typedef struct bNode { short type, flag; short done, level; /* both for dependency and sorting */ short lasty, menunr; /* lasty: check preview render status, menunr: browse ID blocks */ - short pad1, pad2; + short stack_index; /* for groupnode, offset in global caller stack */ + short pad; ListBase inputs, outputs; struct ID *id; /* optional link to libdata */ @@ -116,7 +117,7 @@ typedef struct bNode { float locx, locy; /* root offset for drawing */ float width, miniwidth; short custom1, custom2; /* to be abused for buttons */ - int pad3; + int pad1; rctf totr; /* entire boundbox */ rctf butr; /* optional buttons area */ @@ -152,8 +153,8 @@ typedef struct bNodeTree { ListBase nodes, links; - void *data; /* custom data, set by execute caller, no read/write handling */ - bNodeStack *stack; /* stack is only while executing, no read/write */ + bNodeStack *stack; /* stack is only while executing, no read/write in file */ + bNodeStack *stack1; /* for other thread, easy to expand though... */ int type, init; /* set init on fileread */ int cur_index, pad; /* sockets in groups have unique identifiers, adding new sockets always will increase this counter */ |