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:
authorTon Roosendaal <ton@blender.org>2009-01-27 20:12:40 +0300
committerTon Roosendaal <ton@blender.org>2009-01-27 20:12:40 +0300
commitc0ee40ab1077de07741344b163ccd8de046db0fe (patch)
tree8469c10210578f650141ce0717212a4a608db806 /source/blender/blenkernel/intern/node.c
parentb602fd8b1c7c3f492ba91ff7dc85a0aafd5c3ee7 (diff)
2.5
Compositor now uses threaded jobs. - updates happen per preview node! Check this file for fun: http://www.blender.org/bf/composite_image.blend (any compo node could get preview!) - had to ensure the composite data gets fully copied before it executes thread, so editing is not frustrated. - put back node buttons (missing init) - added WM_jobs api call to check for running job, illustrated with red light icon in 'use nodes' button. - added another callback to WM_jobs, to initialize. use this init to ensure you only do it when job really starts. - added an extra notifier option for WM_jobs, to signal finished job (like redraw image view) - fixed file read error, it copied the screen it read, instead of using it. - commented out annoying prints for missing ops in imagewin
Diffstat (limited to 'source/blender/blenkernel/intern/node.c')
-rw-r--r--source/blender/blenkernel/intern/node.c319
1 files changed, 211 insertions, 108 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index e7ccb15d923..f6407e9416c 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1158,6 +1158,104 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select)
return newtree;
}
+/* *************** preview *********** */
+/* if node->preview, then we assume the rect to exist */
+
+static void node_free_preview(bNode *node)
+{
+ if(node->preview) {
+ if(node->preview->rect)
+ MEM_freeN(node->preview->rect);
+ MEM_freeN(node->preview);
+ node->preview= NULL;
+ }
+}
+
+static void node_init_preview(bNode *node, int xsize, int ysize)
+{
+
+ if(node->preview==NULL) {
+ node->preview= MEM_callocN(sizeof(bNodePreview), "node preview");
+ // printf("added preview %s\n", node->name);
+ }
+
+ /* node previews can get added with variable size this way */
+ if(xsize==0 || ysize==0)
+ return;
+
+ /* sanity checks & initialize */
+ if(node->preview->rect) {
+ if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) {
+ MEM_freeN(node->preview->rect);
+ node->preview->rect= NULL;
+ }
+ }
+
+ if(node->preview->rect==NULL) {
+ node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect");
+ node->preview->xsize= xsize;
+ node->preview->ysize= ysize;
+ }
+}
+
+void ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize)
+{
+ bNode *node;
+
+ if(ntree==NULL)
+ return;
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->typeinfo->flag & NODE_PREVIEW) /* hrms, check for closed nodes? */
+ node_init_preview(node, xsize, ysize);
+ if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
+ ntreeInitPreview((bNodeTree *)node->id, xsize, ysize);
+ }
+}
+
+static void nodeClearPreview(bNode *node)
+{
+ if(node->preview && node->preview->rect)
+ memset(node->preview->rect, 0, MEM_allocN_len(node->preview->rect));
+}
+
+/* use it to enforce clear */
+void ntreeClearPreview(bNodeTree *ntree)
+{
+ bNode *node;
+
+ if(ntree==NULL)
+ return;
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->typeinfo->flag & NODE_PREVIEW)
+ nodeClearPreview(node);
+ if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
+ ntreeClearPreview((bNodeTree *)node->id);
+ }
+}
+
+/* hack warning! this function is only used for shader previews, and
+since it gets called multiple times per pixel for Ztransp we only
+add the color once. Preview gets cleared before it starts render though */
+void nodeAddToPreview(bNode *node, float *col, int x, int y)
+{
+ bNodePreview *preview= node->preview;
+ if(preview) {
+ if(x>=0 && y>=0) {
+ if(x<preview->xsize && y<preview->ysize) {
+ float *tar= preview->rect+ 4*((preview->xsize*y) + x);
+ //if(tar[0]==0.0f) {
+ QUATCOPY(tar, col);
+ //}
+ }
+ //else printf("prv out bound x y %d %d\n", x, y);
+ }
+ //else printf("prv out bound x y %d %d\n", x, y);
+ }
+}
+
+
/* ************** Free stuff ********** */
/* goes over entire tree */
@@ -1215,11 +1313,8 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
BLI_freelistN(&node->inputs);
BLI_freelistN(&node->outputs);
- if(node->preview) {
- if(node->preview->rect)
- MEM_freeN(node->preview->rect);
- MEM_freeN(node->preview);
- }
+ node_free_preview(node);
+
if(node->typeinfo && node->typeinfo->freestoragefunc) {
node->typeinfo->freestoragefunc(node);
}
@@ -1652,14 +1747,8 @@ void NodeTagChanged(bNodeTree *ntree, bNode *node)
for(sock= node->outputs.first; sock; sock= sock->next) {
if(sock->ns.data) {
- free_compbuf(sock->ns.data);
- sock->ns.data= NULL;
-
- //if(node->preview && node->preview->rect) {
- // MEM_freeN(node->preview->rect);
- // node->preview->rect= NULL;
- //}
-
+ //free_compbuf(sock->ns.data);
+ //sock->ns.data= NULL;
}
}
node->need_exec= 1;
@@ -1683,95 +1772,6 @@ void NodeTagIDChanged(bNodeTree *ntree, ID *id)
}
-/* *************** preview *********** */
-
-/* if node->preview, then we assume the rect to exist */
-
-static void nodeInitPreview(bNode *node, int xsize, int ysize)
-{
-
- if(node->preview==NULL) {
- node->preview= MEM_callocN(sizeof(bNodePreview), "node preview");
-// printf("added preview %s\n", node->name);
- }
-
- /* node previews can get added with variable size this way */
- if(xsize==0 || ysize==0)
- return;
-
- /* sanity checks & initialize */
- if(node->preview->rect) {
- if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) {
- MEM_freeN(node->preview->rect);
- node->preview->rect= NULL;
- }
- }
-
- if(node->preview->rect==NULL) {
- node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect");
- node->preview->xsize= xsize;
- node->preview->ysize= ysize;
- }
-}
-
-void ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize)
-{
- bNode *node;
-
- if(ntree==NULL)
- return;
-
- for(node= ntree->nodes.first; node; node= node->next) {
- if(node->typeinfo->flag & NODE_PREVIEW) /* hrms, check for closed nodes? */
- nodeInitPreview(node, xsize, ysize);
- if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
- ntreeInitPreview((bNodeTree *)node->id, xsize, ysize);
- }
-}
-
-static void nodeClearPreview(bNode *node)
-{
- if(node->preview && node->preview->rect)
- memset(node->preview->rect, 0, MEM_allocN_len(node->preview->rect));
-}
-
-/* use it to enforce clear */
-void ntreeClearPreview(bNodeTree *ntree)
-{
- bNode *node;
-
- if(ntree==NULL)
- return;
-
- for(node= ntree->nodes.first; node; node= node->next) {
- if(node->typeinfo->flag & NODE_PREVIEW)
- nodeClearPreview(node);
- if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
- ntreeClearPreview((bNodeTree *)node->id);
- }
-}
-
-/* hack warning! this function is only used for shader previews, and
- since it gets called multiple times per pixel for Ztransp we only
- add the color once. Preview gets cleared before it starts render though */
-void nodeAddToPreview(bNode *node, float *col, int x, int y)
-{
- bNodePreview *preview= node->preview;
- if(preview) {
- if(x>=0 && y>=0) {
- if(x<preview->xsize && y<preview->ysize) {
- float *tar= preview->rect+ 4*((preview->xsize*y) + x);
- //if(tar[0]==0.0f) {
- QUATCOPY(tar, col);
- //}
- }
- //else printf("prv out bound x y %d %d\n", x, y);
- }
- //else printf("prv out bound x y %d %d\n", x, y);
- }
-}
-
-
/* ******************* executing ************* */
@@ -2205,7 +2205,7 @@ static void *exec_composite_node(void *node_v)
bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
bNode *node= node_v;
- ThreadData *thd= (ThreadData *)node->new_node; /* abuse */
+ ThreadData *thd= (ThreadData *)node->threaddata;
node_get_stack(node, thd->stack, nsin, nsout);
@@ -2300,7 +2300,7 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
}
else {
/* tag for getExecutableNode() */
- node->exec= NODE_READY|NODE_FINISHED;
+ node->exec= NODE_READY|NODE_FINISHED|NODE_SKIPPED;
}
}
@@ -2410,7 +2410,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
/* sets need_exec tags in nodes */
totnode= setExecutableNodes(ntree, &thdata);
-
+
BLI_init_threads(&threads, exec_composite_node, rd->threads);
while(rendering) {
@@ -2418,7 +2418,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
if(BLI_available_threads(&threads)) {
node= getExecutableNode(ntree);
if(node) {
-
+
if(ntree->timecursor)
ntree->timecursor(ntree->tch, totnode);
if(ntree->stats_draw) {
@@ -2428,7 +2428,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
}
totnode--;
- node->new_node = (bNode *)&thdata;
+ node->threaddata = &thdata;
node->exec= NODE_PROCESSING;
BLI_insert_thread(&threads, node);
}
@@ -2461,12 +2461,115 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
}
}
-
BLI_end_threads(&threads);
ntreeEndExecTree(ntree);
}
+
+/* ********** copy composite tree entirely, to allow threaded exec ******************* */
+/* ***************** do NOT execute this in a thread! ****************** */
+
+/* returns localized composite tree for execution in threads */
+/* local tree then owns all compbufs */
+bNodeTree *ntreeLocalize(bNodeTree *ntree)
+{
+ bNodeTree *ltree= ntreeCopyTree(ntree, 0);
+ bNode *node;
+ bNodeSocket *sock;
+
+ /* move over the compbufs */
+ /* right after ntreeCopyTree() oldsock pointers are valid */
+ for(node= ntree->nodes.first; node; node= node->next) {
+
+ /* store new_node pointer to original */
+ node->new_node->new_node= node;
+ /* ensure new user input gets handled ok */
+ node->need_exec= 0;
+
+ for(sock= node->outputs.first; sock; sock= sock->next) {
+
+ sock->new_sock->ns.data= sock->ns.data;
+ sock->ns.data= NULL;
+ sock->new_sock->new_sock= sock;
+ }
+ }
+
+ return ltree;
+}
+
+static int node_exists(bNodeTree *ntree, bNode *testnode)
+{
+ bNode *node= ntree->nodes.first;
+ for(; node; node= node->next)
+ if(node==testnode)
+ return 1;
+ return 0;
+}
+
+static int outsocket_exists(bNode *node, bNodeSocket *testsock)
+{
+ bNodeSocket *sock= node->outputs.first;
+ for(; sock; sock= sock->next)
+ if(sock==testsock)
+ return 1;
+ return 0;
+}
+
+
+/* sync local composite with real tree */
+/* local composite is supposed to be running, be careful moving previews! */
+void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree)
+{
+ bNode *lnode;
+
+ /* move over the compbufs and previews */
+ for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
+ if( (lnode->exec & NODE_READY) && !(lnode->exec & NODE_SKIPPED) ) {
+ if(node_exists(ntree, lnode->new_node)) {
+
+ if(lnode->preview && lnode->preview->rect) {
+ node_free_preview(lnode->new_node);
+ lnode->new_node->preview= lnode->preview;
+ lnode->preview= NULL;
+ }
+ }
+ }
+ }
+}
+
+/* merge local tree results back, and free local tree */
+/* we have to assume the editor already changed completely */
+void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
+{
+ bNode *lnode;
+ bNodeSocket *lsock;
+
+ /* move over the compbufs and previews */
+ for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
+ if(node_exists(ntree, lnode->new_node)) {
+
+ if(lnode->preview && lnode->preview->rect) {
+ node_free_preview(lnode->new_node);
+ lnode->new_node->preview= lnode->preview;
+ lnode->preview= NULL;
+ }
+
+ for(lsock= lnode->outputs.first; lsock; lsock= lsock->next) {
+ if(outsocket_exists(lnode->new_node, lsock->new_sock)) {
+ lsock->new_sock->ns.data= lsock->ns.data;
+ lsock->ns.data= NULL;
+ lsock->new_sock= NULL;
+ }
+ }
+ }
+ }
+ ntreeFreeTree(localtree);
+ MEM_freeN(localtree);
+}
+
+/* *********************************************** */
+
/* GPU material from shader nodes */
static void gpu_from_node_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs)