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