diff options
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 191 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_threads.h | 3 | ||||
-rw-r--r-- | source/blender/blenlib/intern/threads.c | 5 | ||||
-rw-r--r-- | source/blender/nodes/intern/CMP_nodes/CMP_composite.c | 4 | ||||
-rw-r--r-- | source/blender/nodes/intern/CMP_nodes/CMP_viewer.c | 6 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 11 |
6 files changed, 106 insertions, 114 deletions
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index ee3d685938b..f870fc1083b 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1932,113 +1932,93 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser) /* always returns a single ibuf, also during render progress */ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_r) { - Render *re= NULL; - RenderResult *rr= NULL; - + Render *re; + RenderResult rres; + float *rectf, *rectz; + unsigned int *rect; + float dither; + int channels, layer, pass; + ImBuf *ibuf; + + if(!(iuser && iuser->scene)) + return NULL; + /* if we the caller is not going to release the lock, don't give the image */ if(!lock_r) return NULL; - if(iuser && iuser->scene) { - re= RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW); - rr= RE_AcquireResultRead(re); + re= RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW); + + channels= 4; + layer= (iuser)? iuser->layer: 0; + pass= (iuser)? iuser->pass: 0; + + /* this gives active layer, composite or seqence result */ + RE_AcquireResultImage(re, &rres); + rect= (unsigned int *)rres.rect32; + rectf= rres.rectf; + rectz= rres.rectz; + dither= iuser->scene->r.dither_intensity; + + /* get compo/seq result by default */ + if(rres.rectf && layer==0); + else if(rres.layers.first) { + RenderLayer *rl= BLI_findlink(&rres.layers, layer-(rres.rectf?1:0)); + if(rl) { + RenderPass *rpass; + + /* there's no combined pass, is in renderlayer itself */ + if(pass==0) { + rectf= rl->rectf; + } + else { + rpass= BLI_findlink(&rl->passes, pass-1); + if(rpass) { + channels= rpass->channels; + rectf= rpass->rect; + dither= 0.0f; /* don't dither passes */ + } + } - /* release is done in BKE_image_release_ibuf using lock_r */ - *lock_r= re; + for(rpass= rl->passes.first; rpass; rpass= rpass->next) + if(rpass->passtype == SCE_PASS_Z) + rectz= rpass->rect; + } } - - if(rr==NULL) - return NULL; - if(RE_RenderInProgress(re)) { - ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0); - - /* make ibuf if needed, and initialize it */ - /* this only gets called when mutex locked */ - if(ibuf==NULL) { - ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, IB_rect, 0); - image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); - } - - return ibuf; + if(!(rectf || rect)) { + RE_ReleaseResultImage(re); + return NULL; } - else { - RenderResult rres; - float *rectf, *rectz; - unsigned int *rect; - float dither; - int channels, layer, pass; - - channels= 4; - layer= (iuser)? iuser->layer: 0; - pass= (iuser)? iuser->pass: 0; - - /* this gives active layer, composite or seqence result */ - RE_AcquireResultImage(RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW), &rres); - rect= (unsigned int *)rres.rect32; - rectf= rres.rectf; - rectz= rres.rectz; - dither= iuser->scene->r.dither_intensity; - - /* get compo/seq result by default */ - if(rr->rectf && layer==0); - else if(rr->layers.first) { - RenderLayer *rl= BLI_findlink(&rr->layers, layer-(rr->rectf?1:0)); - if(rl) { - RenderPass *rpass; - - /* there's no combined pass, is in renderlayer itself */ - if(pass==0) { - rectf= rl->rectf; - } - else { - rpass= BLI_findlink(&rl->passes, pass-1); - if(rpass) { - channels= rpass->channels; - rectf= rpass->rect; - dither= 0.0f; /* don't dither passes */ - } - } - for(rpass= rl->passes.first; rpass; rpass= rpass->next) - if(rpass->passtype == SCE_PASS_Z) - rectz= rpass->rect; - } - } - - if(rectf || rect) { - ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0); + ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0); - /* make ibuf if needed, and initialize it */ - if(ibuf==NULL) { - ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, 0, 0); - image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); - } - ibuf->x= rr->rectx; - ibuf->y= rr->recty; - - if(ibuf->rect_float!=rectf || rect) /* ensure correct redraw */ - imb_freerectImBuf(ibuf); - if(rect) - ibuf->rect= rect; - - ibuf->rect_float= rectf; - ibuf->flags |= IB_rectfloat; - ibuf->channels= channels; - ibuf->zbuf_float= rectz; - ibuf->flags |= IB_zbuffloat; - ibuf->dither= dither; + /* make ibuf if needed, and initialize it */ + if(ibuf==NULL) { + ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, 0, 0); + image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); + } + ibuf->x= rres.rectx; + ibuf->y= rres.recty; + + if(ibuf->rect_float!=rectf || rect) /* ensure correct redraw */ + imb_freerectImBuf(ibuf); + if(rect) + ibuf->rect= rect; + + ibuf->rect_float= rectf; + ibuf->flags |= IB_rectfloat; + ibuf->channels= channels; + ibuf->zbuf_float= rectz; + ibuf->flags |= IB_zbuffloat; + ibuf->dither= dither; - RE_ReleaseResultImage(re); + ima->ok= IMA_OK_LOADED; - ima->ok= IMA_OK_LOADED; - return ibuf; - } + /* release is done in BKE_image_release_ibuf using lock_r */ + *lock_r= re; - RE_ReleaseResultImage(re); - } - - return NULL; + return ibuf; } static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame_r, int *index_r) @@ -2199,10 +2179,17 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) ibuf= image_get_render_result(ima, iuser, lock_r); } else if(ima->type==IMA_TYPE_COMPOSITE) { - /* Composite Viewer, all handled in compositor */ - /* fake ibuf, will be filled in compositor */ - ibuf= IMB_allocImBuf(256, 256, 32, IB_rect, 0); - image_assign_ibuf(ima, ibuf, 0, frame); + /* requires lock/unlock, otherwise don't return image */ + if(lock_r) { + /* unlock in BKE_image_release_ibuf */ + BLI_lock_thread(LOCK_VIEWER); + *lock_r= ima; + + /* Composite Viewer, all handled in compositor */ + /* fake ibuf, will be filled in compositor */ + ibuf= IMB_allocImBuf(256, 256, 32, IB_rect, 0); + image_assign_ibuf(ima, ibuf, 0, frame); + } } } } @@ -2220,9 +2207,11 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) void BKE_image_release_ibuf(Image *ima, void *lock) { - /* for getting image during threaded render, need to release */ - if(lock) - RE_ReleaseResult(lock); + /* for getting image during threaded render / compositing, need to release */ + if(lock == ima) + BLI_unlock_thread(LOCK_VIEWER); /* viewer image */ + else if(lock) + RE_ReleaseResultImage(lock); /* render result */ } ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser) diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h index 25ecea919e7..08e24d677f5 100644 --- a/source/blender/blenlib/BLI_threads.h +++ b/source/blender/blenlib/BLI_threads.h @@ -59,7 +59,8 @@ int BLI_system_thread_count(void); /* gets the number of threads the system can #define LOCK_IMAGE 0 #define LOCK_PREVIEW 1 -#define LOCK_CUSTOM1 2 +#define LOCK_VIEWER 2 +#define LOCK_CUSTOM1 3 void BLI_lock_thread(int type); void BLI_unlock_thread(int type); diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index 02d6ab0b7b5..be016456fc4 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -109,6 +109,7 @@ A sample loop can look like this (pseudo c); static pthread_mutex_t _malloc_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _image_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _preview_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t _viewer_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER; static int thread_levels= 0; /* threads can be invoked inside threads */ @@ -327,6 +328,8 @@ void BLI_lock_thread(int type) pthread_mutex_lock(&_image_lock); else if (type==LOCK_PREVIEW) pthread_mutex_lock(&_preview_lock); + else if (type==LOCK_VIEWER) + pthread_mutex_lock(&_viewer_lock); else if (type==LOCK_CUSTOM1) pthread_mutex_lock(&_custom1_lock); } @@ -337,6 +340,8 @@ void BLI_unlock_thread(int type) pthread_mutex_unlock(&_image_lock); else if (type==LOCK_PREVIEW) pthread_mutex_unlock(&_preview_lock); + else if (type==LOCK_VIEWER) + pthread_mutex_unlock(&_viewer_lock); else if(type==LOCK_CUSTOM1) pthread_mutex_unlock(&_custom1_lock); } diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c index 76a78e46e3a..9a302527a61 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c @@ -80,10 +80,10 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i outbuf->malloc= 0; free_compbuf(outbuf); - RE_ReleaseResult(re); - /* signal for imageviewer to refresh (it converts to byte rects...) */ BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE); + + RE_ReleaseResult(re); return; } else diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_viewer.c b/source/blender/nodes/intern/CMP_nodes/CMP_viewer.c index e62a7462702..80200ad9ce6 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_viewer.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_viewer.c @@ -50,13 +50,15 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, ImBuf *ibuf; CompBuf *cbuf, *tbuf; int rectx, recty; + void *lock; BKE_image_user_calc_frame(node->storage, rd->cfra, 0); /* always returns for viewer image, but we check nevertheless */ - ibuf= BKE_image_get_ibuf(ima, node->storage); + ibuf= BKE_image_acquire_ibuf(ima, node->storage, &lock); if(ibuf==NULL) { printf("node_composit_exec_viewer error\n"); + BKE_image_release_ibuf(ima, lock); return; } @@ -106,6 +108,8 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, free_compbuf(zbuf); } + BKE_image_release_ibuf(ima, lock); + generate_preview(data, node, cbuf); free_compbuf(cbuf); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index ec250a7136b..b995e686c58 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -138,11 +138,6 @@ static void int_nothing(void *unused, int val) {} static void print_error(void *unused, char *str) {printf("ERROR: %s\n", str);} static int default_break(void *unused) {return G.afbreek == 1;} -int RE_RenderInProgress(Render *re) -{ - return re->result_ok==0; -} - static void stats_background(void *unused, RenderStats *rs) { uintptr_t mem_in_use= MEM_get_memory_in_use(); @@ -1091,6 +1086,8 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr) if(rr->rectz==NULL) rr->rectz= RE_RenderLayerGetPass(rl, SCE_PASS_Z); } + + rr->layers= re->result->layers; } } } @@ -2801,7 +2798,6 @@ void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, unsigned i { /* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */ RenderGlobal.renderingslot= re->slot; - re->result_ok= 0; G.rendering= 1; scene->r.cfra= frame; @@ -2811,7 +2807,6 @@ void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, unsigned i } /* UGLY WARNING */ - re->result_ok= 1; G.rendering= 0; RenderGlobal.renderingslot= RenderGlobal.viewslot; } @@ -2917,7 +2912,6 @@ void RE_BlenderAnim(Render *re, Scene *scene, unsigned int lay, int sfra, int ef /* is also set by caller renderwin.c */ G.rendering= 1; RenderGlobal.renderingslot= re->slot; - re->result_ok= 0; if(BKE_imtype_is_movie(scene->r.imtype)) if(!mh->start_movie(scene, &re->r, re->rectx, re->recty, reports)) @@ -3014,7 +3008,6 @@ void RE_BlenderAnim(Render *re, Scene *scene, unsigned int lay, int sfra, int ef /* UGLY WARNING */ G.rendering= 0; - re->result_ok= 1; RenderGlobal.renderingslot= RenderGlobal.viewslot; } |