From ec28fe2e6b4e2b6455d64f0467d26f585adc715a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 31 Mar 2016 15:35:47 +1100 Subject: Fix T47985: VSE GL-render scene strip hangs Regression in d5f1b9c22, threading deadlock rendering a scene from the OpenGL preview. --- source/blender/editors/render/render_opengl.c | 52 +++++++++++++++++++-------- 1 file changed, 38 insertions(+), 14 deletions(-) (limited to 'source/blender/editors/render') diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 12fed3fc128..992b827113d 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -88,8 +88,13 @@ typedef struct OGLRender { ScrArea *prevsa; ARegion *prevar; + int views_len; /* multi-view views */ + bool is_sequencer; SpaceSeq *sseq; + struct { + ImBuf **ibufs_arr; + } seq_data; Image *ima; @@ -253,7 +258,6 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr) View3D *v3d = oglrender->v3d; RegionView3D *rv3d = oglrender->rv3d; Object *camera = NULL; - ImBuf *ibuf; int sizex = oglrender->sizex; int sizey = oglrender->sizey; const short view_context = (v3d != NULL); @@ -263,22 +267,11 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr) const char *viewname = RE_GetActiveRenderView(oglrender->re); if (oglrender->is_sequencer) { - SeqRenderData context; SpaceSeq *sseq = oglrender->sseq; - int chanshown = sseq ? sseq->chanshown : 0; struct bGPdata *gpd = (sseq && (sseq->flag & SEQ_SHOW_GPENCIL)) ? sseq->gpd : NULL; - BKE_sequencer_new_render_data( - oglrender->bmain->eval_ctx, oglrender->bmain, scene, - oglrender->sizex, oglrender->sizey, 100.0f, - &context); - - context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname); - context.gpu_offscreen = oglrender->ofs; - context.gpu_fx = oglrender->fx; - context.gpu_full_samples = oglrender->ofs_full_samples; - - ibuf = BKE_sequencer_give_ibuf(&context, CFRA, chanshown); + /* use pre-calculated ImBuf (avoids deadlock), see: */ + ImBuf *ibuf = oglrender->seq_data.ibufs_arr[oglrender->view_id]; if (ibuf) { ImBuf *out = IMB_dupImBuf(ibuf); @@ -429,8 +422,31 @@ static void screen_opengl_render_apply(OGLRender *oglrender) ImBuf *ibuf; void *lock; + if (oglrender->is_sequencer) { + Scene *scene = oglrender->scene; + + SeqRenderData context; + SpaceSeq *sseq = oglrender->sseq; + int chanshown = sseq ? sseq->chanshown : 0; + + BKE_sequencer_new_render_data( + oglrender->bmain->eval_ctx, oglrender->bmain, scene, + oglrender->sizex, oglrender->sizey, 100.0f, + &context); + + for (view_id = 0; view_id < oglrender->views_len; view_id++) { + context.view_id = view_id; + context.gpu_offscreen = oglrender->ofs; + context.gpu_fx = oglrender->fx; + context.gpu_full_samples = oglrender->ofs_full_samples; + + oglrender->seq_data.ibufs_arr[view_id] = BKE_sequencer_give_ibuf(&context, CFRA, chanshown); + } + } + rr = RE_AcquireResultRead(oglrender->re); for (rv = rr->views.first, view_id = 0; rv; rv = rv->next, view_id++) { + BLI_assert(view_id < oglrender->views_len); RE_SetActiveRenderView(oglrender->re, rv->name); oglrender->view_id = view_id; screen_opengl_render_doit(oglrender, rr); @@ -529,9 +545,13 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) oglrender->write_still = is_write_still && !is_animation; + oglrender->views_len = BKE_scene_multiview_num_views_get(&scene->r); + oglrender->is_sequencer = is_sequencer; if (is_sequencer) { oglrender->sseq = CTX_wm_space_seq(C); + ImBuf **ibufs_arr = MEM_callocN(sizeof(*ibufs_arr) * oglrender->views_len, __func__); + oglrender->seq_data.ibufs_arr = ibufs_arr; } oglrender->prevsa = prevsa; @@ -616,6 +636,10 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) GPU_offscreen_free(oglrender->ofs); + if (oglrender->is_sequencer) { + MEM_freeN(oglrender->seq_data.ibufs_arr); + } + oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); -- cgit v1.2.3