[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [31781] branches/particles-2010/source/ blender: Replaced the stack and threadstack variables in node trees with a generic void* execdata .

Lukas Toenne lukas.toenne at googlemail.com
Mon Sep 6 10:13:28 CEST 2010


Revision: 31781
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=31781
Author:   lukastoenne
Date:     2010-09-06 10:13:28 +0200 (Mon, 06 Sep 2010)

Log Message:
-----------
Replaced the stack and threadstack variables in node trees with a generic void* execdata. This is created according to the tree type from the beginExec callback and holds the former stack variable and all other execution-specific data. It could be removed from the node tree itself in the future to finally separate execution from the data model completely.

Modified Paths:
--------------
    branches/particles-2010/source/blender/blenkernel/BKE_node.h
    branches/particles-2010/source/blender/blenkernel/intern/node.c
    branches/particles-2010/source/blender/makesdna/DNA_node_types.h
    branches/particles-2010/source/blender/nodes/intern/node_tree_composite.c
    branches/particles-2010/source/blender/nodes/intern/node_tree_shader.c
    branches/particles-2010/source/blender/nodes/intern/node_tree_simulation.c
    branches/particles-2010/source/blender/nodes/intern/node_tree_texture.c
    branches/particles-2010/source/blender/nodes/intern/node_util.c
    branches/particles-2010/source/blender/nodes/intern/node_util.h

Modified: branches/particles-2010/source/blender/blenkernel/BKE_node.h
===================================================================
--- branches/particles-2010/source/blender/blenkernel/BKE_node.h	2010-09-06 07:26:21 UTC (rev 31780)
+++ branches/particles-2010/source/blender/blenkernel/BKE_node.h	2010-09-06 08:13:28 UTC (rev 31781)
@@ -167,9 +167,9 @@
 	void (*freeCache)(struct bNodeTree *ntree);
 	void (*freeNodeCache)(struct bNodeTree *ntree, struct bNode *node);
 	void (*foreachNodeTree)(struct Main *main, void *calldata, bNodeTreeCallback func);		/* iteration over all node trees */
-	void (*beginExec)(struct bNodeTree *ntree);
-	void (*endExec)(struct bNodeTree *ntree);
-	void (*exec)(struct bNodeTree *ntree, void *callerdata, int thread);
+	void *(*beginExec)(struct bNodeTree *ntree);
+	void (*endExec)(struct bNodeTree *ntree, void *execdata);
+	void (*exec)(struct bNodeTree *ntree, void *execdata, void *callerdata, int thread);
 
 	/* called when a node is updated (e.g. linked) in the editor.
 	 * individual node update calls should be made internally if this function is defined! */

Modified: branches/particles-2010/source/blender/blenkernel/intern/node.c
===================================================================
--- branches/particles-2010/source/blender/blenkernel/intern/node.c	2010-09-06 07:26:21 UTC (rev 31780)
+++ branches/particles-2010/source/blender/blenkernel/intern/node.c	2010-09-06 08:13:28 UTC (rev 31781)
@@ -2064,26 +2064,25 @@
 	bNodeTreeTypeInfo *treetype;
 
 	/* let's make it sure */
-	if(ntree->init & NTREE_EXEC_INIT)
+	if(ntree->execdata)
 		return;
 
 	treetype = ntreeGetTypeInfo(ntree->type);
 	if (treetype->beginExec)
-		treetype->beginExec(ntree);
-	
-	ntree->init |= NTREE_EXEC_INIT;
+		ntree->execdata = treetype->beginExec(ntree);
 }
 
 void ntreeEndExecTree(bNodeTree *ntree)
 {
 	bNodeTreeTypeInfo *treetype;
 	
-	if(ntree->init & NTREE_EXEC_INIT) {
+	if(ntree->execdata) {
 		treetype = ntreeGetTypeInfo(ntree->type);
 		if (treetype->endExec)
-			treetype->endExec(ntree);
+			treetype->endExec(ntree, ntree->execdata);
 		
-		ntree->init &= ~NTREE_EXEC_INIT;
+		MEM_freeN(ntree->execdata);
+		ntree->execdata = NULL;
 	}
 }
 
@@ -2092,8 +2091,14 @@
 {
 	bNodeTreeTypeInfo *treetype= ntreeGetTypeInfo(ntree->type);
 	
+	/* let's make it sure */
+	if(!ntree->execdata)
+		ntreeBeginExecTree(ntree);
+	if(!ntree->execdata)
+		return;
+
 	if (treetype->exec)
-		treetype->exec(ntree, callerdata, thread);
+		treetype->exec(ntree, ntree->execdata, callerdata, thread);
 }
 
 
@@ -2332,16 +2337,18 @@
 
 void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat)
 {
+	bNodeExecData *execdata;
 	bNode *node;
 	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];
 
-	if((ntree->init & NTREE_EXEC_INIT)==0)
+	if(!ntree->execdata)
 		ntreeBeginExecTree(ntree);
+	execdata = (bNodeExecData*)ntree->execdata;
 
-	stack= ntree->stack;
+	stack= execdata->stack;
 
 	for(node= ntree->nodes.first; node; node= node->next) {
 		if(node->typeinfo->gpufunc) {

Modified: branches/particles-2010/source/blender/makesdna/DNA_node_types.h
===================================================================
--- branches/particles-2010/source/blender/makesdna/DNA_node_types.h	2010-09-06 07:26:21 UTC (rev 31780)
+++ branches/particles-2010/source/blender/makesdna/DNA_node_types.h	2010-09-06 08:13:28 UTC (rev 31781)
@@ -205,22 +205,24 @@
 	
 	ListBase nodes, links;
 	
-	/* TODO put all execution-specific data into treetype structs, addressed by this pointer */
-	void *execdata;				/* data used during execution */
-	
-	bNodeStack *stack;				/* stack is only while executing, no read/write in file */
-	struct ListBase *threadstack;	/* same as above */
-	
 	int type, init;					/* set init on fileread */
-	int stacksize;					/* amount of elements in stack */
 	int cur_index;					/* sockets in groups have unique identifiers, adding new sockets always 
 									   will increase this counter */
-	int flag, pad;
+	int flag;
 	
 	struct bNodeType *owntype;		/* for groups or dynamic trees, no read/write */
 	
 	struct bNodeSocketIsland *islands;	/* used during calculation of socket type islands */
 	
+	/* execution data */
+	/* XXX It would be preferable to completely move this data out of the underlying node tree,
+	 * so node tree execution could finally run independent of the tree itself. This would allow node trees
+	 * to be merely linked by other data (materials, textures, etc.), as ID data is supposed to.
+	 * Execution data is generated from the tree once at execution start and can then be used
+	 * as long as necessary, even while the tree is being modified.
+	 */
+	void *execdata;
+	
 	/* callbacks */
 	void (*progress)(void *, float progress);
 	void (*stats_draw)(void *, char *str);
@@ -238,7 +240,6 @@
 
 /* ntree->init, flag */
 #define NTREE_TYPE_INIT	1
-#define NTREE_EXEC_INIT	2
 
 /* ntree->flag */
 #define NTREE_DS_EXPAND				1	/* for animation editors */

Modified: branches/particles-2010/source/blender/nodes/intern/node_tree_composite.c
===================================================================
--- branches/particles-2010/source/blender/nodes/intern/node_tree_composite.c	2010-09-06 07:26:21 UTC (rev 31780)
+++ branches/particles-2010/source/blender/nodes/intern/node_tree_composite.c	2010-09-06 08:13:28 UTC (rev 31781)
@@ -80,7 +80,7 @@
 /* the index_ext we need to be able to map from groups to the group-node own stack */
 
 /* copy socket compbufs to stack, initialize usage of curve nodes */
-static void composit_begin_exec(bNodeTree *ntree, int is_group)
+static void composit_begin_exec(bNodeTree *ntree, bNodeExecData *execdata, int is_group)
 {
 	bNode *node;
 	bNodeSocket *sock;
@@ -92,7 +92,7 @@
 		
 		if(is_group==0) {
 			for(sock= node->outputs.first; sock; sock= sock->next) {
-				bNodeStack *ns= ntree->stack + sock->stack_index;
+				bNodeStack *ns= execdata->stack + sock->stack_index;
 				
 				if(sock->ns.data) {
 					ns->data= sock->ns.data;
@@ -107,26 +107,28 @@
 				curvemapping_premultiply(node->storage, 0);
 		}
 		if(node->type==NODE_GROUP)
-			composit_begin_exec((bNodeTree *)node->id, 1);
+			composit_begin_exec((bNodeTree *)node->id, execdata, 1);
 
 	}
 }
 
-static void beginExec(bNodeTree *ntree)
+static void *beginExec(bNodeTree *ntree)
 {
+	bNodeExecData *execdata = MEM_callocN(sizeof(bNodeExecData), "node exec data");
+	
 	/* goes recursive over all groups */
-	ntree->stacksize= ntree_begin_exec_tree(ntree);
+	execdata->stacksize= ntree_begin_exec_tree(ntree);
 
-	if(ntree->stacksize) {
+	if(execdata->stacksize) {
 		bNode *node;
 		bNodeStack *ns;
 		int a;
 		
 		/* allocate the base stack */
-		ns=ntree->stack= MEM_callocN(ntree->stacksize*sizeof(bNodeStack), "node stack");
+		ns=execdata->stack= MEM_callocN(execdata->stacksize*sizeof(bNodeStack), "node stack");
 		
 		/* tag inputs, the get_stack() gives own socket stackdata if not in use */
-		for(a=0; a<ntree->stacksize; a++, ns++) ns->hasinput= 1;
+		for(a=0; a<execdata->stacksize; a++, ns++) ns->hasinput= 1;
 		
 		/* tag used outputs, so we know when we can skip operations */
 		for(node= ntree->nodes.first; node; node= node->next) {
@@ -134,7 +136,7 @@
 			
 			for(sock= node->inputs.first; sock; sock= sock->next) {
 				if(sock->link) {
-					ns= ntree->stack + sock->link->fromsock->stack_index;
+					ns= execdata->stack + sock->link->fromsock->stack_index;
 					ns->hasoutput= 1;
 					ns->sockettype= sock->link->fromsock->type;
 				}
@@ -154,15 +156,17 @@
 			}
 			
 			if(node->type==NODE_GROUP && node->id)
-				group_tag_used_outputs(node, ntree->stack);
+				group_tag_used_outputs(node, execdata->stack);
 		}
 		
-		composit_begin_exec(ntree, 0);
+		composit_begin_exec(ntree, execdata, 0);
 	}
+	
+	return execdata;
 }
 
 /* copy stack compbufs to sockets */
-static void composit_end_exec(bNodeTree *ntree, int is_group)
+static void composit_end_exec_recursive(bNodeTree *ntree, bNodeExecData *execdata, int is_group)
 {
 	extern void print_compbuf(char *str, struct CompBuf *cbuf);
 	bNode *node;
@@ -174,7 +178,7 @@
 			bNodeSocket *sock;
 		
 			for(sock= node->outputs.first; sock; sock= sock->next) {
-				ns= ntree->stack + sock->stack_index;
+				ns= execdata->stack + sock->stack_index;
 				if(ns->data) {
 					sock->ns.data= ns->data;
 					ns->data= NULL;
@@ -185,14 +189,14 @@
 			curvemapping_premultiply(node->storage, 1);
 		
 		if(node->type==NODE_GROUP)
-			composit_end_exec((bNodeTree *)node->id, 1);
+			composit_end_exec_recursive((bNodeTree *)node->id, execdata, 1);
 
 		node->need_exec= 0;
 	}
 	
 	if(is_group==0) {
 		/* internally, group buffers are not stored */
-		for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++) {
+		for(ns= execdata->stack, a=0; a<execdata->stacksize; a++, ns++) {
 			if(ns->data) {
 				printf("freed leftover buffer from stack\n");
 				free_compbuf(ns->data);
@@ -202,32 +206,34 @@
 	}
 }
 
-static void endExec(bNodeTree *ntree)
+static void endExec(bNodeTree *ntree, void *vexecdata)
 {
+	bNodeExecData *execdata = (bNodeExecData*)vexecdata;
 	bNodeThreadStack *nts;
 	int a;
 	
-	composit_end_exec(ntree, 0);
+	composit_end_exec_recursive(ntree, execdata, 0);
 	
-	if(ntree->stack) {
-		MEM_freeN(ntree->stack);
-		ntree->stack= NULL;
+	if(execdata->stack) {
+		MEM_freeN(execdata->stack);
+		execdata->stack= NULL;
 	}
 	
-	if(ntree->threadstack) {
+	if(execdata->threadstack) {
 		for(a=0; a<BLENDER_MAX_THREADS; a++) {
-			for(nts=ntree->threadstack[a].first; nts; nts=nts->next)
+			for(nts=execdata->threadstack[a].first; nts; nts=nts->next)
 				if (nts->stack) MEM_freeN(nts->stack);
-			BLI_freelistN(&ntree->threadstack[a]);
+			BLI_freelistN(&execdata->threadstack[a]);
 		}
 		
-		MEM_freeN(ntree->threadstack);
-		ntree->threadstack= NULL;
+		MEM_freeN(execdata->threadstack);
+		execdata->threadstack= NULL;
 	}
 }
 
-static void exec(bNodeTree *ntree, void *callerdata, int thread)
+static void exec(bNodeTree *ntree, void *vexecdata, void *callerdata, int thread)
 {
+	bNodeExecData *execdata = (bNodeExecData*)vexecdata;
 	bNode *node;
 	bNodeStack *nsin[MAX_SOCKET];	/* arbitrary... watch this */
 	bNodeStack *nsout[MAX_SOCKET];	/* arbitrary... watch this */
@@ -235,19 +241,15 @@
 	/* nodes are presorted, so exec is in order of list */
 	/* composite does 1 node per thread, so no multiple stacks needed */
 	
-	/* only when initialized */

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list