3 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
19 * The Original Code is Copyright (C) 2006 Blender Foundation.
20 * All rights reserved.
22 * The Original Code is: all of this file.
24 * Contributor(s): none yet.
26 * ***** END GPL LICENSE BLOCK *****
34 #include "DNA_group_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_scene_types.h"
38 #include "BKE_global.h"
39 #include "BKE_image.h"
41 #include "BKE_scene.h"
42 #include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */
44 #include "MEM_guardedalloc.h"
46 #include "BLI_arithb.h"
47 #include "BLI_blenlib.h"
50 #include "IMB_imbuf.h"
51 #include "IMB_imbuf_types.h"
53 #include "RE_pipeline.h"
56 #include "BSE_sequence.h" /* <----------------- bad!!! */
59 #include "render_types.h"
60 #include "renderpipeline.h"
61 #include "renderdatabase.h"
62 #include "rendercore.h"
64 #include "initrender.h"
68 #include "SDL_thread.h"
74 - movie/image file init
75 - everything that doesn't change during animation
78 - camera, world, matrices
79 - make render verts, faces, halos, strands
80 - everything can change per frame/field
85 - layers/tiles optionally to disk or directly in Render Result
87 4) Composit Render Result
88 - also read external files etc
91 - save file or append in movie
96 /* ********* globals ******** */
98 /* here we store all renders */
99 static struct ListBase RenderList= {NULL, NULL};
101 /* hardcopy of current render, used while rendering for speed */
104 /* ********* alloc and free ******** */
107 static SDL_mutex *malloc_lock= NULL;
109 void *RE_mallocN(int len, char *name)
112 if(malloc_lock) SDL_mutexP(malloc_lock);
113 mem= MEM_mallocN(len, name);
114 if(malloc_lock) SDL_mutexV(malloc_lock);
117 void *RE_callocN(int len, char *name)
120 if(malloc_lock) SDL_mutexP(malloc_lock);
121 mem= MEM_callocN(len, name);
122 if(malloc_lock) SDL_mutexV(malloc_lock);
125 void RE_freeN(void *poin)
127 if(malloc_lock) SDL_mutexP(malloc_lock);
129 if(malloc_lock) SDL_mutexV(malloc_lock);
132 /* ********************** */
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);}
143 static void free_render_result(RenderResult *res)
145 if(res==NULL) return;
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);
156 MEM_freeN(res->rect32);
158 MEM_freeN(res->rectf);
163 /* called by main render as well for parts */
164 /* will read info from Render *re to define layers */
165 /* called in threads */
166 /* winrct is coordinate rect of entire image, partrct the part within */
167 static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
173 rectx= partrct->xmax - partrct->xmin;
174 recty= partrct->ymax - partrct->ymin;
176 if(rectx<=0 || recty<=0)
179 rr= RE_callocN(sizeof(RenderResult), "new render result");
182 /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
185 /* tilerect is relative coordinates within render disprect. do not subtract crop yet */
186 rr->tilerect.xmin= partrct->xmin - re->disprect.xmin;
187 rr->tilerect.xmax= partrct->xmax - re->disprect.xmax;
188 rr->tilerect.ymin= partrct->ymin - re->disprect.ymin;
189 rr->tilerect.ymax= partrct->ymax - re->disprect.ymax;
191 /* check renderdata for amount of layers */
192 /* for now just one */
193 rl= RE_callocN(sizeof(RenderLayer), "new render layer");
194 BLI_addtail(&rr->layers, rl);
196 rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
197 rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
203 /* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
204 /* no test happens here if it fits... */
205 /* is used within threads */
206 static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
208 RenderLayer *rl= rr->layers.first;
209 RenderLayer *rlp= rrpart->layers.first;
212 int y, height, len, copylen;
214 if(rlp->rectf==NULL) return;
215 if(rl->rectf==NULL) return;
217 rzp= NULL; //rlp->rectz;
220 copylen=len= rrpart->rectx;
221 height= rrpart->recty;
223 if(rrpart->crop) { /* filters add pixel extra */
225 if(rzp) rzp+= rrpart->crop + rrpart->crop*len;
226 if(rfp) rfp+= 4*(rrpart->crop + rrpart->crop*len);
228 copylen= len-2*rrpart->crop;
229 height -= 2*rrpart->crop;
231 // rz= re->rectz+ (pa->miny + rrpart->crop)*rr->rectx+ (pa->minx+rrpart->crop);
232 rf= rl->rectf+ ( (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop) )*4;
235 // rz= re->rectz + (pa->disprect.ymin*rr->rectx + pa->disprect.xmin);
236 rf= rl->rectf+ (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin)*4;
239 for(y=0; y<height; y++) {
241 memcpy(rz, rzp, 4*copylen);
246 memcpy(rf, rfp, 16*copylen);
254 /* *************************************************** */
256 Render *RE_GetRender(const char *name)
260 /* search for existing renders */
261 for(re= RenderList.first; re; re= re->next) {
262 if(strncmp(re->name, name, RE_MAXNAME)==0) {
269 /* if you want to know exactly what has been done */
270 RenderResult *RE_GetResult(Render *re)
277 /* fill provided result struct with what's currently active or done */
278 void RE_GetResultImage(Render *re, RenderResult *rr)
280 memset(rr, sizeof(RenderResult), 0);
282 if(re && re->result) {
285 rr->rectx= re->result->rectx;
286 rr->recty= re->result->recty;
287 rr->rectf= re->result->rectf;
288 rr->rectz= re->result->rectz;
289 rr->rect32= re->result->rect32;
291 /* will become 'active' call */
292 rl= re->result->layers.first;
294 rr->rectf= rl->rectf;
296 rr->rectz= rl->rectz;
300 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
301 /* caller is responsible for allocating rect in correct size! */
302 void RE_ResultGet32(Render *re, unsigned int *rect)
306 RE_GetResultImage(re, &rres);
308 memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty);
309 else if(rres.rectf) {
310 float *fp= rres.rectf;
311 int tot= rres.rectx*rres.recty;
312 char *cp= (char *)rect;
314 for(;tot>0; tot--, cp+=4, fp+=4) {
315 cp[0] = FTOCHAR(fp[0]);
316 cp[1] = FTOCHAR(fp[1]);
317 cp[2] = FTOCHAR(fp[2]);
318 cp[3] = FTOCHAR(fp[3]);
322 /* else fill with black */
323 memset(rect, sizeof(int)*re->rectx*re->recty, 0);
327 RenderStats *RE_GetStats(Render *re)
332 Render *RE_NewRender(const char *name)
336 /* only one render per name exists */
337 re= RE_GetRender(name);
339 BLI_remlink(&RenderList, re);
343 /* new render data struct */
344 re= RE_callocN(sizeof(Render), "new render");
345 BLI_addtail(&RenderList, re);
346 strncpy(re->name, name, RE_MAXNAME);
348 /* set default empty callbacks */
349 re->display_init= result_nothing;
350 re->display_clear= result_nothing;
351 re->display_draw= result_rcti_nothing;
352 re->timecursor= int_nothing;
353 re->test_break= void_nothing;
354 re->test_return= void_nothing;
355 re->error= print_error;
356 re->stats_draw= stats_nothing;
358 /* init some variables */
364 /* only call this while you know it will remove the link too */
365 void RE_FreeRender(Render *re)
368 free_renderdata_tables(re);
369 free_sample_tables(re);
371 free_render_result(re->result);
373 BLI_remlink(&RenderList, re);
378 void RE_FreeAllRender(void)
380 while(RenderList.first) {
381 RE_FreeRender(RenderList.first);
385 /* ********* initialize state ******** */
388 /* what doesn't change during entire render sequence */
389 /* disprect is optional, if NULL it assumes full window render */
390 void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect)
392 re->ok= TRUE; /* maybe flag */
394 re->i.starttime= PIL_check_seconds_timer();
395 re->r= *rd; /* hardcopy */
400 re->disprect= *disprect;
401 re->rectx= disprect->xmax-disprect->xmin;
402 re->recty= disprect->ymax-disprect->ymin;
405 re->disprect.xmin= re->disprect.xmax= 0;
406 re->disprect.xmax= winx;
407 re->disprect.ymax= winy;
412 if(re->rectx < 2 || re->recty < 2) {
413 re->error("Image too small");
417 /* check state variables, osa? */
418 if(re->r.mode & (R_OSA|R_MBLUR)) {
420 if(re->osa>16) re->osa= 16;
424 /* always call, checks for gamma, gamma tables and jitter too */
425 make_sample_tables(re);
427 /* initialize render result */
428 free_render_result(re->result);
429 re->result= new_render_result(re, &re->disprect, 0);
434 void RE_SetDispRect (struct Render *re, rcti *disprect)
436 re->disprect= *disprect;
437 re->rectx= disprect->xmax-disprect->xmin;
438 re->recty= disprect->ymax-disprect->ymin;
440 /* initialize render result */
441 free_render_result(re->result);
442 re->result= new_render_result(re, &re->disprect, 0);
445 void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend)
449 re->viewplane= *viewplane;
450 re->clipsta= clipsta;
451 re->clipend= clipend;
453 i_window(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat);
456 void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend)
460 re->viewplane= *viewplane;
461 re->clipsta= clipsta;
462 re->clipend= clipend;
463 re->r.mode |= R_ORTHO;
465 i_ortho(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat);
468 void RE_SetView(Render *re, float mat[][4])
471 Mat4CpyMat4(re->viewmat, mat);
472 Mat4Invert(re->viewinv, re->viewmat);
475 /* image and movie output has to move to either imbuf or kernel */
477 void RE_display_init_cb(Render *re, void (*f)(RenderResult *rr))
481 void RE_display_clear_cb(Render *re, void (*f)(RenderResult *rr))
483 re->display_clear= f;
485 void RE_display_draw_cb(Render *re, void (*f)(RenderResult *rr, rcti *rect))
490 void RE_stats_draw_cb(Render *re, void (*f)(RenderStats *rs))
494 void RE_timecursor_cb(Render *re, void (*f)(int))
499 void RE_test_break_cb(Render *re, int (*f)(void))
503 void RE_test_return_cb(Render *re, int (*f)(void))
507 void RE_error_cb(Render *re, void (*f)(const char *str))
513 /* ********* add object data (later) ******** */
515 /* object is considered fully prepared on correct time etc */
516 /* includes lights */
517 void RE_AddObject(Render *re, Object *ob)
522 /* ********** basic thread control API ************ */
524 #define RE_MAX_THREAD 4
526 typedef struct ThreadSlot {
531 static ThreadSlot threadslots[RE_MAX_THREAD];
533 static void init_threadslots(int tot)
537 if(tot>RE_MAX_THREAD) tot= RE_MAX_THREAD;
538 else if(tot<1) tot= 1;
540 for(a=0; a< RE_MAX_THREAD; a++) {
541 threadslots[a].part= NULL;
543 threadslots[a].avail= 1;
545 threadslots[a].avail= 0;
549 static int available_threadslots(void)
552 for(a=0; a< RE_MAX_THREAD; a++)
553 if(threadslots[a].avail)
558 static void insert_threadslot(RenderPart *pa)
561 for(a=0; a< RE_MAX_THREAD; a++) {
562 if(threadslots[a].avail) {
563 threadslots[a].avail= 0;
564 threadslots[a].part= pa;
571 static void remove_threadslot(RenderPart *pa)
574 for(a=0; a< RE_MAX_THREAD; a++) {
575 if(threadslots[a].part==pa) {
576 threadslots[a].avail= 1;
577 threadslots[a].part= NULL;
582 /* ********** basic thread control API ************ */
584 static int do_part_thread(void *pa_v)
586 RenderPart *pa= pa_v;
588 /* need to return nicely all parts on esc */
589 if(R.test_break()==0) {
591 pa->result= new_render_result(&R, &pa->disprect, pa->crop);
594 zbufshadeDA_tile(pa);
599 merge_render_result(R.result, pa->result);
603 remove_threadslot(pa);
608 /* returns with render result filled, not threaded */
609 static void render_tile_processor(Render *re)
616 re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
617 re->stats_draw(&re->i);
618 re->i.starttime= PIL_check_seconds_timer();
625 /* assuming no new data gets added to dbase... */
628 for(pa= re->parts.first; pa; pa= pa->next) {
632 if(!re->test_break()) {
633 re->display_draw(pa->result, NULL);
636 free_render_result(pa->result);
643 re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
644 re->stats_draw(&re->i);
649 static RenderPart *find_nicest_part(Render *re)
651 RenderPart *pa, *best= NULL;
652 int centx=re->winx/2, centy=re->winy/2, tot=1;
653 int mindist, distx, disty;
655 /* find center of rendered parts, image center counts for 1 too */
656 for(pa= re->parts.first; pa; pa= pa->next) {
658 centx+= (pa->disprect.xmin+pa->disprect.xmax)/2;
659 centy+= (pa->disprect.ymin+pa->disprect.ymax)/2;
666 /* closest of the non-rendering parts */
667 mindist= re->winx*re->winy;
668 for(pa= re->parts.first; pa; pa= pa->next) {
669 if(pa->ready==0 && pa->nr==0) {
670 distx= centx - (pa->disprect.xmin+pa->disprect.xmax)/2;
671 disty= centy - (pa->disprect.ymin+pa->disprect.ymax)/2;
672 distx= (int)sqrt(distx*distx + disty*disty);
682 static void threaded_tile_processor(Render *re)
685 int maxthreads=2, rendering=1, counter= 1;
693 init_threadslots(maxthreads);
695 /* assuming no new data gets added to dbase... */
698 malloc_lock = SDL_CreateMutex();
702 /* I noted that test_break() in a thread doesn't make ghost send ESC */
703 if(available_threadslots() && !re->test_break()) {
704 pa= find_nicest_part(re);
706 insert_threadslot(pa);
707 pa->nr= counter++; /* only for stats */
708 SDL_CreateThread(do_part_thread, pa);
714 /* check for ready ones to display, and if we need to continue */
716 for(pa= re->parts.first; pa; pa= pa->next) {
719 re->display_draw(pa->result, NULL);
720 free_render_result(pa->result);
728 /* on break, wait for all slots to get freed */
729 if(re->test_break() && available_threadslots()==maxthreads)
734 if(malloc_lock) SDL_DestroyMutex(malloc_lock); malloc_lock= NULL;
739 void RE_TileProcessor(Render *re)
741 if(re->r.mode & R_THREADS)
742 threaded_tile_processor(re);
744 render_tile_processor(re);
748 /* ************ This part uses API, for rendering Blender scenes ********** */
750 void render_one_frame(Render *re)
753 // re->cfra= cfra; /* <- unused! */
755 /* make render verts/faces/halos/lamps */
756 RE_Database_FromScene(re, re->scene, 1);
758 RE_TileProcessor(re);
760 /* free all render verts etc */
761 RE_Database_Free(re);
764 /* accumulates osa frames */
765 static void do_render_blurred(Render *re, float frame)
770 /* interleaves 2 frames */
771 static void do_render_fields(Render *re)
776 static void do_render_final(Render *re, Scene *scene)
778 /* we set start time here, for main Blender loops */
779 re->i.starttime= PIL_check_seconds_timer();
781 if(re->r.scemode & R_DOSEQ) {
782 re->result->rect32= MEM_callocN(sizeof(int)*re->rectx*re->recty, "rectot");
783 if(!re->test_break())
784 do_render_seq(re->result);
787 /* first check if theres nodetree with render result */
788 int do_render= ntreeCompositNeedsRender(scene->nodetree);
789 /* but.. do we use nodes? */
790 if(scene->use_nodes==NULL) do_render= 1;
795 /* now use renderdata and camera to set viewplane */
796 RE_SetCamera(re, re->scene->camera);
798 if(re->r.mode & R_FIELDS)
799 do_render_fields(re);
800 else if(re->r.mode & R_MBLUR)
801 do_render_blurred(re, re->scene->r.cfra);
803 render_one_frame(re);
805 if(re->r.scemode & R_DOCOMP)
806 ntreeCompositExecTree(scene->nodetree, &re->r, 0);
810 re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
811 re->stats_draw(&re->i);
813 re->display_draw(re->result, NULL);
818 static int is_rendering_allowed(Render *re)
821 /* forbidden combinations */
822 if(re->r.mode & R_PANORAMA) {
823 if(re->r.mode & R_BORDER) {
824 re->error("No border supported for Panorama");
828 re->error("No Y-Parts supported for Panorama");
831 if(re->r.mode & R_ORTHO) {
832 re->error("No Ortho render possible for Panorama");
837 if(re->r.mode & R_BORDER) {
838 if(re->r.border.xmax <= re->r.border.xmin ||
839 re->r.border.ymax <= re->r.border.ymin) {
840 re->error("No border area selected.");
845 if(re->r.xparts*re->r.yparts>=2 && (re->r.mode & R_MOVIECROP) && (re->r.mode & R_BORDER)) {
846 re->error("Combination of border, crop and parts not allowed");
850 if(re->r.xparts*re->r.yparts>64) {
851 re->error("No more than 64 parts supported");
855 if(re->r.yparts>1 && (re->r.mode & R_PANORAMA)) {
856 re->error("No Y-Parts supported for Panorama");
860 /* check valid camera */
861 if(re->scene->camera==NULL)
862 re->scene->camera= scene_find_camera(re->scene);
863 if(re->scene->camera==NULL) {
864 re->error("No camera");
872 /* evaluating scene options for general Blender render */
873 static int render_initialize_from_scene(Render *re, Scene *scene)
878 /* r.xsch and r.ysch has the actual view window size
879 r.border is the clipping rect */
881 /* calculate actual render result and display size */
882 winx= (scene->r.size*scene->r.xsch)/100;
883 winy= (scene->r.size*scene->r.ysch)/100;
884 // if(scene->r.mode & R_PANORAMA)
885 // winx*= scene->r.xparts;
887 /* only in movie case we render smaller part */
888 if(scene->r.mode & R_BORDER) {
889 disprect.xmin= scene->r.border.xmin*winx;
890 disprect.xmax= scene->r.border.xmax*winx;
892 disprect.ymin= scene->r.border.ymin*winy;
893 disprect.ymax= scene->r.border.ymax*winy;
896 disprect.xmin= disprect.ymin= 0;
901 RE_InitState(re, &scene->r, winx, winy, &disprect);
904 if(!is_rendering_allowed(re))
907 re->display_init(re->result);
908 re->display_clear(re->result);
913 /* general Blender frame render call */
914 /* should return 1 when all is OK, otherwise it throws up errors */
915 void RE_BlenderFrame(Render *re, Scene *scene, int frame)
917 /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
918 /* is also set by caller renderwin.c */
921 if(render_initialize_from_scene(re, scene)) {
922 do_render_final(re, scene);
927 /* saves images to disk */
928 void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
930 bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype);
931 int cfrao= scene->r.cfra;
932 char name[FILE_MAXDIR+FILE_MAXFILE];
934 /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
935 /* is also set by caller renderwin.c */
938 if(!render_initialize_from_scene(re, scene))
941 /* confusing... scene->r or re->r? make a decision once! */
942 if(BKE_imtype_is_movie(scene->r.imtype))
943 mh->start_movie(&scene->r, re->rectx, re->recty);
945 for(scene->r.cfra= sfra; scene->r.cfra<=efra; scene->r.cfra++) {
946 re->r.cfra= scene->r.cfra; /* weak.... */
948 do_render_final(re, scene);
950 /* write image or movie */
951 if(re->test_break()==0) {
954 RE_GetResultImage(re, &rres);
956 /* write movie or image */
957 if(BKE_imtype_is_movie(scene->r.imtype)) {
958 /* note; the way it gets 32 bits rects is weak... */
960 if(rres.rect32==NULL) {
961 rres.rect32= MEM_mallocN(sizeof(int)*rres.rectx*rres.recty, "temp 32 bits rect");
964 RE_ResultGet32(re, rres.rect32);
965 mh->append_movie(scene->r.cfra, rres.rect32, rres.rectx, rres.recty);
966 if(dofree) MEM_freeN(rres.rect32);
967 printf("Append frame %d", scene->r.cfra);
970 ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0);
973 BKE_makepicstring(name, (scene->r.cfra));
974 ibuf->rect= rres.rect32; /* if not exists, BKE_write_ibuf makes one */
975 ibuf->rect_float= rres.rectf;
976 ibuf->zbuf_float= rres.rectz;
977 ok= BKE_write_ibuf(ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
978 IMB_freeImBuf(ibuf); /* imbuf knows which rects are not part of ibuf */
981 printf("Render error: cannot save %s\n", name);
984 else printf("Saved: %s", name);
987 BLI_timestr(re->i.lastframetime, name);
988 printf(" Time: %s\n", name);
989 fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */
992 if(G.afbreek==1) break;
996 if(BKE_imtype_is_movie(scene->r.imtype))
999 scene->r.cfra= cfrao;