Two fixes in renderpipe...
authorTon Roosendaal <ton@blender.org>
Mon, 13 Mar 2006 11:01:17 +0000 (11:01 +0000)
committerTon Roosendaal <ton@blender.org>
Mon, 13 Mar 2006 11:01:17 +0000 (11:01 +0000)
- Renderwin still used a thread-unsafe malloc, in the header text print

- Setting clipping flags in vertices for parts required a mutex lock after
  all... I thought it would go fine, but noticed on renders with small
  amounts of faces that sometimes faces disappear from a render.
  (was doing movie credits, so all faces are visible! Otherwise it would
  have hardly been noticable...)

source/blender/blenkernel/intern/node_composite.c
source/blender/blenlib/BLI_threads.h
source/blender/blenlib/intern/threads.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/imagetexture.c
source/blender/render/intern/source/zbuf.c
source/blender/src/renderwin.c

index 1eebe1c251029865b4d3c1ad007e10eaba5abf97..c09d8a6c664468397ca6ecba1937711ed4d769be 100644 (file)
@@ -779,9 +779,9 @@ static CompBuf *node_composit_get_image(bNode *node, RenderData *rd)
        if(ima->ok==0) return NULL;
        
        if(ima->ibuf==NULL) {
-               BLI_lock_thread();
+               BLI_lock_thread(LOCK_MALLOC);
                load_image(ima, IB_rect, G.sce, rd->cfra);      /* G.sce is current .blend path */
-               BLI_unlock_thread();
+               BLI_unlock_thread(LOCK_MALLOC);
                if(ima->ibuf==NULL) {
                        ima->ok= 0;
                        return NULL;
index 00ea4f7aaabd54ddf6b30467ff063f24a49ece27..43792ccb1bc51a38e3d2af56fd07f61c1f6a0331 100644 (file)
 #ifndef BLI_THREADS_H
 #define BLI_THREADS_H 
 
+/* default lock is to protect MEM_ module calls, one custom lock available now. van be extended */
+#define LOCK_MALLOC            0
+#define LOCK_CUSTOM1   1
+
 
 void   BLI_init_threads        (ListBase *threadbase, void *(*do_thread)(void *), int tot);
 int            BLI_available_threads(ListBase *threadbase);
@@ -39,8 +43,8 @@ void  BLI_insert_thread       (ListBase *threadbase, void *callerdata);
 void   BLI_remove_thread       (ListBase *threadbase, void *callerdata);
 void   BLI_end_threads         (ListBase *threadbase);
 
-void   BLI_lock_thread         (void);
-void   BLI_unlock_thread       (void);
+void   BLI_lock_thread         (int type);
+void   BLI_unlock_thread       (int type);
 
                /* threadsafe version of MEM_malloc and friends */
 void   *MEM_mallocT(int len, char *name);
index ba1539bb0fa3a91acdfbf849422c3d6f045d1d28..f94d959d46a5fe0c4aaf13cb8c1124d2ef9146e1 100644 (file)
@@ -84,6 +84,7 @@ A sample loop can look like this (pseudo c);
 
  ************************************************ */
 static pthread_mutex_t _malloc_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER;
 
 /* just a max for security reasons */
 #define RE_MAX_THREAD  8
@@ -183,14 +184,20 @@ void BLI_end_threads(ListBase *threadbase)
        
 }
 
-void BLI_lock_thread(void)
+void BLI_lock_thread(int type)
 {
-       pthread_mutex_lock(&_malloc_lock);
+       if(type==LOCK_MALLOC)
+               pthread_mutex_lock(&_malloc_lock);
+       else
+               pthread_mutex_lock(&_custom1_lock);
 }
 
-void BLI_unlock_thread(void)
+void BLI_unlock_thread(int type)
 {
-       pthread_mutex_unlock(&_malloc_lock);
+       if(type==LOCK_MALLOC)
+               pthread_mutex_unlock(&_malloc_lock);
+       else
+               pthread_mutex_unlock(&_custom1_lock);
 }
 
 
index b173be4bc9bec3c82ecf973f8ca8eb00a80eff01..8112ece8c097d3a04e59ca4e8a2b631f909c4e21 100644 (file)
@@ -595,10 +595,10 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
                env->ima= tex->ima;
                if(env->ima && env->ima->ok) {
                        // Now thread safe
-                       BLI_lock_thread();
+                       BLI_lock_thread(LOCK_MALLOC);
                        if(env->ima->ibuf==NULL) ima_ibuf_is_nul(tex, tex->ima);
                        if(env->ima->ok && env->ok==0) envmap_split_ima(env);
-                       BLI_unlock_thread();
+                       BLI_unlock_thread(LOCK_MALLOC);
                }
        }
 
index 4552aba421a464a2839b6d363d03e6ac835c155a..38d47d3d7cb05929cc073b78443e326f4d3d9ec1 100644 (file)
@@ -105,9 +105,9 @@ int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres)
        }
        
        if(ima->ibuf==NULL) {
-               BLI_lock_thread();
+               BLI_lock_thread(LOCK_MALLOC);
                if(ima->ibuf==NULL) ima_ibuf_is_nul(tex, ima);
-               BLI_unlock_thread();
+               BLI_unlock_thread(LOCK_MALLOC);
        }
 
        if (ima->ok) {
@@ -608,18 +608,18 @@ int imagewraposa(Tex *tex, Image *ima, float *texvec, float *dxt, float *dyt, Te
        }
        
        if(ima->ibuf==NULL) {
-               BLI_lock_thread();
+               BLI_lock_thread(LOCK_MALLOC);
                if(ima->ibuf==NULL) ima_ibuf_is_nul(tex, ima);
-               BLI_unlock_thread();
+               BLI_unlock_thread(LOCK_MALLOC);
        }
        
        if (ima->ok) {
        
                if(tex->imaflag & TEX_MIPMAP) {
                        if(ima->mipmap[0]==NULL) {
-                               BLI_lock_thread();
+                               BLI_lock_thread(LOCK_MALLOC);
                                if(ima->mipmap[0]==NULL) makemipmap(tex, ima);
-                               BLI_unlock_thread();
+                               BLI_unlock_thread(LOCK_MALLOC);
                        }
                }
        
index 4d6f0610ff5cab48c32e19abf25077e75e1a9331..bf46158ba8c74b5387cbdf99ab387402db61975e 100644 (file)
@@ -1572,8 +1572,12 @@ void set_part_zbuf_clipflag(RenderPart *pa)
        /* supports up to 4 threads this way */
        clipclear= ~(15 << 4*(pa->thread & 3));
        
+       /* extra security to prevent access to same data */
+       BLI_lock_thread(LOCK_CUSTOM1);
+       
        for(v=0; v<R.totvert; v++) {
-               if((v & 255)==0) ver= RE_findOrAddVert(&R, v);
+               if((v & 255)==0)
+                       ver= RE_findOrAddVert(&R, v);
                else ver++;
                
                wco= ver->ho[3];
@@ -1606,6 +1610,8 @@ void set_part_zbuf_clipflag(RenderPart *pa)
                                break;
                }
        }
+       
+       BLI_unlock_thread(LOCK_CUSTOM1);
 }
 
 void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag)
index e115857e8935e7bf7fec98e8d48143ba145f2f8b..0816618d7ca4d45093936403830a345c36c4411f 100644 (file)
@@ -56,6 +56,7 @@
 #include <limits.h>
 
 #include "BLI_blenlib.h"
+#include "BLI_threads.h"
 
 #include "MEM_guardedalloc.h"
 
 /* space for info text */
 #define RW_HEADERY             18
 
+/* header print for window */
+#define RW_MAXTEXT             512
+
 typedef struct {
        Window *win;
 
@@ -164,7 +168,8 @@ static RenderWin *renderwin_alloc(Window *win)
        rw->flags= 0;
        rw->zoomofs[0]= rw->zoomofs[1]= 0;
        rw->info_text= NULL;
-       rw->render_text= rw->render_text_spare= NULL;
+       rw->render_text= MEM_callocN(RW_MAXTEXT, "rendertext");
+       rw->render_text_spare= MEM_callocN(RW_MAXTEXT, "rendertext spare");
 
        rw->lmouse[0]= rw->lmouse[1]= 0;
        rw->mbut[0]= rw->mbut[1]= rw->mbut[2]= 0;
@@ -754,7 +759,8 @@ static void glaDrawPixelsSafe_to32(float fx, float fy, int img_w, int img_h, int
        /* copy imgw-imgh to a temporal 32 bits rect */
        if(img_w<1 || img_h<1) return;
        
-       rc= rect32= MEM_mallocN(img_w*img_h*sizeof(int), "temp 32 bits");
+       /* happens during threaded render... */
+       rc= rect32= MEM_mallocT(img_w*img_h*sizeof(int), "temp 32 bits");
        
        for(y=0; y<img_h; y++) {
                rf= rectf;
@@ -769,7 +775,7 @@ static void glaDrawPixelsSafe_to32(float fx, float fy, int img_w, int img_h, int
        
        glaDrawPixelsSafe(fx, fy, img_w, img_h, img_w, GL_RGBA, GL_UNSIGNED_BYTE, rect32);
                
-       MEM_freeN(rect32);
+       MEM_freeT(rect32);
 }
 
 /* XXX, this is not good, we do this without any regard to state
@@ -869,7 +875,7 @@ static void printrenderinfo_cb(RenderStats *rs)
        extern char info_time_str[32];  // header_info.c
        extern unsigned long mem_in_use, mmap_in_use;
        static float megs_used_memory, mmap_used_memory;
-       char str[300], *spos= str;
+       char *spos= render_win->render_text;
                
        megs_used_memory= (mem_in_use-mmap_in_use)/(1024.0*1024.0);
        mmap_used_memory= (mmap_in_use)/(1024.0*1024.0);
@@ -891,8 +897,10 @@ static void printrenderinfo_cb(RenderStats *rs)
                if(rs->infostr)
                        spos+= sprintf(spos, " | %s", rs->infostr);
                
-               if(render_win->render_text) MEM_freeN(render_win->render_text);
-               render_win->render_text= BLI_strdup(str);
+               /* very weak... but 512 characters is quite safe... we cannot malloc during thread render */
+               if(spos >= render_win->render_text+RW_MAXTEXT)
+                       printf("WARNING! renderwin text beyond limit \n");
+               
 #ifdef __APPLE__
 #else
                glDrawBuffer(GL_FRONT);
@@ -910,6 +918,7 @@ static void printrenderinfo_cb(RenderStats *rs)
 
        /* temporal render debug printing, needed for testing orange renders atm... will be gone soon (or option) */
        if(G.rt==7 && rs->convertdone) {
+               char str[256];
                spos= str;
                spos+= sprintf(spos, "Fra:%d Mem:%.2fM (%.2fM)", G.scene->r.cfra, megs_used_memory, mmap_used_memory);
                
@@ -1137,9 +1146,7 @@ static void renderwin_store_spare(void)
                window_set_title(render_win->win, renderwin_get_title(1));
        }
        
-       if(render_win->render_text_spare) MEM_freeN(render_win->render_text_spare);
-       render_win->render_text_spare= render_win->render_text;
-       render_win->render_text= NULL;
+       BLI_strncpy(render_win->render_text_spare, render_win->render_text, RW_MAXTEXT);
        
        if(render_win->rectspare) MEM_freeN(render_win->rectspare);
        render_win->rectspare= NULL;