From 34a5739a8a9e579b8e07eb06c0fad9f449d433e6 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 13 Mar 2006 11:01:17 +0000 Subject: [PATCH] Two fixes in renderpipe... - 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...) --- .../blenkernel/intern/node_composite.c | 4 +-- source/blender/blenlib/BLI_threads.h | 8 ++++-- source/blender/blenlib/intern/threads.c | 15 ++++++++--- source/blender/render/intern/source/envmap.c | 4 +-- .../render/intern/source/imagetexture.c | 12 ++++----- source/blender/render/intern/source/zbuf.c | 8 +++++- source/blender/src/renderwin.c | 25 ++++++++++++------- 7 files changed, 50 insertions(+), 26 deletions(-) diff --git a/source/blender/blenkernel/intern/node_composite.c b/source/blender/blenkernel/intern/node_composite.c index 1eebe1c2510..c09d8a6c664 100644 --- a/source/blender/blenkernel/intern/node_composite.c +++ b/source/blender/blenkernel/intern/node_composite.c @@ -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; diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h index 00ea4f7aaab..43792ccb1bc 100644 --- a/source/blender/blenlib/BLI_threads.h +++ b/source/blender/blenlib/BLI_threads.h @@ -31,6 +31,10 @@ #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); diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index ba1539bb0fa..f94d959d46a 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -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); } diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index b173be4bc9b..8112ece8c09 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -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); } } diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 4552aba421a..38d47d3d7cb 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -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); } } diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 4d6f0610ff5..bf46158ba8c 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -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; vho[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) diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c index e115857e893..0816618d7ca 100644 --- a/source/blender/src/renderwin.c +++ b/source/blender/src/renderwin.c @@ -56,6 +56,7 @@ #include #include "BLI_blenlib.h" +#include "BLI_threads.h" #include "MEM_guardedalloc.h" @@ -124,6 +125,9 @@ /* 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; yrender_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;