style cleanup: block comments
[blender.git] / source / blender / nodes / composite / node_composite_tree.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2007 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s):
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/nodes/composite/node_composite_tree.c
29  *  \ingroup nodes
30  */
31
32
33 #include <stdio.h>
34
35 #include "DNA_anim_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_node_types.h"
38
39 #include "BLI_listbase.h"
40 #include "BLI_threads.h"
41
42 #include "BLF_translation.h"
43
44 #include "BKE_animsys.h"
45 #include "BKE_colortools.h"
46 #include "BKE_fcurve.h"
47 #include "BKE_global.h"
48 #include "BKE_main.h"
49 #include "BKE_node.h"
50 #include "BKE_tracking.h"
51 #include "BKE_utildefines.h"
52
53 #include "node_exec.h"
54 #include "node_util.h"
55
56 #include "PIL_time.h"
57
58 #include "RNA_access.h"
59
60 #include "NOD_composite.h"
61 #include "node_composite_util.h"
62
63 static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func)
64 {
65         Scene *sce;
66         for (sce= main->scene.first; sce; sce= sce->id.next) {
67                 if (sce->nodetree) {
68                         func(calldata, &sce->id, sce->nodetree);
69                 }
70         }
71 }
72
73 static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
74 {
75         func(calldata, NODE_CLASS_INPUT, N_("Input"));
76         func(calldata, NODE_CLASS_OUTPUT, N_("Output"));
77         func(calldata, NODE_CLASS_OP_COLOR, N_("Color"));
78         func(calldata, NODE_CLASS_OP_VECTOR, N_("Vector"));
79         func(calldata, NODE_CLASS_OP_FILTER, N_("Filter"));
80         func(calldata, NODE_CLASS_CONVERTOR, N_("Convertor"));
81         func(calldata, NODE_CLASS_MATTE, N_("Matte"));
82         func(calldata, NODE_CLASS_DISTORT, N_("Distort"));
83         func(calldata, NODE_CLASS_GROUP, N_("Group"));
84         func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
85 }
86
87 static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node)
88 {
89         bNodeSocket *sock;
90         
91         for (sock= node->outputs.first; sock; sock= sock->next) {
92                 if (sock->cache) {
93                         free_compbuf(sock->cache);
94                         sock->cache= NULL;
95                 }
96         }
97 }
98
99 static void free_cache(bNodeTree *ntree)
100 {
101         bNode *node;
102         for (node= ntree->nodes.first; node; node= node->next)
103                 free_node_cache(ntree, node);
104 }
105
106 static void update_node(bNodeTree *ntree, bNode *node)
107 {
108         bNodeSocket *sock;
109
110         for (sock= node->outputs.first; sock; sock= sock->next) {
111                 if (sock->cache) {
112                         //free_compbuf(sock->cache);
113                         //sock->cache= NULL;
114                 }
115         }
116         node->need_exec= 1;
117         
118         /* individual node update call */
119         if (node->typeinfo->updatefunc)
120                 node->typeinfo->updatefunc(ntree, node);
121 }
122
123 /* local tree then owns all compbufs */
124 static void localize(bNodeTree *localtree, bNodeTree *ntree)
125 {
126         bNode *node, *node_next;
127         bNodeSocket *sock;
128         
129         for (node= ntree->nodes.first; node; node= node->next) {
130                 /* ensure new user input gets handled ok */
131                 node->need_exec= 0;
132                 
133                 /* move over the compbufs */
134                 /* right after ntreeCopyTree() oldsock pointers are valid */
135                 
136                 if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
137                         if (node->id) {
138                                 if (node->flag & NODE_DO_OUTPUT)
139                                         node->new_node->id= (ID *)BKE_image_copy((Image *)node->id);
140                                 else
141                                         node->new_node->id= NULL;
142                         }
143                 }
144                 
145                 for (sock= node->outputs.first; sock; sock= sock->next) {
146                         sock->new_sock->cache= sock->cache;
147                         compbuf_set_node(sock->new_sock->cache, node->new_node);
148                         
149                         sock->cache= NULL;
150                         sock->new_sock->new_sock= sock;
151                 }
152         }
153         
154         /* replace muted nodes by internal links */
155         for (node= localtree->nodes.first; node; node= node_next) {
156                 node_next = node->next;
157                 
158                 if (node->flag & NODE_MUTED) {
159                         /* make sure the update tag isn't lost when removing the muted node.
160                          * propagate this to all downstream nodes.
161                          */
162                         if (node->need_exec) {
163                                 bNodeLink *link;
164                                 for (link=localtree->links.first; link; link=link->next)
165                                         if (link->fromnode==node && link->tonode)
166                                                 link->tonode->need_exec = 1;
167                         }
168                         
169                         nodeInternalRelink(localtree, node);
170                         nodeFreeNode(localtree, node);
171                 }
172         }
173 }
174
175 static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
176 {
177         bNode *lnode;
178         
179         /* move over the compbufs and previews */
180         for (lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
181                 if ( (lnode->exec & NODE_READY) && !(lnode->exec & NODE_SKIPPED) ) {
182                         if (ntreeNodeExists(ntree, lnode->new_node)) {
183                                 
184                                 if (lnode->preview && lnode->preview->rect) {
185                                         nodeFreePreview(lnode->new_node);
186                                         lnode->new_node->preview= lnode->preview;
187                                         lnode->preview= NULL;
188                                 }
189                         }
190                 }
191         }
192 }
193
194 static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
195 {
196         bNode *lnode;
197         bNodeSocket *lsock;
198         
199         /* move over the compbufs and previews */
200         for (lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
201                 if (ntreeNodeExists(ntree, lnode->new_node)) {
202                         if (ELEM(lnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
203                                 if (lnode->id && (lnode->flag & NODE_DO_OUTPUT)) {
204                                         /* image_merge does sanity check for pointers */
205                                         BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id);
206                                 }
207                         }
208                         else if (lnode->type==CMP_NODE_MOVIEDISTORTION) {
209                                 /* special case for distortion node: distortion context is allocating in exec function
210                                    and to achive much better performance on further calls this context should be
211                                    copied back to original node */
212                                 if (lnode->storage) {
213                                         if (lnode->new_node->storage)
214                                                 BKE_tracking_distortion_destroy(lnode->new_node->storage);
215
216                                         lnode->new_node->storage= BKE_tracking_distortion_copy(lnode->storage);
217                                 }
218                         }
219                         
220                         for (lsock= lnode->outputs.first; lsock; lsock= lsock->next) {
221                                 if (ntreeOutputExists(lnode->new_node, lsock->new_sock)) {
222                                         lsock->new_sock->cache= lsock->cache;
223                                         compbuf_set_node(lsock->new_sock->cache, lnode->new_node);
224                                         lsock->cache= NULL;
225                                         lsock->new_sock= NULL;
226                                 }
227                         }
228                 }
229         }
230 }
231
232 static void update(bNodeTree *ntree)
233 {
234         ntreeSetOutput(ntree);
235 }
236
237 bNodeTreeType ntreeType_Composite = {
238         /* type */                              NTREE_COMPOSIT,
239         /* idname */                    "NTCompositing Nodetree",
240         
241         /* node_types */                { NULL, NULL },
242         
243         /* free_cache */                free_cache,
244         /* free_node_cache */   free_node_cache,
245         /* foreach_nodetree */  foreach_nodetree,
246         /* foreach_nodeclass */ foreach_nodeclass,
247         /* localize */                  localize,
248         /* local_sync */                local_sync,
249         /* local_merge */               local_merge,
250         /* update */                    update,
251         /* update_node */               update_node,
252         /* validate_link */             NULL,
253         /* internal_connect */  node_internal_connect_default
254 };
255
256
257 /* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
258  * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
259  */
260 struct bNodeTreeExec *ntreeCompositBeginExecTree(bNodeTree *ntree, int use_tree_data)
261 {
262         bNodeTreeExec *exec;
263         bNode *node;
264         bNodeSocket *sock;
265         
266         if (use_tree_data) {
267                 /* XXX hack: prevent exec data from being generated twice.
268                  * this should be handled by the renderer!
269                  */
270                 if (ntree->execdata)
271                         return ntree->execdata;
272         }
273         
274         /* ensures only a single output node is enabled */
275         ntreeSetOutput(ntree);
276         
277         exec = ntree_exec_begin(ntree);
278         
279         for (node= exec->nodetree->nodes.first; node; node= node->next) {
280                 /* initialize needed for groups */
281                 node->exec= 0;  
282                 
283                 for (sock= node->outputs.first; sock; sock= sock->next) {
284                         bNodeStack *ns= node_get_socket_stack(exec->stack, sock);
285                         if (ns && sock->cache) {
286                                 ns->data= sock->cache;
287                                 sock->cache= NULL;
288                         }
289                 }
290                 /* cannot initialize them while using in threads */
291                 if (ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) {
292                         curvemapping_initialize(node->storage);
293                         if (node->type==CMP_NODE_CURVE_RGB)
294                                 curvemapping_premultiply(node->storage, 0);
295                 }
296         }
297         
298         if (use_tree_data) {
299                 /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
300                  * which only store the ntree pointer. Should be fixed at some point!
301                  */
302                 ntree->execdata = exec;
303         }
304         
305         return exec;
306 }
307
308 /* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
309  * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
310  */
311 void ntreeCompositEndExecTree(bNodeTreeExec *exec, int use_tree_data)
312 {
313         if (exec) {
314                 bNodeTree *ntree= exec->nodetree;
315                 bNode *node;
316                 bNodeStack *ns;
317                 
318                 for (node= exec->nodetree->nodes.first; node; node= node->next) {
319                         bNodeSocket *sock;
320                         
321                         for (sock= node->outputs.first; sock; sock= sock->next) {
322                                 ns = node_get_socket_stack(exec->stack, sock);
323                                 if (ns && ns->data) {
324                                         sock->cache= ns->data;
325                                         ns->data= NULL;
326                                 }
327                         }
328                         if (node->type==CMP_NODE_CURVE_RGB)
329                                 curvemapping_premultiply(node->storage, 1);
330                         
331                         node->need_exec= 0;
332                 }
333         
334                 ntree_exec_end(exec);
335                 
336                 if (use_tree_data) {
337                         /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
338                         ntree->execdata = NULL;
339                 }
340         }
341 }
342
343 /* ***************************** threaded version for execute composite nodes ************* */
344 /* these are nodes without input, only giving values */
345 /* or nodes with only value inputs */
346 static int node_only_value(bNode *node)
347 {
348         bNodeSocket *sock;
349         
350         if (ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
351                 return 1;
352         
353         /* doing this for all node types goes wrong. memory free errors */
354         if (node->inputs.first && node->type==CMP_NODE_MAP_VALUE) {
355                 int retval= 1;
356                 for (sock= node->inputs.first; sock; sock= sock->next) {
357                         if (sock->link)
358                                 retval &= node_only_value(sock->link->fromnode);
359                 }
360                 return retval;
361         }
362         return 0;
363 }
364
365 /* not changing info, for thread callback */
366 typedef struct ThreadData {
367         bNodeStack *stack;
368         RenderData *rd;
369 } ThreadData;
370
371 static void *exec_composite_node(void *nodeexec_v)
372 {
373         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
374         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
375         bNodeExec *nodeexec= nodeexec_v;
376         bNode *node= nodeexec->node;
377         ThreadData *thd= (ThreadData *)node->threaddata;
378         
379         node_get_stack(node, thd->stack, nsin, nsout);
380         
381         if (node->typeinfo->execfunc)
382                 node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
383         else if (node->typeinfo->newexecfunc)
384                 node->typeinfo->newexecfunc(thd->rd, 0, node, nodeexec->data, nsin, nsout);
385         
386         node->exec |= NODE_READY;
387         return NULL;
388 }
389
390 /* return total of executable nodes, for timecursor */
391 static int setExecutableNodes(bNodeTreeExec *exec, ThreadData *thd)
392 {
393         bNodeTree *ntree = exec->nodetree;
394         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
395         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
396         bNodeExec *nodeexec;
397         bNode *node;
398         bNodeSocket *sock;
399         int n, totnode= 0, group_edit= 0;
400         
401         /* if we are in group edit, viewer nodes get skipped when group has viewer */
402         for (node= ntree->nodes.first; node; node= node->next)
403                 if (node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
404                         if (ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER))
405                                 group_edit= 1;
406         
407         /* NB: using the exec data list here to have valid dependency sort */
408         for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
409                 int a;
410                 node = nodeexec->node;
411                 
412                 node_get_stack(node, exec->stack, nsin, nsout);
413                 
414                 /* test the outputs */
415                 /* skip value-only nodes (should be in type!) */
416                 if (!node_only_value(node)) {
417                         for (a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
418                                 if (nsout[a]->data==NULL && nsout[a]->hasoutput) {
419                                         node->need_exec= 1;
420                                         break;
421                                 }
422                         }
423                 }
424                 
425                 /* test the inputs */
426                 for (a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
427                         /* skip viewer nodes in bg render or group edit */
428                         if ( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit))
429                                 node->need_exec= 0;
430                         /* is sock in use? */
431                         else if (sock->link) {
432                                 bNodeLink *link= sock->link;
433                                 
434                                 /* this is the test for a cyclic case */
435                                 if (link->fromnode==NULL || link->tonode==NULL);
436                                 else if (link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
437                                         if (link->fromnode->need_exec) {
438                                                 node->need_exec= 1;
439                                                 break;
440                                         }
441                                 }
442                                 else {
443                                         node->need_exec= 0;
444                                         printf("Node %s skipped, cyclic dependency\n", node->name);
445                                 }
446                         }
447                 }
448                 
449                 if (node->need_exec) {
450                         
451                         /* free output buffers */
452                         for (a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
453                                 if (nsout[a]->data) {
454                                         free_compbuf(nsout[a]->data);
455                                         nsout[a]->data= NULL;
456                                 }
457                         }
458                         totnode++;
459                         /* printf("node needs exec %s\n", node->name); */
460                         
461                         /* tag for getExecutableNode() */
462                         node->exec= 0;
463                 }
464                 else {
465                         /* tag for getExecutableNode() */
466                         node->exec= NODE_READY|NODE_FINISHED|NODE_SKIPPED;
467                         
468                 }
469         }
470         
471         /* last step: set the stack values for only-value nodes */
472         /* just does all now, compared to a full buffer exec this is nothing */
473         if (totnode) {
474                 for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
475                         node = nodeexec->node;
476                         if (node->need_exec==0 && node_only_value(node)) {
477                                 if (node->typeinfo->execfunc) {
478                                         node_get_stack(node, exec->stack, nsin, nsout);
479                                         node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
480                                 }
481                         }
482                 }
483         }
484         
485         return totnode;
486 }
487
488 /* while executing tree, free buffers from nodes that are not needed anymore */
489 static void freeExecutableNode(bNodeTreeExec *exec)
490 {
491         /* node outputs can be freed when:
492         - not a render result or image node
493         - when node outputs go to nodes all being set NODE_FINISHED
494         */
495         bNodeTree *ntree = exec->nodetree;
496         bNodeExec *nodeexec;
497         bNode *node;
498         bNodeSocket *sock;
499         int n;
500         
501         /* set exec flag for finished nodes that might need freed */
502         for (node= ntree->nodes.first; node; node= node->next) {
503                 if (node->type!=CMP_NODE_R_LAYERS)
504                         if (node->exec & NODE_FINISHED)
505                                 node->exec |= NODE_FREEBUFS;
506         }
507         /* clear this flag for input links that are not done yet.
508          * Using the exec data for valid dependency sort.
509          */
510         for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
511                 node = nodeexec->node;
512                 if ((node->exec & NODE_FINISHED)==0) {
513                         for (sock= node->inputs.first; sock; sock= sock->next)
514                                 if (sock->link)
515                                         sock->link->fromnode->exec &= ~NODE_FREEBUFS;
516                 }
517         }
518         /* now we can free buffers */
519         for (node= ntree->nodes.first; node; node= node->next) {
520                 if (node->exec & NODE_FREEBUFS) {
521                         for (sock= node->outputs.first; sock; sock= sock->next) {
522                                 bNodeStack *ns= node_get_socket_stack(exec->stack, sock);
523                                 if (ns && ns->data) {
524                                         free_compbuf(ns->data);
525                                         ns->data= NULL;
526                                         // printf("freed buf node %s\n", node->name);
527                                 }
528                         }
529                 }
530         }
531 }
532
533 static bNodeExec *getExecutableNode(bNodeTreeExec *exec)
534 {
535         bNodeExec *nodeexec;
536         bNodeSocket *sock;
537         int n;
538         
539         for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
540                 if (nodeexec->node->exec==0) {
541                         /* input sockets should be ready */
542                         for (sock= nodeexec->node->inputs.first; sock; sock= sock->next) {
543                                 if (sock->link && sock->link->fromnode)
544                                         if ((sock->link->fromnode->exec & NODE_READY)==0)
545                                                 break;
546                         }
547                         if (sock==NULL)
548                                 return nodeexec;
549                 }
550         }
551         return NULL;
552 }
553
554 /* check if texture nodes need exec or end */
555 static  void ntree_composite_texnode(bNodeTree *ntree, int init)
556 {
557         bNode *node;
558         
559         for (node= ntree->nodes.first; node; node= node->next) {
560                 if (node->type==CMP_NODE_TEXTURE && node->id) {
561                         Tex *tex= (Tex *)node->id;
562                         if (tex->nodetree && tex->use_nodes) {
563                                 /* has internal flag to detect it only does it once */
564                                 if (init) {
565                                         if (!tex->nodetree->execdata)
566                                                 tex->nodetree->execdata = ntreeTexBeginExecTree(tex->nodetree, 1); 
567                                 }
568                                 else
569                                         ntreeTexEndExecTree(tex->nodetree->execdata, 1);
570                                         tex->nodetree->execdata = NULL;
571                         }
572                 }
573         }
574
575 }
576
577 /* optimized tree execute test for compositing */
578 void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
579 {
580         bNodeExec *nodeexec;
581         bNode *node;
582         ListBase threads;
583         ThreadData thdata;
584         int totnode, curnode, rendering= 1, n;
585         bNodeTreeExec *exec;
586
587         if (ntree==NULL) return;
588
589         exec = ntree->execdata;
590
591         if (do_preview)
592                 ntreeInitPreview(ntree, 0, 0);
593         
594         if (!ntree->execdata) {
595                 /* XXX this is the top-level tree, so we use the ntree->execdata pointer. */
596                 exec = ntreeCompositBeginExecTree(ntree, 1);
597         }
598         ntree_composite_texnode(ntree, 1);
599         
600         /* prevent unlucky accidents */
601         if (G.background)
602                 rd->scemode &= ~R_COMP_CROP;
603         
604         /* setup callerdata for thread callback */
605         thdata.rd= rd;
606         thdata.stack= exec->stack;
607         
608         /* fixed seed, for example noise texture */
609         BLI_srandom(rd->cfra);
610
611         /* sets need_exec tags in nodes */
612         curnode = totnode= setExecutableNodes(exec, &thdata);
613
614         BLI_init_threads(&threads, exec_composite_node, rd->threads);
615         
616         while (rendering) {
617                 
618                 if (BLI_available_threads(&threads)) {
619                         nodeexec= getExecutableNode(exec);
620                         if (nodeexec) {
621                                 node = nodeexec->node;
622                                 if (ntree->progress && totnode)
623                                         ntree->progress(ntree->prh, (1.0f - curnode/(float)totnode));
624                                 if (ntree->stats_draw) {
625                                         char str[128];
626                                         BLI_snprintf(str, sizeof(str), "Compositing %d %s", curnode, node->name);
627                                         ntree->stats_draw(ntree->sdh, str);
628                                 }
629                                 curnode--;
630                                 
631                                 node->threaddata = &thdata;
632                                 node->exec= NODE_PROCESSING;
633                                 BLI_insert_thread(&threads, nodeexec);
634                         }
635                         else
636                                 PIL_sleep_ms(50);
637                 }
638                 else
639                         PIL_sleep_ms(50);
640                 
641                 rendering= 0;
642                 /* test for ESC */
643                 if (ntree->test_break && ntree->test_break(ntree->tbh)) {
644                         for (node= ntree->nodes.first; node; node= node->next)
645                                 node->exec |= NODE_READY;
646                 }
647                 
648                 /* check for ready ones, and if we need to continue */
649                 for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
650                         node = nodeexec->node;
651                         if (node->exec & NODE_READY) {
652                                 if ((node->exec & NODE_FINISHED)==0) {
653                                         BLI_remove_thread(&threads, nodeexec); /* this waits for running thread to finish btw */
654                                         node->exec |= NODE_FINISHED;
655                                         
656                                         /* freeing unused buffers */
657                                         if (rd->scemode & R_COMP_FREE)
658                                                 freeExecutableNode(exec);
659                                 }
660                         }
661                         else rendering= 1;
662                 }
663         }
664         
665         BLI_end_threads(&threads);
666         
667         /* XXX top-level tree uses the ntree->execdata pointer */
668         ntreeCompositEndExecTree(exec, 1);
669 }
670
671 /* *********************************************** */
672
673 /* clumsy checking... should do dynamic outputs once */
674 static void force_hidden_passes(bNode *node, int passflag)
675 {
676         bNodeSocket *sock;
677         
678         for (sock= node->outputs.first; sock; sock= sock->next)
679                 sock->flag &= ~SOCK_UNAVAIL;
680         
681         if (!(passflag & SCE_PASS_COMBINED)) {
682                 sock= BLI_findlink(&node->outputs, RRES_OUT_IMAGE);
683                 sock->flag |= SOCK_UNAVAIL;
684                 sock= BLI_findlink(&node->outputs, RRES_OUT_ALPHA);
685                 sock->flag |= SOCK_UNAVAIL;
686         }
687         
688         sock= BLI_findlink(&node->outputs, RRES_OUT_Z);
689         if (!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL;
690         sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL);
691         if (!(passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL;
692         sock= BLI_findlink(&node->outputs, RRES_OUT_VEC);
693         if (!(passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL;
694         sock= BLI_findlink(&node->outputs, RRES_OUT_UV);
695         if (!(passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL;
696         sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA);
697         if (!(passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL;
698         sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF);
699         if (!(passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL;
700         sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC);
701         if (!(passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL;
702         sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW);
703         if (!(passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL;
704         sock= BLI_findlink(&node->outputs, RRES_OUT_AO);
705         if (!(passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL;
706         sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT);
707         if (!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
708         sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
709         if (!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
710         sock= BLI_findlink(&node->outputs, RRES_OUT_INDIRECT);
711         if (!(passflag & SCE_PASS_INDIRECT)) sock->flag |= SOCK_UNAVAIL;
712         sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
713         if (!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
714         sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXMA);
715         if (!(passflag & SCE_PASS_INDEXMA)) sock->flag |= SOCK_UNAVAIL;
716         sock= BLI_findlink(&node->outputs, RRES_OUT_MIST);
717         if (!(passflag & SCE_PASS_MIST)) sock->flag |= SOCK_UNAVAIL;
718         sock= BLI_findlink(&node->outputs, RRES_OUT_EMIT);
719         if (!(passflag & SCE_PASS_EMIT)) sock->flag |= SOCK_UNAVAIL;
720         sock= BLI_findlink(&node->outputs, RRES_OUT_ENV);
721         if (!(passflag & SCE_PASS_ENVIRONMENT)) sock->flag |= SOCK_UNAVAIL;
722
723         sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF_DIRECT);
724         if (!(passflag & SCE_PASS_DIFFUSE_DIRECT)) sock->flag |= SOCK_UNAVAIL;
725         sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF_INDIRECT);
726         if (!(passflag & SCE_PASS_DIFFUSE_INDIRECT)) sock->flag |= SOCK_UNAVAIL;
727         sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF_COLOR);
728         if (!(passflag & SCE_PASS_DIFFUSE_COLOR)) sock->flag |= SOCK_UNAVAIL;
729
730         sock= BLI_findlink(&node->outputs, RRES_OUT_GLOSSY_DIRECT);
731         if (!(passflag & SCE_PASS_GLOSSY_DIRECT)) sock->flag |= SOCK_UNAVAIL;
732         sock= BLI_findlink(&node->outputs, RRES_OUT_GLOSSY_INDIRECT);
733         if (!(passflag & SCE_PASS_GLOSSY_INDIRECT)) sock->flag |= SOCK_UNAVAIL;
734         sock= BLI_findlink(&node->outputs, RRES_OUT_GLOSSY_COLOR);
735         if (!(passflag & SCE_PASS_GLOSSY_COLOR)) sock->flag |= SOCK_UNAVAIL;
736
737         sock= BLI_findlink(&node->outputs, RRES_OUT_TRANSM_DIRECT);
738         if (!(passflag & SCE_PASS_TRANSM_DIRECT)) sock->flag |= SOCK_UNAVAIL;
739         sock= BLI_findlink(&node->outputs, RRES_OUT_TRANSM_INDIRECT);
740         if (!(passflag & SCE_PASS_TRANSM_INDIRECT)) sock->flag |= SOCK_UNAVAIL;
741         sock= BLI_findlink(&node->outputs, RRES_OUT_TRANSM_COLOR);
742         if (!(passflag & SCE_PASS_TRANSM_COLOR)) sock->flag |= SOCK_UNAVAIL;
743         sock= BLI_findlink(&node->outputs, RRES_OUT_TRANSM_COLOR);
744 }
745
746 /* based on rules, force sockets hidden always */
747 void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene)
748 {
749         bNode *node;
750         
751         if (ntree==NULL) return;
752         
753         for (node= ntree->nodes.first; node; node= node->next) {
754                 if ( node->type==CMP_NODE_R_LAYERS) {
755                         Scene *sce= node->id?(Scene *)node->id:curscene;
756                         SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
757                         if (srl)
758                                 force_hidden_passes(node, srl->passflag);
759                 }
760                 /* XXX this stuff is called all the time, don't want that.
761                  * Updates should only happen when actually necessary.
762                  */
763                 #if 0
764                 else if ( node->type==CMP_NODE_IMAGE) {
765                         nodeUpdate(ntree, node);
766                 }
767                 #endif
768         }
769
770 }
771
772 /* called from render pipeline, to tag render input and output */
773 /* need to do all scenes, to prevent errors when you re-render 1 scene */
774 void ntreeCompositTagRender(Scene *curscene)
775 {
776         Scene *sce;
777         
778         for (sce= G.main->scene.first; sce; sce= sce->id.next) {
779                 if (sce->nodetree) {
780                         bNode *node;
781                         
782                         for (node= sce->nodetree->nodes.first; node; node= node->next) {
783                                 if (node->id==(ID *)curscene || node->type==CMP_NODE_COMPOSITE)
784                                         nodeUpdate(sce->nodetree, node);
785                                 else if (node->type==CMP_NODE_TEXTURE) /* uses scene sizex/sizey */
786                                         nodeUpdate(sce->nodetree, node);
787                         }
788                 }
789         }
790 }
791
792 static int node_animation_properties(bNodeTree *ntree, bNode *node)
793 {
794         bNodeSocket *sock;
795         const ListBase *lb;
796         Link *link;
797         PointerRNA ptr;
798         PropertyRNA *prop;
799         
800         /* check to see if any of the node's properties have fcurves */
801         RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
802         lb = RNA_struct_type_properties(ptr.type);
803         
804         for (link=lb->first; link; link=link->next) {
805                 int driven, len=1, index;
806                 prop = (PropertyRNA *)link;
807                 
808                 if (RNA_property_array_check(prop))
809                         len = RNA_property_array_length(&ptr, prop);
810                 
811                 for (index=0; index<len; index++) {
812                         if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
813                                 nodeUpdate(ntree, node);
814                                 return 1;
815                         }
816                 }
817         }
818         
819         /* now check node sockets */
820         for (sock = node->inputs.first; sock; sock=sock->next) {
821                 int driven, len=1, index;
822                 
823                 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
824                 prop = RNA_struct_find_property(&ptr, "default_value");
825                 if (prop) {
826                         if (RNA_property_array_check(prop))
827                                 len = RNA_property_array_length(&ptr, prop);
828                         
829                         for (index=0; index<len; index++) {
830                                 if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
831                                         nodeUpdate(ntree, node);
832                                         return 1;
833                                 }
834                         }
835                 }
836         }
837
838         return 0;
839 }
840
841 /* tags nodes that have animation capabilities */
842 int ntreeCompositTagAnimated(bNodeTree *ntree)
843 {
844         bNode *node;
845         int tagged= 0;
846         
847         if (ntree==NULL) return 0;
848         
849         for (node= ntree->nodes.first; node; node= node->next) {
850                 
851                 tagged = node_animation_properties(ntree, node);
852                 
853                 /* otherwise always tag these node types */
854                 if (node->type==CMP_NODE_IMAGE) {
855                         Image *ima= (Image *)node->id;
856                         if (ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
857                                 nodeUpdate(ntree, node);
858                                 tagged= 1;
859                         }
860                 }
861                 else if (node->type==CMP_NODE_TIME) {
862                         nodeUpdate(ntree, node);
863                         tagged= 1;
864                 }
865                 /* here was tag render layer, but this is called after a render, so re-composites fail */
866                 else if (node->type==NODE_GROUP) {
867                         if ( ntreeCompositTagAnimated((bNodeTree *)node->id) ) {
868                                 nodeUpdate(ntree, node);
869                         }
870                 }
871                 else if (ELEM(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_TRANSFORM)) {
872                         nodeUpdate(ntree, node);
873                         tagged= 1;
874                 }
875         }
876         
877         return tagged;
878 }
879
880
881 /* called from image window preview */
882 void ntreeCompositTagGenerators(bNodeTree *ntree)
883 {
884         bNode *node;
885         
886         if (ntree==NULL) return;
887         
888         for (node= ntree->nodes.first; node; node= node->next) {
889                 if ( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE))
890                         nodeUpdate(ntree, node);
891         }
892 }
893
894 /* XXX after render animation system gets a refresh, this call allows composite to end clean */
895 void ntreeCompositClearTags(bNodeTree *ntree)
896 {
897         bNode *node;
898         
899         if (ntree==NULL) return;
900         
901         for (node= ntree->nodes.first; node; node= node->next) {
902                 node->need_exec= 0;
903                 if (node->type==NODE_GROUP)
904                         ntreeCompositClearTags((bNodeTree *)node->id);
905         }
906 }