Created threadsafe MEM_malloc versions in BLI_threads.h, now in use
[blender.git] / source / blender / render / intern / source / pipeline.c
index b53393b1cd0fe7b84648a62742c831709f1ce964..375cb5f3a0c1719e2244d0d3aa75f488403e1960 100644 (file)
@@ -45,6 +45,7 @@
 
 #include "BLI_arithb.h"
 #include "BLI_blenlib.h"
+#include "BLI_threads.h"
 
 #include "PIL_time.h"
 #include "IMB_imbuf.h"
@@ -66,6 +67,7 @@
 #include "zbuf.h"
 
 #include "SDL_thread.h"
+#include "SDL_mutex.h"
 
 /* render flow
 
@@ -153,11 +155,11 @@ static void free_render_result(RenderResult *res)
        }
        
        if(res->rect32)
-               MEM_freeN(res->rect32);
+               RE_freeN(res->rect32);
        if(res->rectz)
-               MEM_freeN(res->rectz);
+               RE_freeN(res->rectz);
        if(res->rectf)
-               MEM_freeN(res->rectf);
+               RE_freeN(res->rectf);
        
        RE_freeN(res);
 }
@@ -214,8 +216,14 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
                rl= RE_callocN(sizeof(RenderLayer), "new render layer");
                BLI_addtail(&rr->layers, rl);
                
-               rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
-               rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
+               rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "prev/env float rgba");
+               rl->rectz= RE_callocN(rectx*recty*sizeof(float), "prev/env float Z");
+               
+               /* note, this has to be in sync with scene.c */
+               rl->lay= (1<<20) -1;
+               rl->layflag= 0x7FFF;    /* solid ztra halo strand */
+               rl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;
+               
        }
        
        return rr;
@@ -550,67 +558,7 @@ void RE_AddObject(Render *re, Object *ob)
        
 }
 
-/* ********** basic thread control API ************ */
-
-#define RE_MAX_THREAD 4
-
-typedef struct ThreadSlot {
-       RenderPart *part;
-       int avail;
-} ThreadSlot;
-
-static ThreadSlot threadslots[RE_MAX_THREAD];
-
-static void init_threadslots(int tot)
-{
-       int a;
-       
-       if(tot>RE_MAX_THREAD) tot= RE_MAX_THREAD;
-       else if(tot<1) tot= 1;
-       
-       for(a=0; a< RE_MAX_THREAD; a++) {
-               threadslots[a].part= NULL;
-               if(a<tot)
-                       threadslots[a].avail= 1;
-               else
-                       threadslots[a].avail= 0;
-       }
-}
-
-static int available_threadslots(void)
-{
-       int a, counter=0;
-       for(a=0; a< RE_MAX_THREAD; a++)
-               if(threadslots[a].avail)
-                       counter++;
-       return counter;
-}
-
-static void insert_threadslot(RenderPart *pa)
-{
-       int a;
-       for(a=0; a< RE_MAX_THREAD; a++) {
-               if(threadslots[a].avail) {
-                       threadslots[a].avail= 0;
-                       threadslots[a].part= pa;
-                       pa->thread= a;
-                       break;
-               }
-       }
-}
-
-static void remove_threadslot(RenderPart *pa)
-{
-       int a;
-       for(a=0; a< RE_MAX_THREAD; a++) {
-               if(threadslots[a].part==pa) {
-                       threadslots[a].avail= 1;
-                       threadslots[a].part= NULL;
-               }
-       }
-}
-
-/* ********** basic thread control API ************ */
+/* *************************************** */
 
 static int do_part_thread(void *pa_v)
 {
@@ -631,7 +579,6 @@ static int do_part_thread(void *pa_v)
        }
        
        pa->ready= 1;
-       remove_threadslot(pa);
        
        return 0;
 }
@@ -712,6 +659,7 @@ static RenderPart *find_nicest_part(Render *re)
 
 static void threaded_tile_processor(Render *re)
 {
+       ListBase threads;
        RenderPart *pa;
        int maxthreads=2, rendering=1, counter= 1;
        
@@ -721,7 +669,7 @@ static void threaded_tile_processor(Render *re)
                return;
        
        initparts(re);
-       init_threadslots(maxthreads);
+       BLI_init_threads(&threads, do_part_thread, maxthreads);
        
        /* assuming no new data gets added to dbase... */
        R= *re;
@@ -731,12 +679,12 @@ static void threaded_tile_processor(Render *re)
        while(rendering) {
                
                /* I noted that test_break() in a thread doesn't make ghost send ESC */
-               if(available_threadslots() && !re->test_break()) {
+               if(BLI_available_threads(&threads) && !re->test_break()) {
                        pa= find_nicest_part(re);
                        if(pa) {
-                               insert_threadslot(pa);
-                               pa->nr= counter++;      /* only for stats */
-                               SDL_CreateThread(do_part_thread, pa);
+                               pa->nr= counter++;      /* for nicest part, and for stats */
+                               pa->thread= BLI_available_thread_index(&threads);       /* sample index */
+                               BLI_insert_thread(&threads, pa);
                        }
                }
                else
@@ -747,6 +695,7 @@ static void threaded_tile_processor(Render *re)
                for(pa= re->parts.first; pa; pa= pa->next) {
                        if(pa->ready) {
                                if(pa->result) {
+                                       BLI_remove_thread(&threads, pa);
                                        re->display_draw(pa->result, NULL);
                                        free_render_result(pa->result);
                                        pa->result= NULL;
@@ -757,13 +706,14 @@ static void threaded_tile_processor(Render *re)
                }
                
                /* on break, wait for all slots to get freed */
-               if(re->test_break() && available_threadslots()==maxthreads)
+               if(re->test_break() && BLI_available_threads(&threads)==maxthreads)
                        rendering= 0;
                
        }
        
        if(malloc_lock) SDL_DestroyMutex(malloc_lock); malloc_lock= NULL;
        
+       BLI_end_threads(&threads);
        freeparts(re);
 }
 
@@ -818,7 +768,7 @@ static void do_render_final(Render *re, Scene *scene)
                /* first check if theres nodetree with render result */
                int do_render= ntreeCompositNeedsRender(scene->nodetree);
                /* but.. do we use nodes? */
-               if(scene->use_nodes==NULL) do_render= 1;
+               if(scene->use_nodes==0) do_render= 1;
                
                re->scene= scene;
                
@@ -833,6 +783,10 @@ static void do_render_final(Render *re, Scene *scene)
                        else
                                render_one_frame(re);
                }
+               
+               ntreeCompositTagRender(scene->nodetree);
+               ntreeCompositTagAnimated(scene->nodetree);
+               
                if(re->r.scemode & R_DOCOMP)
                        ntreeCompositExecTree(scene->nodetree, &re->r, 0);
        }