Render feature request; when saving EXR files during anim render, it can
[blender-staging.git] / source / blender / render / intern / source / pipeline.c
1 /**  
2  *
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. 
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2006 Blender Foundation.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <math.h>
30 #include <limits.h>
31 #include <string.h>
32 #include <stdlib.h>
33
34 #include "DNA_group_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_scene_types.h"
37
38 #include "BKE_global.h"
39 #include "BKE_image.h"
40 #include "BKE_node.h"
41 #include "BKE_scene.h"
42 #include "BKE_writeavi.h"       /* <------ should be replaced once with generic movie module */
43
44 #include "MEM_guardedalloc.h"
45
46 #include "BLI_arithb.h"
47 #include "BLI_blenlib.h"
48 #include "BLI_threads.h"
49
50 #include "PIL_time.h"
51 #include "IMB_imbuf.h"
52 #include "IMB_imbuf_types.h"
53
54 #include "RE_pipeline.h"
55 #include "radio.h"
56
57 #include "BSE_sequence.h"  /* <----------------- bad!!! */
58
59 /* internal */
60 #include "render_types.h"
61 #include "renderpipeline.h"
62 #include "renderdatabase.h"
63 #include "rendercore.h"
64 #include "envmap.h"
65 #include "initrender.h"
66 #include "shadbuf.h"
67 #include "zbuf.h"
68
69 #include "SDL_thread.h"
70 #include "SDL_mutex.h"
71
72 /* render flow
73
74 1) Initialize state
75 - state data, tables
76 - movie/image file init
77 - everything that doesn't change during animation
78
79 2) Initialize data
80 - camera, world, matrices
81 - make render verts, faces, halos, strands
82 - everything can change per frame/field
83
84 3) Render Processor
85 - multiple layers
86 - tiles, rect, baking
87 - layers/tiles optionally to disk or directly in Render Result
88
89 4) Composit Render Result
90 - also read external files etc
91
92 5) Image Files
93 - save file or append in movie
94
95 */
96
97
98 /* ********* globals ******** */
99
100 /* here we store all renders */
101 static struct ListBase RenderList= {NULL, NULL};
102
103 /* hardcopy of current render, used while rendering for speed */
104 Render R;
105
106 /* ********* alloc and free ******** */
107
108
109 static SDL_mutex *malloc_lock= NULL;
110
111 void *RE_mallocN(int len, char *name)
112 {
113         void *mem;
114         if(malloc_lock) SDL_mutexP(malloc_lock);
115         mem= MEM_mallocN(len, name);
116         if(malloc_lock) SDL_mutexV(malloc_lock);
117         return mem;
118 }
119 void *RE_callocN(int len, char *name)
120 {
121         void *mem;
122         if(malloc_lock) SDL_mutexP(malloc_lock);
123         mem= MEM_callocN(len, name);
124         if(malloc_lock) SDL_mutexV(malloc_lock);
125         return mem;
126 }
127 void RE_freeN(void *poin)
128 {
129         if(malloc_lock) SDL_mutexP(malloc_lock);
130         MEM_freeN(poin);
131         if(malloc_lock) SDL_mutexV(malloc_lock);
132 }
133
134 /* ********************** */
135
136 static int g_break= 0;
137 static int thread_break(void)
138 {
139         return g_break;
140 }
141
142 /* default callbacks, set in each new render */
143 static void result_nothing(RenderResult *rr) {}
144 static void result_rcti_nothing(RenderResult *rr, rcti *rect) {}
145 static void stats_nothing(RenderStats *rs) {}
146 static void int_nothing(int val) {}
147 static int void_nothing(void) {return 0;}
148 static void print_error(const char *str) {printf("ERROR: %s\n", str);}
149
150 static void free_render_result(RenderResult *res)
151 {
152         if(res==NULL) return;
153
154         while(res->layers.first) {
155                 RenderLayer *rl= res->layers.first;
156                 
157                 if(rl->rectf) RE_freeN(rl->rectf);
158                 while(rl->passes.first) {
159                         RenderPass *rpass= rl->passes.first;
160                         RE_freeN(rpass->rect);
161                         BLI_remlink(&rl->passes, rpass);
162                         RE_freeN(rpass);
163                 }
164                 BLI_remlink(&res->layers, rl);
165                 RE_freeN(rl);
166         }
167         
168         if(res->rect32)
169                 RE_freeN(res->rect32);
170         if(res->rectz)
171                 RE_freeN(res->rectz);
172         if(res->rectf)
173                 RE_freeN(res->rectf);
174         
175         RE_freeN(res);
176 }
177
178 static void render_layer_add_pass(RenderLayer *rl, int rectsize, int passtype, char *mallocstr)
179 {
180         RenderPass *rpass= RE_mallocN(sizeof(RenderPass), mallocstr);
181         
182         BLI_addtail(&rl->passes, rpass);
183         rpass->passtype= passtype;
184         rpass->rect= RE_callocN(sizeof(float)*rectsize, mallocstr);
185 }
186
187 float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype)
188 {
189         RenderPass *rpass;
190         
191         for(rpass=rl->passes.first; rpass; rpass= rpass->next)
192                 if(rpass->passtype== passtype)
193                         return rpass->rect;
194         return NULL;
195 }
196
197 /* called by main render as well for parts */
198 /* will read info from Render *re to define layers */
199 /* called in threads */
200 /* winrct is coordinate rect of entire image, partrct the part within */
201 static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
202 {
203         RenderResult *rr;
204         RenderLayer *rl;
205         SceneRenderLayer *srl;
206         int rectx, recty;
207         
208         rectx= partrct->xmax - partrct->xmin;
209         recty= partrct->ymax - partrct->ymin;
210         
211         if(rectx<=0 || recty<=0)
212                 return NULL;
213         
214         rr= RE_callocN(sizeof(RenderResult), "new render result");
215         rr->rectx= rectx;
216         rr->recty= recty;
217         /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
218         rr->crop= crop;
219         
220         /* tilerect is relative coordinates within render disprect. do not subtract crop yet */
221         rr->tilerect.xmin= partrct->xmin - re->disprect.xmin;
222         rr->tilerect.xmax= partrct->xmax - re->disprect.xmax;
223         rr->tilerect.ymin= partrct->ymin - re->disprect.ymin;
224         rr->tilerect.ymax= partrct->ymax - re->disprect.ymax;
225         
226         /* check renderdata for amount of layers */
227         for(srl= re->r.layers.first; srl; srl= srl->next) {
228                 rl= RE_callocN(sizeof(RenderLayer), "new render layer");
229                 BLI_addtail(&rr->layers, rl);
230                 
231                 strcpy(rl->name, srl->name);
232                 rl->lay= srl->lay;
233                 rl->layflag= srl->layflag;
234                 rl->passflag= srl->passflag;
235                 
236                 rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
237                 
238                 if(srl->passflag  & SCE_PASS_Z)
239                         render_layer_add_pass(rl, rectx*recty, SCE_PASS_Z, "Layer float Z");
240                 if(srl->passflag  & SCE_PASS_VECTOR)
241                         render_layer_add_pass(rl, rectx*recty*2, SCE_PASS_VECTOR, "layer float Vector");
242                 if(srl->passflag  & SCE_PASS_NORMAL)
243                         render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_NORMAL, "layer float Normal");
244                 if(srl->passflag  & SCE_PASS_RGBA)
245                         render_layer_add_pass(rl, rectx*recty*4, SCE_PASS_RGBA, "layer float Color");
246                 if(srl->passflag  & SCE_PASS_DIFFUSE)
247                         render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_DIFFUSE, "layer float Diffuse");
248                 if(srl->passflag  & SCE_PASS_SPEC)
249                         render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_SPEC, "layer float Spec");
250                 if(srl->passflag  & SCE_PASS_SHADOW)
251                         render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_SHADOW, "layer float Shadow");
252                 if(srl->passflag  & SCE_PASS_AO)
253                         render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_AO, "layer float AO");
254                 if(srl->passflag  & SCE_PASS_RAY)
255                         render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_RAY, "layer float Mirror");
256                 
257         }
258         /* previewrender and envmap don't do layers, so we make a default one */
259         if(rr->layers.first==NULL) {
260                 rl= RE_callocN(sizeof(RenderLayer), "new render layer");
261                 BLI_addtail(&rr->layers, rl);
262                 
263                 rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "prev/env float rgba");
264                 
265                 /* note, this has to be in sync with scene.c */
266                 rl->lay= (1<<20) -1;
267                 rl->layflag= 0x7FFF;    /* solid ztra halo strand */
268                 rl->passflag= SCE_PASS_COMBINED;
269         }
270         
271         return rr;
272 }
273
274 static int render_result_needs_vector(RenderResult *rr)
275 {
276         RenderLayer *rl;
277         
278         for(rl= rr->layers.first; rl; rl= rl->next)
279                 if(rl->passflag & SCE_PASS_VECTOR)
280                         return 1;
281         return 0;
282 }
283
284 static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
285 {
286         int y, ofs, copylen, tilex, tiley;
287         
288         copylen= tilex= rrpart->rectx;
289         tiley= rrpart->recty;
290         
291         if(rrpart->crop) {      /* filters add pixel extra */
292                 tile+= pixsize*(rrpart->crop + rrpart->crop*tilex);
293                 
294                 copylen= tilex - 2*rrpart->crop;
295                 tiley -= 2*rrpart->crop;
296                 
297                 ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop);
298                 target+= pixsize*ofs;
299         }
300         else {
301                 ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin);
302                 target+= pixsize*ofs;
303         }
304
305         copylen *= sizeof(float)*pixsize;
306         tilex *= pixsize;
307         ofs= pixsize*rr->rectx;
308
309         for(y=0; y<tiley; y++) {
310                 memcpy(target, tile, copylen);
311                 target+= ofs;
312                 tile+= tilex;
313         }
314 }
315
316 /* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
317 /* no test happens here if it fits... we also assume layers are in sync */
318 /* is used within threads */
319 static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
320 {
321         RenderLayer *rl, *rlp;
322         RenderPass *rpass, *rpassp;
323         
324         for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
325                 
326                 /* combined */
327                 if(rl->rectf && rlp->rectf)
328                         do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
329                 
330                 /* passes are allocated in sync */
331                 for(rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) {
332                         switch(rpass->passtype) {
333                                 case SCE_PASS_Z:
334                                         do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 1);
335                                         break;
336                                 case SCE_PASS_VECTOR:
337                                         do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 2);
338                                         break;
339                                 case SCE_PASS_RGBA:
340                                         do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 4);
341                                         break;
342                                 default:
343                                         do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 3);
344                         }
345                 }
346         }
347 }
348
349
350 /* *************************************************** */
351
352 Render *RE_GetRender(const char *name)
353 {
354         Render *re;
355         
356         /* search for existing renders */
357         for(re= RenderList.first; re; re= re->next) {
358                 if(strncmp(re->name, name, RE_MAXNAME)==0) {
359                         break;
360                 }
361         }
362         return re;
363 }
364
365 /* if you want to know exactly what has been done */
366 RenderResult *RE_GetResult(Render *re)
367 {
368         if(re)
369                 return re->result;
370         return NULL;
371 }
372
373 /* fill provided result struct with what's currently active or done */
374 void RE_GetResultImage(Render *re, RenderResult *rr)
375 {
376         memset(rr, 0, sizeof(RenderResult));
377
378         if(re && re->result) {
379                 RenderLayer *rl;
380                 
381                 rr->rectx= re->result->rectx;
382                 rr->recty= re->result->recty;
383                 
384                 rr->rectf= re->result->rectf;
385                 rr->rectz= re->result->rectz;
386                 rr->rect32= re->result->rect32;
387                 
388                 /* active layer */
389                 rl= BLI_findlink(&re->result->layers, re->r.actlay);
390                 if(rl) {
391                         if(rr->rectf==NULL)
392                                 rr->rectf= rl->rectf;
393                         if(rr->rectz==NULL)
394                                 rr->rectz= RE_RenderLayerGetPass(rl, SCE_PASS_Z);       
395                 }
396         }
397 }
398
399 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
400 /* caller is responsible for allocating rect in correct size! */
401 void RE_ResultGet32(Render *re, unsigned int *rect)
402 {
403         RenderResult rres;
404         
405         RE_GetResultImage(re, &rres);
406         if(rres.rect32) 
407                 memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty);
408         else if(rres.rectf) {
409                 float *fp= rres.rectf;
410                 int tot= rres.rectx*rres.recty;
411                 char *cp= (char *)rect;
412                 
413                 for(;tot>0; tot--, cp+=4, fp+=4) {
414                         cp[0] = FTOCHAR(fp[0]);
415                         cp[1] = FTOCHAR(fp[1]);
416                         cp[2] = FTOCHAR(fp[2]);
417                         cp[3] = FTOCHAR(fp[3]);
418                 }
419         }
420         else
421                 /* else fill with black */
422                 memset(rect, 0, sizeof(int)*re->rectx*re->recty);
423 }
424
425
426 RenderStats *RE_GetStats(Render *re)
427 {
428         return &re->i;
429 }
430
431 Render *RE_NewRender(const char *name)
432 {
433         Render *re;
434         
435         /* only one render per name exists */
436         re= RE_GetRender(name);
437         if(re) {
438                 BLI_remlink(&RenderList, re);
439                 RE_FreeRender(re);
440         }
441         
442         /* new render data struct */
443         re= RE_callocN(sizeof(Render), "new render");
444         BLI_addtail(&RenderList, re);
445         strncpy(re->name, name, RE_MAXNAME);
446         
447         /* set default empty callbacks */
448         re->display_init= result_nothing;
449         re->display_clear= result_nothing;
450         re->display_draw= result_rcti_nothing;
451         re->timecursor= int_nothing;
452         re->test_break= void_nothing;
453         re->test_return= void_nothing;
454         re->error= print_error; 
455         re->stats_draw= stats_nothing;
456         
457         /* init some variables */
458         re->ycor= 1.0f;
459         
460         return re;
461 }
462
463 /* only call this while you know it will remove the link too */
464 void RE_FreeRender(Render *re)
465 {
466         
467         free_renderdata_tables(re);
468         free_sample_tables(re);
469         
470         free_render_result(re->result);
471         
472         BLI_remlink(&RenderList, re);
473         RE_freeN(re);
474 }
475
476 /* exit blender */
477 void RE_FreeAllRender(void)
478 {
479         while(RenderList.first) {
480                 RE_FreeRender(RenderList.first);
481         }
482 }
483
484 /* ********* initialize state ******** */
485
486
487 /* what doesn't change during entire render sequence */
488 /* disprect is optional, if NULL it assumes full window render */
489 void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect)
490 {
491         re->ok= TRUE;   /* maybe flag */
492         
493         re->i.starttime= PIL_check_seconds_timer();
494         re->r= *rd;             /* hardcopy */
495         
496         re->winx= winx;
497         re->winy= winy;
498         if(disprect) {
499                 re->disprect= *disprect;
500                 re->rectx= disprect->xmax-disprect->xmin;
501                 re->recty= disprect->ymax-disprect->ymin;
502         }
503         else {
504                 re->disprect.xmin= re->disprect.xmax= 0;
505                 re->disprect.xmax= winx;
506                 re->disprect.ymax= winy;
507                 re->rectx= winx;
508                 re->recty= winy;
509         }
510         
511         if(re->rectx < 2 || re->recty < 2) {
512                 re->error("Image too small");
513                 re->ok= 0;
514         }
515         else {
516                 /* check state variables, osa? */
517                 if(re->r.mode & (R_OSA|R_MBLUR)) {
518                         re->osa= re->r.osa;
519                         if(re->osa>16) re->osa= 16;
520                 }
521                 else re->osa= 0;
522                 
523                 /* always call, checks for gamma, gamma tables and jitter too */
524                 make_sample_tables(re); 
525                 
526                 /* initialize render result */
527                 free_render_result(re->result);
528                 re->result= new_render_result(re, &re->disprect, 0);
529
530         }
531 }
532
533 void RE_SetDispRect (struct Render *re, rcti *disprect)
534 {
535         re->disprect= *disprect;
536         re->rectx= disprect->xmax-disprect->xmin;
537         re->recty= disprect->ymax-disprect->ymin;
538         
539         /* initialize render result */
540         free_render_result(re->result);
541         re->result= new_render_result(re, &re->disprect, 0);
542 }
543
544 void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend)
545 {
546         /* re->ok flag? */
547         
548         re->viewplane= *viewplane;
549         re->clipsta= clipsta;
550         re->clipend= clipend;
551
552         i_window(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat);
553 }
554
555 void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend)
556 {
557         /* re->ok flag? */
558         
559         re->viewplane= *viewplane;
560         re->clipsta= clipsta;
561         re->clipend= clipend;
562         re->r.mode |= R_ORTHO;
563
564         i_ortho(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat);
565 }
566
567 void RE_SetView(Render *re, float mat[][4])
568 {
569         /* re->ok flag? */
570         Mat4CpyMat4(re->viewmat, mat);
571         Mat4Invert(re->viewinv, re->viewmat);
572 }
573
574 /* image and movie output has to move to either imbuf or kernel */
575
576 void RE_display_init_cb(Render *re, void (*f)(RenderResult *rr))
577 {
578         re->display_init= f;
579 }
580 void RE_display_clear_cb(Render *re, void (*f)(RenderResult *rr))
581 {
582         re->display_clear= f;
583 }
584 void RE_display_draw_cb(Render *re, void (*f)(RenderResult *rr, rcti *rect))
585 {
586         re->display_draw= f;
587 }
588
589 void RE_stats_draw_cb(Render *re, void (*f)(RenderStats *rs))
590 {
591         re->stats_draw= f;
592 }
593 void RE_timecursor_cb(Render *re, void (*f)(int))
594 {
595         re->timecursor= f;
596 }
597
598 void RE_test_break_cb(Render *re, int (*f)(void))
599 {
600         re->test_break= f;
601 }
602 void RE_test_return_cb(Render *re, int (*f)(void))
603 {
604         re->test_return= f;
605 }
606 void RE_error_cb(Render *re, void (*f)(const char *str))
607 {
608         re->error= f;
609 }
610
611
612 /* ********* add object data (later) ******** */
613
614 /* object is considered fully prepared on correct time etc */
615 /* includes lights */
616 void RE_AddObject(Render *re, Object *ob)
617 {
618         
619 }
620
621 /* *************************************** */
622
623 static int do_part_thread(void *pa_v)
624 {
625         RenderPart *pa= pa_v;
626         
627         /* need to return nicely all parts on esc */
628         if(R.test_break()==0) {
629                 
630                 pa->result= new_render_result(&R, &pa->disprect, pa->crop);
631                 
632                 if(R.osa)
633                         zbufshadeDA_tile(pa);
634                 else
635                         zbufshade_tile(pa);
636                 
637                 /* merge too on break! */       
638                 merge_render_result(R.result, pa->result);
639         }
640         
641         pa->ready= 1;
642         
643         return 0;
644 }
645
646 /* returns with render result filled, not threaded */
647 static void render_tile_processor(Render *re)
648 {
649         RenderPart *pa;
650         
651         if(re->test_break())
652                 return;
653         
654         re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
655         re->stats_draw(&re->i);
656         re->i.starttime= PIL_check_seconds_timer();
657  
658         if(re->result==NULL)
659                 return;
660         
661         initparts(re);
662         
663         /* assuming no new data gets added to dbase... */
664         R= *re;
665         
666         for(pa= re->parts.first; pa; pa= pa->next) {
667                 do_part_thread(pa);
668                 
669                 if(pa->result) {
670                         if(!re->test_break()) {
671                                 re->display_draw(pa->result, NULL);
672                                 re->i.partsdone++;
673                         }
674                         free_render_result(pa->result);
675                         pa->result= NULL;
676                 }               
677                 if(re->test_break())
678                         break;
679         }
680         
681         re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
682         re->stats_draw(&re->i);
683
684         freeparts(re);
685 }
686
687 static RenderPart *find_nicest_part(Render *re)
688 {
689         RenderPart *pa, *best= NULL;
690         int centx=re->winx/2, centy=re->winy/2, tot=1;
691         int mindist, distx, disty;
692         
693         /* find center of rendered parts, image center counts for 1 too */
694         for(pa= re->parts.first; pa; pa= pa->next) {
695                 if(pa->ready) {
696                         centx+= (pa->disprect.xmin+pa->disprect.xmax)/2;
697                         centy+= (pa->disprect.ymin+pa->disprect.ymax)/2;
698                         tot++;
699                 }
700         }
701         centx/=tot;
702         centy/=tot;
703         
704         /* closest of the non-rendering parts */
705         mindist= re->winx*re->winy;
706         for(pa= re->parts.first; pa; pa= pa->next) {
707                 if(pa->ready==0 && pa->nr==0) {
708                         distx= centx - (pa->disprect.xmin+pa->disprect.xmax)/2;
709                         disty= centy - (pa->disprect.ymin+pa->disprect.ymax)/2;
710                         distx= (int)sqrt(distx*distx + disty*disty);
711                         if(distx<mindist) {
712                                 best= pa;
713                                 mindist= distx;
714                         }
715                 }
716         }
717         return best;
718 }
719
720 static void threaded_tile_processor(Render *re)
721 {
722         ListBase threads;
723         RenderPart *pa;
724         int maxthreads, rendering=1, counter= 1, hasdrawn, drawtimer=0;
725         
726         if(re->result==NULL)
727                 return;
728         if(re->test_break())
729                 return;
730         
731         if(re->r.mode & R_THREADS) maxthreads= 2;
732         else maxthreads= 1;
733         
734         initparts(re);
735         BLI_init_threads(&threads, do_part_thread, maxthreads);
736         
737         /* assuming no new data gets added to dbase... */
738         R= *re;
739         
740         /* set threadsafety */
741         R.test_break= thread_break;
742         malloc_lock = SDL_CreateMutex();
743         
744         while(rendering) {
745                 
746                 if(BLI_available_threads(&threads) && !re->test_break()) {
747                         pa= find_nicest_part(re);
748                         if(pa) {
749                                 pa->nr= counter++;      /* for nicest part, and for stats */
750                                 pa->thread= BLI_available_thread_index(&threads);       /* sample index */
751                                 BLI_insert_thread(&threads, pa);
752                         }
753                 }
754                 else {
755                         PIL_sleep_ms(50);
756                         drawtimer++;
757                 }
758                 
759                 /* check for ready ones to display, and if we need to continue */
760                 hasdrawn= 0;
761                 rendering= 0;
762                 for(pa= re->parts.first; pa; pa= pa->next) {
763                         if(pa->ready) {
764                                 if(pa->result) {
765                                         BLI_remove_thread(&threads, pa);
766                                         re->display_draw(pa->result, NULL);
767                                         free_render_result(pa->result);
768                                         pa->result= NULL;
769                                         re->i.partsdone++;
770                                         hasdrawn= 1;
771                                 }
772                         }
773                         else {
774                                 rendering= 1;
775                                 if(pa->nr && pa->result && drawtimer>20) {
776                                         re->display_draw(pa->result, &pa->result->renrect);
777                                         hasdrawn= 1;
778                                 }
779                         }
780                 }
781                 
782                 if(hasdrawn)
783                         drawtimer= 0;
784                 
785                 /* on break, wait for all slots to get freed */
786                 if( (g_break=re->test_break()) && BLI_available_threads(&threads)==maxthreads)
787                         rendering= 0;
788                 
789         }
790         
791         /* restore threadsafety */
792         if(malloc_lock) SDL_DestroyMutex(malloc_lock); malloc_lock= NULL;
793         g_break= 0;
794         
795         BLI_end_threads(&threads);
796         freeparts(re);
797 }
798
799 void RE_TileProcessor(Render *re)
800 {
801         if(0) 
802                 threaded_tile_processor(re);
803         else
804                 render_tile_processor(re);      
805 }
806
807
808 /* ************  This part uses API, for rendering Blender scenes ********** */
809
810 void render_one_frame(Render *re)
811 {
812         
813 //      re->cfra= cfra; /* <- unused! */
814         
815         /* make render verts/faces/halos/lamps */
816         if(render_result_needs_vector(re->result))
817                 RE_Database_FromScene_Vectors(re, re->scene);
818         else
819            RE_Database_FromScene(re, re->scene, 1);
820         
821         threaded_tile_processor(re);
822         
823         /* free all render verts etc */
824         RE_Database_Free(re);
825 }
826
827 /* accumulates osa frames */
828 static void do_render_blurred(Render *re, float frame)
829 {
830         
831 }
832
833 /* interleaves 2 frames */
834 static void do_render_fields(Render *re)
835 {
836         
837 }
838
839 static void ntree_render_scenes(Render *re)
840 {
841         SceneRenderLayer *srl;
842         
843         for(srl= re->r.layers.first; srl; srl= srl->next) {
844                 
845         }
846 }
847
848 static void do_render_final(Render *re, Scene *scene)
849 {
850         /* we set start time here, for main Blender loops */
851         re->i.starttime= PIL_check_seconds_timer();
852
853         if(re->r.scemode & R_DOSEQ) {
854                 re->result->rect32= RE_callocN(sizeof(int)*re->rectx*re->recty, "rectot");
855                 if(!re->test_break()) 
856                         do_render_seq(re->result);
857         }
858         else {
859                 /* first check if theres nodetree with render result */
860                 int do_render= ntreeCompositNeedsRender(scene->nodetree);
861                 /* but.. do we use nodes? */
862                 if(scene->use_nodes==0) do_render= 1;
863                 
864                 re->scene= scene;
865                 
866                 if(do_render) {
867                         /* now use renderdata and camera to set viewplane */
868                         RE_SetCamera(re, re->scene->camera);
869                         
870                         if(re->r.mode & R_FIELDS)
871                                 do_render_fields(re);
872                         else if(re->r.mode & R_MBLUR)
873                                 do_render_blurred(re, re->scene->r.cfra);
874                         else
875                                 render_one_frame(re);
876                 }
877                 
878                 if(!re->test_break()) {
879                         /* checks if there are layer nodes that need scene */
880                         ntree_render_scenes(re);
881                         
882                         ntreeCompositTagRender(scene->nodetree);
883                         ntreeCompositTagAnimated(scene->nodetree);
884                         
885                         if(re->r.scemode & R_DOCOMP)
886                                 ntreeCompositExecTree(scene->nodetree, &re->r, G.background==0);
887                 }
888         }
889         
890
891         re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
892         re->stats_draw(&re->i);
893         
894         re->display_draw(re->result, NULL);
895         
896 }
897
898
899 static int is_rendering_allowed(Render *re)
900 {
901         
902         /* forbidden combinations */
903         if(re->r.mode & R_PANORAMA) {
904                 if(re->r.mode & R_BORDER) {
905                         re->error("No border supported for Panorama");
906                         return 0;
907                 }
908                 if(re->r.yparts>1) {
909                         re->error("No Y-Parts supported for Panorama");
910                         return 0;
911                 }
912                 if(re->r.mode & R_ORTHO) {
913                         re->error("No Ortho render possible for Panorama");
914                         return 0;
915                 }
916         }
917         
918         if(re->r.mode & R_BORDER) {
919                 if(re->r.border.xmax <= re->r.border.xmin || 
920                    re->r.border.ymax <= re->r.border.ymin) {
921                         re->error("No border area selected.");
922                         return 0;
923                 }
924         }
925         
926         if(re->r.xparts*re->r.yparts>=2 && (re->r.mode & R_MOVIECROP) && (re->r.mode & R_BORDER)) {
927                 re->error("Combination of border, crop and parts not allowed");
928                 return 0;
929         }
930         
931         if(re->r.xparts*re->r.yparts>64) {
932                 re->error("No more than 64 parts supported");
933                 return 0;
934         }
935         
936         if(re->r.yparts>1 && (re->r.mode & R_PANORAMA)) {
937                 re->error("No Y-Parts supported for Panorama");
938                 return 0;
939         }
940         
941         /* check valid camera */
942         if(re->scene->camera==NULL)
943                 re->scene->camera= scene_find_camera(re->scene);
944         if(re->scene->camera==NULL) {
945                 re->error("No camera");
946                 return 0;
947         }
948         
949         
950         return 1;
951 }
952
953 /* evaluating scene options for general Blender render */
954 static int render_initialize_from_scene(Render *re, Scene *scene)
955 {
956         int winx, winy;
957         rcti disprect;
958         
959         /* r.xsch and r.ysch has the actual view window size
960                 r.border is the clipping rect */
961         
962         /* calculate actual render result and display size */
963         winx= (scene->r.size*scene->r.xsch)/100;
964         winy= (scene->r.size*scene->r.ysch)/100;
965         //      if(scene->r.mode & R_PANORAMA)
966         //              winx*= scene->r.xparts;
967         
968         /* only in movie case we render smaller part */
969         if(scene->r.mode & R_BORDER) {
970                 disprect.xmin= scene->r.border.xmin*winx;
971                 disprect.xmax= scene->r.border.xmax*winx;
972                 
973                 disprect.ymin= scene->r.border.ymin*winy;
974                 disprect.ymax= scene->r.border.ymax*winy;
975         }
976         else {
977                 disprect.xmin= disprect.ymin= 0;
978                 disprect.xmax= winx;
979                 disprect.ymax= winy;
980         }
981         
982         RE_InitState(re, &scene->r, winx, winy, &disprect);
983         
984         re->scene= scene;
985         if(!is_rendering_allowed(re))
986                 return 0;
987         
988         re->display_init(re->result);
989         re->display_clear(re->result);
990         
991         return 1;
992 }
993
994 /* general Blender frame render call */
995 void RE_BlenderFrame(Render *re, Scene *scene, int frame)
996 {
997         /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
998         /* is also set by caller renderwin.c */
999         G.rendering= 1;
1000         
1001         if(render_initialize_from_scene(re, scene)) {
1002                 do_render_final(re, scene);
1003         }
1004 }
1005
1006
1007 /* saves images to disk */
1008 void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
1009 {
1010         bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype);
1011         int cfrao= scene->r.cfra;
1012         char name[FILE_MAXDIR+FILE_MAXFILE];
1013         
1014         /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
1015         /* is also set by caller renderwin.c */
1016         G.rendering= 1;
1017         
1018         if(!render_initialize_from_scene(re, scene))
1019            return;
1020         
1021         /* confusing... scene->r or re->r? make a decision once! */
1022         if(BKE_imtype_is_movie(scene->r.imtype))
1023                 mh->start_movie(&scene->r, re->rectx, re->recty);
1024         
1025         for(scene->r.cfra= sfra; scene->r.cfra<=efra; scene->r.cfra++) {
1026                 re->r.cfra= scene->r.cfra;      /* weak.... */
1027                 
1028                 do_render_final(re, scene);
1029                 
1030                 /* write image or movie */
1031                 if(re->test_break()==0) {
1032                         RenderResult rres;
1033                         
1034                         RE_GetResultImage(re, &rres);
1035
1036                         /* write movie or image */
1037                         if(BKE_imtype_is_movie(scene->r.imtype)) {
1038                                 /* note; the way it gets 32 bits rects is weak... */
1039                                 int dofree=0;
1040                                 if(rres.rect32==NULL) {
1041                                         rres.rect32= RE_mallocN(sizeof(int)*rres.rectx*rres.recty, "temp 32 bits rect");
1042                                         dofree= 1;
1043                                 }
1044                                 RE_ResultGet32(re, rres.rect32);
1045                                 mh->append_movie(scene->r.cfra, rres.rect32, rres.rectx, rres.recty);
1046                                 if(dofree) RE_freeN(rres.rect32);
1047                                 printf("Append frame %d", scene->r.cfra);
1048                         }
1049                         else {
1050                                 ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0);
1051                                 int ok;
1052                                 
1053                                 BKE_makepicstring(name, (scene->r.cfra));
1054                                 ibuf->rect= rres.rect32;                /* if not exists, BKE_write_ibuf makes one */
1055                                 ibuf->rect_float= rres.rectf;
1056                                 ibuf->zbuf_float= rres.rectz;
1057                                 ok= BKE_write_ibuf(ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
1058                                 if(ok==0) {
1059                                         printf("Render error: cannot save %s\n", name);
1060                                         break;
1061                                 }
1062                                 else printf("Saved: %s", name);
1063                                 
1064                                 /* optional preview images for exr */
1065                                 if(ok && scene->r.imtype==R_OPENEXR && (scene->r.subimtype & R_PREVIEW_JPG)) {
1066                                         if(BLI_testextensie(name, ".exr")) name[strlen(name)-4]= 0;
1067                                         BKE_add_image_extension(name, R_JPEG90);
1068                                         BKE_write_ibuf(ibuf, name, R_JPEG90, scene->r.subimtype, scene->r.quality);
1069                                         printf("Saved: %s", name);
1070                                 }
1071                                    
1072                                 IMB_freeImBuf(ibuf);    /* imbuf knows which rects are not part of ibuf */
1073                         }
1074                         
1075                         BLI_timestr(re->i.lastframetime, name);
1076                         printf(" Time: %s\n", name);
1077                         fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */
1078                 }
1079                 
1080                 if(G.afbreek==1) break;
1081         }
1082         
1083         /* end movie */
1084         if(BKE_imtype_is_movie(scene->r.imtype))
1085                 mh->end_movie();
1086
1087         scene->r.cfra= cfrao;
1088 }
1089
1090
1091