diff options
19 files changed, 208 insertions, 87 deletions
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index b35cf917895..7d89d94c6d5 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -321,9 +321,9 @@ static Render *fastshade_get_render(Scene *scene) /* XXX ugly global still, but we can't do preview while rendering */ if(G.rendering==0) { - Render *re= RE_GetRender("_Shade View_"); + Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT); if(re==NULL) { - re= RE_NewRender("_Shade View_"); + re= RE_NewRender("_Shade View_", RE_SLOT_DEFAULT); RE_Database_Baking(re, scene, 0, 0); /* 0= no faces */ } @@ -337,7 +337,7 @@ static Render *fastshade_get_render(Scene *scene) /* called on file reading */ void fastshade_free_render(void) { - Render *re= RE_GetRender("_Shade View_"); + Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT); if(re) { RE_Database_Free(re); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 09b86234d33..41a05a989e6 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1088,7 +1088,7 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix) } { - Render *re= RE_GetRender(scene->id.name); + Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING); RenderStats *stats= re ? RE_GetStats(re):NULL; if (stats && (scene->r.stamp & R_STAMP_RENDERTIME)) { @@ -1599,7 +1599,7 @@ RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, Image *ima) if(ima->rr) return ima->rr; else if(ima->type==IMA_TYPE_R_RESULT) - return RE_AcquireResultRead(RE_GetRender(scene->id.name)); + return RE_AcquireResultRead(RE_GetRender(scene->id.name, RE_SLOT_VIEW)); return NULL; } @@ -1607,7 +1607,7 @@ void BKE_image_release_renderresult(struct Scene *scene, Image *ima) { if(ima->rr); else if(ima->type==IMA_TYPE_R_RESULT) - RE_ReleaseResult(RE_GetRender(scene->id.name)); + RE_ReleaseResult(RE_GetRender(scene->id.name, RE_SLOT_VIEW)); } /* after imbuf load, openexr type can return with a exrhandle open */ @@ -1919,7 +1919,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ return NULL; if(iuser && iuser->scene) { - re= RE_GetRender(iuser->scene->id.name); + re= RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW); rr= RE_AcquireResultRead(re); /* release is done in BKE_image_release_ibuf using lock_r */ @@ -1953,7 +1953,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ pass= (iuser)? iuser->pass: 0; /* this gives active layer, composite or seqence result */ - RE_AcquireResultImage(RE_GetRender(iuser->scene->id.name), &rres); + RE_AcquireResultImage(RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW), &rres); rect= (unsigned int *)rres.rect32; rectf= rres.rectf; rectz= rres.rectz; diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 8c119eb753b..c5865db5e26 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2049,7 +2049,6 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int Scene *sce= seq->scene;// *oldsce= scene; Render *re; RenderResult rres; - char scenename[64]; int have_seq= FALSE; int sce_valid= FALSE; @@ -2093,11 +2092,10 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int oldcfra = seq->scene->r.cfra; - if(rendering) { - BLI_strncpy(scenename, sce->id.name+2, 64); - strcpy(sce->id.name+2, " do_build_seq_ibuf"); - } - re= RE_NewRender(sce->id.name); + if(rendering) + re= RE_NewRender(" do_build_seq_ibuf", RE_SLOT_DEFAULT); + else + re= RE_NewRender(sce->id.name, RE_SLOT_VIEW); /* prevent eternal loop */ doseq= scene->r.scemode & R_DOSEQ; @@ -2106,9 +2104,6 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int RE_BlenderFrame(re, sce, NULL, seq->sfra+se->nr+seq->anim_startofs); - if(rendering) - BLI_strncpy(sce->id.name+2, scenename, 64); - RE_AcquireResultImage(re, &rres); if(rres.rectf) { diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 7aa9d557118..39eda367d85 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -141,7 +141,7 @@ static void init_bake_internal(BakeRender *bkr, bContext *C) bkr->sa= biggest_image_area(CTX_wm_screen(C)); /* can be NULL */ bkr->scene= scene; bkr->actob= (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL; - bkr->re= RE_NewRender("_Bake View_"); + bkr->re= RE_NewRender("_Bake View_", RE_SLOT_DEFAULT); if(scene->r.bake_mode==RE_BAKE_AO) { /* If raytracing or AO is disabled, switch it on temporarily for baking. */ diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 1f1a0ff859d..8aa57ca3fbb 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -474,7 +474,7 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int } } - re= RE_GetRender(name); + re= RE_GetRender(name, RE_SLOT_DEFAULT); RE_AcquireResultImage(re, &rres); if(rres.rectf) { @@ -702,7 +702,7 @@ void BIF_view3d_previewrender(Scene *scene, ScrArea *sa) ri->status= 0; sprintf(name, "View3dPreview %p", sa); - re= ri->re= RE_NewRender(name); + re= ri->re= RE_NewRender(name, RE_SLOT_DEFAULT); //RE_display_draw_cb(re, view3d_previewrender_progress); //RE_stats_draw_cb(re, view3d_previewrender_stats); //RE_test_break_cb(re, qtest); @@ -890,11 +890,11 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs if(!split || first) sprintf(name, "Preview %p", sp->owner); else sprintf(name, "SecondPreview %p", sp->owner); - re= RE_GetRender(name); + re= RE_GetRender(name, RE_SLOT_DEFAULT); /* full refreshed render from first tile */ if(re==NULL) - re= RE_NewRender(name); + re= RE_NewRender(name, RE_SLOT_DEFAULT); /* sce->r gets copied in RE_InitState! */ sce->r.scemode &= ~(R_MATNODE_PREVIEW|R_TEXNODE_PREVIEW); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 53cd34c46f5..2957e77a89e 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2885,10 +2885,10 @@ static void screen_set_image_output(bContext *C, int mx, int my) static int screen_render_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Render *re= RE_GetRender(scene->id.name); + Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); if(re==NULL) { - re= RE_NewRender(scene->id.name); + re= RE_NewRender(scene->id.name, RE_SLOT_VIEW); } RE_test_break_cb(re, NULL, (int (*)(void *)) blender_test_break); @@ -3236,7 +3236,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) rj->image= ima; /* setup new render */ - re= RE_NewRender(scene->id.name); + re= RE_NewRender(scene->id.name, RE_SLOT_VIEW); RE_test_break_cb(re, rj, render_breakjob); RE_display_draw_cb(re, rj, image_rect_update); RE_stats_draw_cb(re, rj, image_renderinfo_cb); @@ -3398,7 +3398,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) oglrender->iuser.ok= 1; /* create render and render result */ - oglrender->re= RE_NewRender(scene->id.name); + oglrender->re= RE_NewRender(scene->id.name, RE_SLOT_VIEW); RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL); rr= RE_AcquireResultWrite(oglrender->re); diff --git a/source/blender/editors/space_file/writeimage.c b/source/blender/editors/space_file/writeimage.c index 5f0b75d068a..14a8a79a1fa 100644 --- a/source/blender/editors/space_file/writeimage.c +++ b/source/blender/editors/space_file/writeimage.c @@ -114,14 +114,14 @@ static void save_rendered_image_cb_real(char *name, int confirm) if(overwrite) { if(scene->r.imtype==R_MULTILAYER) { - Render *re= RE_GetRender(scene->id.name); + Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); RenderResult *rr= RE_AcquireResultRead(re); if(rr) RE_WriteRenderResult(rr, str, scene->r.quality); RE_ReleaseResult(re); } else { - Render *re= RE_GetRender(scene->id.name); + Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); RenderResult rres; ImBuf *ibuf; @@ -235,7 +235,7 @@ void BIF_save_rendered_image(char *name) /* calls fileselect */ void BIF_save_rendered_image_fs(Scene *scene) { - Render *re= RE_GetRender(scene->id.name); + Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); RenderResult rres; RE_AcquireResultImage(re, &rres); diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 94df99d9c8d..2eb371357f1 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -533,6 +533,22 @@ static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PREVI /* ********************* callbacks for standard image buttons *************** */ +static char *slot_menu() +{ + char *str; + int a, slot; + + str= MEM_callocN(RE_SLOT_MAX*32, "menu slots"); + + strcpy(str, "Slot %t"); + a= strlen(str); + + for(slot=0; slot<RE_SLOT_MAX; slot++) + a += sprintf(str+a, "|Slot %d %%x%d", slot+1, slot); + + return str; +} + static char *layer_menu(RenderResult *rr, short *curlay) { RenderLayer *rl; @@ -599,7 +615,10 @@ static void set_frames_cb(bContext *C, void *ima_v, void *iuser_v) /* 5 layer button callbacks... */ static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v) { - BKE_image_multilayer_index(rr_v, iuser_v); + ImageUser *iuser= iuser_v; + + RE_SetViewSlot(iuser->menunr); + BKE_image_multilayer_index(rr_v, iuser); WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); } static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v) @@ -699,34 +718,45 @@ static void image_user_change(bContext *C, void *iuser_v, void *unused) } #endif -static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w) +static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w, int render) { uiBlock *block= uiLayoutGetBlock(layout); uiBut *but; RenderLayer *rl= NULL; - int wmenu1, wmenu2; + int wmenu1, wmenu2, wmenu3; char *strp; uiLayoutRow(layout, 1); /* layer menu is 1/3 larger than pass */ - wmenu1= (3*w)/5; - wmenu2= (2*w)/5; + wmenu1= (2*w)/5; + wmenu2= (3*w)/5; + wmenu3= (3*w)/6; /* menu buts */ - strp= layer_menu(rr, &iuser->layer); - but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, 20, &iuser->layer, 0,0,0,0, "Select Layer"); - uiButSetFunc(but, image_multi_cb, rr, iuser); - MEM_freeN(strp); - - rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */ - strp= pass_menu(rl, &iuser->pass); - but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu2, 20, &iuser->pass, 0,0,0,0, "Select Pass"); - uiButSetFunc(but, image_multi_cb, rr, iuser); - MEM_freeN(strp); + if(render) { + strp= slot_menu(); + iuser->menunr= RE_GetViewSlot(); + but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, 20, &iuser->menunr, 0,0,0,0, "Select Slot"); + uiButSetFunc(but, image_multi_cb, rr, iuser); + MEM_freeN(strp); + } + + if(rr) { + strp= layer_menu(rr, &iuser->layer); + but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu2, 20, &iuser->layer, 0,0,0,0, "Select Layer"); + uiButSetFunc(but, image_multi_cb, rr, iuser); + MEM_freeN(strp); + + rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */ + strp= pass_menu(rl, &iuser->pass); + but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu3, 20, &iuser->pass, 0,0,0,0, "Select Pass"); + uiButSetFunc(but, image_multi_cb, rr, iuser); + MEM_freeN(strp); + } } -static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser) +static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int render) { uiBlock *block= uiLayoutGetBlock(layout); uiLayout *row; @@ -747,7 +777,7 @@ static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, but= uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0,0,18,20, NULL, 0, 0, 0, 0, "Next Layer"); uiButSetFunc(but, image_multi_inclay_cb, rr, iuser); - uiblock_layer_pass_buttons(row, rr, iuser, 230); + uiblock_layer_pass_buttons(row, rr, iuser, 230, render); /* decrease, increase arrows */ but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0,0,17,20, NULL, 0, 0, 0, 0, "Previous Pass"); @@ -856,9 +886,9 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn } else if(ima->type==IMA_TYPE_R_RESULT) { /* browse layer/passes */ - Render *re= RE_GetRender(scene->id.name); + Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); RenderResult *rr= RE_AcquireResultRead(re); - uiblock_layer_pass_arrow_buttons(layout, rr, iuser); + uiblock_layer_pass_arrow_buttons(layout, rr, iuser, 1); RE_ReleaseResult(re); } } @@ -885,7 +915,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn /* multilayer? */ if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) { - uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser); + uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser, 0); } else if(ima->source != IMA_SRC_GENERATED) { if(compact == 0) { @@ -965,10 +995,7 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser /* render layers and passes */ if(ima && iuser) { rr= BKE_image_acquire_renderresult(scene, ima); - - if(rr) - uiblock_layer_pass_buttons(layout, rr, iuser, 160); - + uiblock_layer_pass_buttons(layout, rr, iuser, 160, ima->type==IMA_TYPE_R_RESULT); BKE_image_release_renderresult(scene, ima); } } diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index b7f81245296..80fcbe5f240 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -77,6 +77,8 @@ void IMAGE_OT_save_sequence(struct wmOperatorType *ot); void IMAGE_OT_pack(struct wmOperatorType *ot); void IMAGE_OT_unpack(struct wmOperatorType *ot); +void IMAGE_OT_cycle_render_slot(struct wmOperatorType *ot); + void IMAGE_OT_sample(struct wmOperatorType *ot); void IMAGE_OT_curves_point_set(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 2011649fda6..a1557e424da 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1791,6 +1791,51 @@ void IMAGE_OT_record_composite(wmOperatorType *ot) ot->poll= space_image_poll; } +/********************* cycle render slot operator *********************/ + +static int cycle_render_slot_poll(bContext *C) +{ + Image *ima= CTX_data_edit_image(C); + + return (ima && ima->type == IMA_TYPE_R_RESULT); +} + +static int cycle_render_slot_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + int a, slot, cur= RE_GetViewSlot(); + + for(a=1; a<RE_SLOT_MAX; a++) { + slot= (cur+a)%RE_SLOT_MAX; + + if(RE_GetRender(scene->id.name, slot)) { + RE_SetViewSlot(slot); + break; + } + } + + if(a == RE_SLOT_MAX) + RE_SetViewSlot((cur == 1)? 0: 1); + + WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL); + + return OPERATOR_FINISHED; +} + +void IMAGE_OT_cycle_render_slot(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Cycle Render Slot"; + ot->idname= "IMAGE_OT_cycle_render_slot"; + + /* api callbacks */ + ot->exec= cycle_render_slot_exec; + ot->poll= cycle_render_slot_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + /******************** TODO ********************/ /* XXX notifier? */ @@ -1843,3 +1888,4 @@ void BIF_image_update_frame(void) } #endif + diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index a653838c073..c8c110b3d02 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -472,6 +472,8 @@ void image_operatortypes(void) WM_operatortype_append(IMAGE_OT_pack); WM_operatortype_append(IMAGE_OT_unpack); + WM_operatortype_append(IMAGE_OT_cycle_render_slot); + WM_operatortype_append(IMAGE_OT_sample); WM_operatortype_append(IMAGE_OT_curves_point_set); @@ -493,6 +495,8 @@ void image_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "IMAGE_OT_save_as", F3KEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "IMAGE_OT_scopes", PKEY, KM_PRESS, 0, 0); + + WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, 0, 0); keymap= WM_keymap_find(keyconf, "Image", SPACE_IMAGE, 0); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 89fb40367e8..e03e6e023dd 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1661,7 +1661,7 @@ void node_read_renderlayers(SpaceNode *snode) void node_read_fullsamplelayers(SpaceNode *snode) { Scene *curscene= NULL; // XXX - Render *re= RE_NewRender(curscene->id.name); + Render *re= RE_NewRender(curscene->id.name, RE_SLOT_VIEW); WM_cursor_wait(1); diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c index d117a3cb235..079d2ebeac1 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c @@ -50,7 +50,7 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i RenderData *rd= data; if(scene && (rd->scemode & R_DOCOMP)) { - Render *re= RE_GetRender(scene->id.name); + Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING); RenderResult *rr= RE_AcquireResultWrite(re); if(rr) { CompBuf *outbuf, *zbuf=NULL; diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c index f209687d6a5..09f826ebff7 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c @@ -346,7 +346,7 @@ void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { Scene *sce= (Scene *)node->id; - Render *re= (sce)? RE_GetRender(sce->id.name): NULL; + Render *re= (sce)? RE_GetRender(sce->id.name, RE_SLOT_RENDERING): NULL; RenderData *rd= data; RenderResult *rr= NULL; diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index a90220b9c1b..4084958488c 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -146,8 +146,21 @@ typedef struct RenderStats { /* the name is used as identifier, so elsewhere in blender the result can retrieved */ /* calling a new render with same name, frees automatic existing render */ -struct Render *RE_NewRender (const char *name); -struct Render *RE_GetRender(const char *name); +struct Render *RE_NewRender (const char *name, int slot); +struct Render *RE_GetRender(const char *name, int slot); + +/* render slots. for most cases like baking or preview render this will + always be default, for actual render multiple slots can be used. in + that case 'rendering' is the slot being rendered to, and 'view' is the + slot being viewed. these are always the same except if the currently + viewed slot is changed during render, at the end they will be synced. */ +#define RE_SLOT_RENDERING -2 +#define RE_SLOT_VIEW -1 +#define RE_SLOT_DEFAULT 0 +#define RE_SLOT_MAX 10 + +void RE_SetViewSlot(int slot); +int RE_GetViewSlot(void); /* returns 1 while render is working (or renders called from within render) */ int RE_RenderInProgress(struct Render *re); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index de7d176759e..c4465781940 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -113,6 +113,7 @@ struct Render { struct Render *next, *prev; char name[RE_MAXNAME]; + int slot; /* state settings */ short flag, osa, ok, result_ok; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index d05d88266c7..a24fa47ec3e 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -5605,7 +5605,7 @@ void RE_make_sticky(Scene *scene, View3D *v3d) return; } - re= RE_NewRender("_make sticky_"); + re= RE_NewRender("_make sticky_", RE_SLOT_DEFAULT); RE_InitState(re, NULL, &scene->r, NULL, scene->r.xsch, scene->r.ysch, NULL); /* use renderdata and camera to set viewplane */ diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 7ba860955b3..0ab0b1c4141 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -108,7 +108,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) Render *envre; int cuberes; - envre= RE_NewRender("Envmap"); + envre= RE_NewRender("Envmap", RE_SLOT_DEFAULT); env->lastsize= re->r.size; cuberes = (env->cuberes * re->r.size) / 100; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index f679b35c627..c5d4392a53c 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -108,14 +108,19 @@ /* ********* globals ******** */ /* here we store all renders */ -static struct ListBase RenderList= {NULL, NULL}; +static struct { + ListBase renderlist; + + /* render slots */ + int viewslot, renderingslot; + + /* commandline thread override */ + int threads; +} RenderGlobal = {{NULL, NULL}, 0, 0, -1}; /* hardcopy of current render, used while rendering for speed */ Render R; -/* commandline thread override */ -static int commandline_threads= -1; - /* ********* alloc and free ******** */ @@ -228,11 +233,11 @@ static void push_render_result(Render *re) /* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */ static void pop_render_result(Render *re) { - if(re->result==NULL) { printf("pop render result error; no current result!\n"); return; } + if(re->pushedresult) { BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); @@ -989,13 +994,35 @@ static void read_render_result(Render *re, int sample) /* *************************************************** */ -Render *RE_GetRender(const char *name) +void RE_SetViewSlot(int slot) +{ + RenderGlobal.viewslot = slot; +} + +int RE_GetViewSlot(void) +{ + return RenderGlobal.viewslot; +} + +static int re_get_slot(int slot) +{ + if(slot == RE_SLOT_VIEW) + return RenderGlobal.viewslot; + else if(slot == RE_SLOT_RENDERING) + return (G.rendering)? RenderGlobal.renderingslot: RenderGlobal.viewslot; + + return slot; +} + +Render *RE_GetRender(const char *name, int slot) { Render *re; + + slot= re_get_slot(slot); /* search for existing renders */ - for(re= RenderList.first; re; re= re->next) { - if(strncmp(re->name, name, RE_MAXNAME)==0) { + for(re= RenderGlobal.renderlist.first; re; re= re->next) { + if(strncmp(re->name, name, RE_MAXNAME)==0 && re->slot==slot) { break; } } @@ -1126,24 +1153,26 @@ void RE_ResultGet32(Render *re, unsigned int *rect) RE_ReleaseResultImage(re); } - RenderStats *RE_GetStats(Render *re) { return &re->i; } -Render *RE_NewRender(const char *name) +Render *RE_NewRender(const char *name, int slot) { Render *re; + + slot= re_get_slot(slot); /* only one render per name exists */ - re= RE_GetRender(name); + re= RE_GetRender(name, slot); if(re==NULL) { /* new render data struct */ re= MEM_callocN(sizeof(Render), "new render"); - BLI_addtail(&RenderList, re); + BLI_addtail(&RenderGlobal.renderlist, re); strncpy(re->name, name, RE_MAXNAME); + re->slot= slot; BLI_rw_mutex_init(&re->resultmutex); } @@ -1178,15 +1207,15 @@ void RE_FreeRender(Render *re) RE_FreeRenderResult(re->result); RE_FreeRenderResult(re->pushedresult); - BLI_remlink(&RenderList, re); + BLI_remlink(&RenderGlobal.renderlist, re); MEM_freeN(re); } /* exit blender */ void RE_FreeAllRender(void) { - while(RenderList.first) { - RE_FreeRender(RenderList.first); + while(RenderGlobal.renderlist.first) { + RE_FreeRender(RenderGlobal.renderlist.first); } } @@ -2186,7 +2215,7 @@ static void do_render_fields_blur_3d(Render *re) */ static void render_scene(Render *re, Scene *sce, int cfra) { - Render *resc= RE_NewRender(sce->id.name); + Render *resc= RE_NewRender(sce->id.name, RE_SLOT_RENDERING); int winx= re->winx, winy= re->winy; sce->r.cfra= cfra; @@ -2313,7 +2342,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) Render *re1; tag_scenes_for_render(re); - for(re1= RenderList.first; re1; re1= re1->next) { + for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) { if(re1->scene->id.flag & LIB_DOIT) if(re1->r.scemode & R_FULL_SAMPLE) read_render_result(re1, sample); @@ -2475,7 +2504,7 @@ static void do_render_composite_fields_blur_3d(Render *re) static void renderresult_stampinfo(Scene *scene) { RenderResult rres; - Render *re= RE_GetRender(scene->id.name); + Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING); /* this is the basic trick to get the displayed float or char rect from render result */ RE_AcquireResultImage(re, &rres); @@ -2784,8 +2813,9 @@ static int render_initialize_from_scene(Render *re, Scene *scene, SceneRenderLay void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, int frame) { /* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */ - G.rendering= 1; + RenderGlobal.renderingslot= re->slot; re->result_ok= 0; + G.rendering= 1; scene->r.cfra= frame; @@ -2794,8 +2824,9 @@ void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, int frame) } /* UGLY WARNING */ - G.rendering= 0; re->result_ok= 1; + G.rendering= 0; + RenderGlobal.renderingslot= RenderGlobal.viewslot; } static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, ReportList *reports) @@ -2899,6 +2930,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, Repo /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ /* 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)) @@ -2995,6 +3027,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, Repo /* UGLY WARNING */ G.rendering= 0; re->result_ok= 1; + RenderGlobal.renderingslot= RenderGlobal.viewslot; } /* note; repeated win/disprect calc... solve that nicer, also in compo */ @@ -3028,9 +3061,9 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode) scene= scenode; /* get render: it can be called from UI with draw callbacks */ - re= RE_GetRender(scene->id.name); + re= RE_GetRender(scene->id.name, RE_SLOT_VIEW); if(re==NULL) - re= RE_NewRender(scene->id.name); + re= RE_NewRender(scene->id.name, RE_SLOT_VIEW); RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect); re->scene= scene; @@ -3040,9 +3073,9 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode) void RE_set_max_threads(int threads) { if (threads==0) { - commandline_threads = BLI_system_thread_count(); + RenderGlobal.threads = BLI_system_thread_count(); } else if(threads>=1 && threads<=BLENDER_MAX_THREADS) { - commandline_threads= threads; + RenderGlobal.threads= threads; } else { printf("Error, threads has to be in range 0-%d\n", BLENDER_MAX_THREADS); } @@ -3050,9 +3083,9 @@ void RE_set_max_threads(int threads) void RE_init_threadcount(Render *re) { - if(commandline_threads >= 1) { /* only set as an arg in background mode */ - re->r.threads= MIN2(commandline_threads, BLENDER_MAX_THREADS); - } else if ((re->r.mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */ + if(RenderGlobal.threads >= 1) { /* only set as an arg in background mode */ + re->r.threads= MIN2(RenderGlobal.threads, BLENDER_MAX_THREADS); + } else if ((re->r.mode & R_FIXED_THREADS)==0 || RenderGlobal.threads == 0) { /* Automatic threads */ re->r.threads = BLI_system_thread_count(); } } |