Second attempt at committing the different render slot implementation. This
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 27 Mar 2010 15:35:34 +0000 (15:35 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 27 Mar 2010 15:35:34 +0000 (15:35 +0000)
has a fix that hopefully solves the problem on mac/win. Also fixes #21322,
render slots not working well with FSA.

23 files changed:
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/object/object_bake.c
source/blender/editors/render/render_internal.c
source/blender/editors/render/render_opengl.c
source/blender/editors/render/render_preview.c
source/blender/editors/space_file/writeimage.c
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_node/node_edit.c
source/blender/makesdna/DNA_image_types.h
source/blender/nodes/intern/CMP_nodes/CMP_composite.c
source/blender/nodes/intern/CMP_nodes/CMP_image.c
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/pipeline.c
source/creator/creator.c

index df51d01..915f59b 100644 (file)
@@ -141,6 +141,9 @@ struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct Im
 /* for multilayer images as well as for render-viewer */
 struct RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, struct Image *ima);
 void BKE_image_release_renderresult(struct Scene *scene, struct Image *ima);
+
+/* for multiple slot render, call this before render */
+void BKE_image_backup_render(struct Scene *scene, struct Image *ima);
        
 /* goes over all textures that use images */
 void   BKE_image_free_all_textures(void);
index 3e28dcc..487ecb8 100644 (file)
@@ -295,9 +295,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_", RE_SLOT_DEFAULT);
+               Render *re= RE_GetRender("_Shade View_");
                if(re==NULL) {
-                       re= RE_NewRender("_Shade View_", RE_SLOT_DEFAULT);
+                       re= RE_NewRender("_Shade View_");
                
                        RE_Database_Baking(re, scene, 0, 0);    /* 0= no faces */
                }
@@ -311,7 +311,7 @@ static Render *fastshade_get_render(Scene *scene)
 /* called on file reading */
 void fastshade_free_render(void)
 {
-       Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT);
+       Render *re= RE_GetRender("_Shade View_");
        
        if(re) {
                RE_Database_Free(re);
index 1a3c53e..f9352f1 100644 (file)
@@ -229,7 +229,7 @@ static void image_free_buffers(Image *ima)
        
        if(ima->anim) IMB_free_anim(ima->anim);
        ima->anim= NULL;
-       
+
        if(ima->rr) {
                RE_FreeRenderResult(ima->rr);
                ima->rr= NULL;
@@ -243,6 +243,8 @@ static void image_free_buffers(Image *ima)
 /* called by library too, do not free ima itself */
 void free_image(Image *ima)
 {
+       int a;
+
        image_free_buffers(ima);
        if (ima->packedfile) {
                freePackedFile(ima->packedfile);
@@ -253,9 +255,11 @@ void free_image(Image *ima)
        if (ima->preview) {
                BKE_previewimg_free(&ima->preview);
        }
-       if (ima->render_text) {
-               MEM_freeN(ima->render_text);
-               ima->render_text= NULL;
+       for(a=0; a<IMA_MAX_RENDER_SLOT; a++) {
+               if(ima->renders[a]) {
+                       RE_FreeRenderResult(ima->renders[a]);
+                       ima->renders[a]= NULL;
+               }
        }
 }
 
@@ -1005,7 +1009,7 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
        }
 
        {
-               Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING);
+               Render *re= RE_GetRender(scene->id.name);
                RenderStats *stats= re ? RE_GetStats(re):NULL;
 
                if (stats && (scene->r.stamp & R_STAMP_RENDERTIME)) {
@@ -1511,20 +1515,48 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
        return rpass;
 }
 
-RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, Image *ima)
+RenderResult *BKE_image_acquire_renderresult(Scene *scene, Image *ima)
 {
-       if(ima->rr)
+       if(ima->rr) {
                return ima->rr;
-       else if(ima->type==IMA_TYPE_R_RESULT)
-               return RE_AcquireResultRead(RE_GetRender(scene->id.name, RE_SLOT_VIEW));
-       return NULL;
+       }
+       else if(ima->type==IMA_TYPE_R_RESULT) {
+               if(ima->render_slot == ima->last_render_slot)
+                       return RE_AcquireResultRead(RE_GetRender(scene->id.name));
+               else
+                       return ima->renders[ima->render_slot];
+       }
+       else
+               return NULL;
 }
 
-void BKE_image_release_renderresult(struct Scene *scene, Image *ima)
+void BKE_image_release_renderresult(Scene *scene, Image *ima)
 {
        if(ima->rr);
-       else if(ima->type==IMA_TYPE_R_RESULT)
-               RE_ReleaseResult(RE_GetRender(scene->id.name, RE_SLOT_VIEW));
+       else if(ima->type==IMA_TYPE_R_RESULT) {
+               if(ima->render_slot == ima->last_render_slot)
+                       RE_ReleaseResult(RE_GetRender(scene->id.name));
+       }
+}
+
+void BKE_image_backup_render(Scene *scene, Image *ima)
+{
+       /* called right before rendering, ima->renders contains render
+          result pointers for everything but the current render */
+       Render *re= RE_GetRender(scene->id.name);
+       int slot= ima->render_slot, last= ima->last_render_slot;
+
+       if(slot != last) {
+               if(ima->renders[slot]) {
+                       RE_FreeRenderResult(ima->renders[slot]);
+                       ima->renders[slot]= NULL;
+               }
+
+               ima->renders[last]= NULL;
+               RE_SwapResult(re, &ima->renders[last]);
+       }
+
+       ima->last_render_slot= slot;
 }
 
 /* after imbuf load, openexr type can return with a exrhandle open */
@@ -1839,6 +1871,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
        float dither;
        int channels, layer, pass;
        ImBuf *ibuf;
+       int from_render= (ima->render_slot == ima->last_render_slot);
 
        if(!(iuser && iuser->scene))
                return NULL;
@@ -1847,14 +1880,29 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
        if(!lock_r)
                return NULL;
 
-       re= RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW);
+       re= RE_GetRender(iuser->scene->id.name);
 
        channels= 4;
        layer= (iuser)? iuser->layer: 0;
        pass= (iuser)? iuser->pass: 0;
+
+       if(from_render)
+               RE_AcquireResultImage(re, &rres);
+       else if(ima->renders[ima->render_slot])
+               rres= *(ima->renders[ima->render_slot]);
+       else
+               memset(&rres, 0, sizeof(RenderResult));
        
+       if(!(rres.rectx > 0 && rres.recty > 0)) {
+               RE_ReleaseResultImage(re);
+               return NULL;
+       }
+
+       /* release is done in BKE_image_release_ibuf using lock_r */
+       if(from_render)
+               *lock_r= re;
+
        /* this gives active layer, composite or seqence result */
-       RE_AcquireResultImage(re, &rres);
        rect= (unsigned int *)rres.rect32;
        rectf= rres.rectf;
        rectz= rres.rectz;
@@ -1885,11 +1933,6 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
                                        rectz= rpass->rect;
                }
        }
-       
-       if(!(rectf || rect)) {
-               RE_ReleaseResultImage(re);
-               return NULL;
-       }
 
        ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
 
@@ -1898,6 +1941,10 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
                ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, 0, 0);
                image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
        }
+
+       if(!(rectf || rect))
+               return ibuf;
+
        ibuf->x= rres.rectx;
        ibuf->y= rres.recty;
        
@@ -1915,9 +1962,6 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
 
        ima->ok= IMA_OK_LOADED;
 
-       /* release is done in BKE_image_release_ibuf using lock_r */
-       *lock_r= re;
-
        return ibuf;
 }
 
index 17f6bd1..913ec3d 100644 (file)
@@ -2175,9 +2175,9 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
                                RenderResult rres;
 
                                if(rendering)
-                                       re= RE_NewRender(" do_build_seq_ibuf", RE_SLOT_DEFAULT);
+                                       re= RE_NewRender(" do_build_seq_ibuf");
                                else
-                                       re= RE_NewRender(sce->id.name, RE_SLOT_VIEW);
+                                       re= RE_NewRender(sce->id.name);
 
                                RE_BlenderFrame(re, sce, NULL, sce->lay, frame);
 
index 356ae15..c6e3ef4 100644 (file)
@@ -1183,6 +1183,7 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
 {
        Image *ima= oldmain->image.first;
        Scene *sce= oldmain->scene.first;
+       int a;
        
        fd->imamap= oldnewmap_new();
        
@@ -1192,6 +1193,9 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
                        oldnewmap_insert(fd->imamap, ibuf, ibuf, 0);
                if(ima->gputexture)
                        oldnewmap_insert(fd->imamap, ima->gputexture, ima->gputexture, 0);
+               for(a=0; a<IMA_MAX_RENDER_SLOT; a++)
+                       if(ima->renders[a])
+                               oldnewmap_insert(fd->imamap, ima->renders[a], ima->renders[a], 0);
        }
        for(; sce; sce= sce->id.next) {
                if(sce->nodetree) {
@@ -1209,7 +1213,7 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
        OldNew *entry= fd->imamap->entries;
        Image *ima= oldmain->image.first;
        Scene *sce= oldmain->scene.first;
-       int i;
+       int i, a;
        
        /* used entries were restored, so we put them to zero */
        for (i=0; i<fd->imamap->nentries; i++, entry++) {
@@ -1231,6 +1235,8 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
                }
 
                ima->gputexture= newimaadr(fd, ima->gputexture);
+               for(a=0; a<IMA_MAX_RENDER_SLOT; a++)
+                       ima->renders[a]= newimaadr(fd, ima->renders[a]);
        }
        for(; sce; sce= sce->id.next) {
                if(sce->nodetree) {
@@ -2653,7 +2659,8 @@ static void direct_link_image(FileData *fd, Image *ima)
        ima->anim= NULL;
        ima->rr= NULL;
        ima->repbind= NULL;
-       ima->render_text= newdataadr(fd, ima->render_text);
+       memset(ima->renders, 0, sizeof(ima->renders));
+       ima->last_render_slot= ima->render_slot;
        
        ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
        ima->preview = direct_link_preview_image(fd, ima->preview);
index ccd7d5f..f5470d1 100644 (file)
@@ -1625,10 +1625,6 @@ static void write_images(WriteData *wd, ListBase *idbase)
                        }
 
                        write_previews(wd, ima->preview);
-
-                       /* exception: render text only saved in undo files (wd->current) */
-                       if (ima->render_text && wd->current)
-                               writedata(wd, DATA, IMA_RW_MAXTEXT, ima->render_text);
                }
                ima= ima->id.next;
        }
index 8d5268b..d3f9847 100644 (file)
@@ -140,7 +140,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_", RE_SLOT_DEFAULT);
+       bkr->re= RE_NewRender("_Bake View_");
 
        if(scene->r.bake_mode==RE_BAKE_AO) {
                /* If raytracing or AO is disabled, switch it on temporarily for baking. */
index 678de91..bdb93b0 100644 (file)
@@ -391,15 +391,20 @@ static ScrArea *find_empty_image_area(bContext *C)
 static int screen_render_exec(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
-       Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW);
+       Render *re= RE_GetRender(scene->id.name);
+       Image *ima;
        View3D *v3d= CTX_wm_view3d(C);
        int lay= (v3d)? v3d->lay|scene->lay: scene->lay;
 
        if(re==NULL) {
-               re= RE_NewRender(scene->id.name, RE_SLOT_VIEW);
+               re= RE_NewRender(scene->id.name);
        }
        RE_test_break_cb(re, NULL, (int (*)(void *)) blender_test_break);
 
+       ima= BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
+       BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
+       BKE_image_backup_render(scene, ima);
+
        if(RNA_boolean_get(op->ptr, "animation"))
                RE_BlenderAnim(re, scene, lay, scene->r.sfra, scene->r.efra, scene->r.frame_step, op->reports);
        else
@@ -434,7 +439,7 @@ static void render_freejob(void *rjv)
        MEM_freeN(rj);
 }
 
-/* str is IMA_RW_MAXTEXT in size */
+/* str is IMA_MAX_RENDER_TEXT in size */
 static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str)
 {
        char info_time_str[32]; // used to be extern to header_info.c
@@ -475,7 +480,7 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str)
                spos+= sprintf(spos, "| %s ", rs->infostr);
 
        /* very weak... but 512 characters is quite safe */
-       if(spos >= str+IMA_RW_MAXTEXT)
+       if(spos >= str+IMA_MAX_RENDER_TEXT)
                if (G.f & G_DEBUG)
                        printf("WARNING! renderwin text beyond limit \n");
 
@@ -484,12 +489,16 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str)
 static void image_renderinfo_cb(void *rjv, RenderStats *rs)
 {
        RenderJob *rj= rjv;
+       RenderResult *rr;
+
+       rr= RE_AcquireResultRead(rj->re);
 
        /* malloc OK here, stats_draw is not in tile threads */
-       if(rj->image->render_text==NULL)
-               rj->image->render_text= MEM_callocN(IMA_RW_MAXTEXT, "rendertext");
+       if(rr->text==NULL)
+               rr->text= MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext");
 
-       make_renderinfo_string(rs, rj->scene, rj->image->render_text);
+       make_renderinfo_string(rs, rj->scene, rr->text);
+       RE_ReleaseResult(rj->re);
 
        /* make jobs timer to send notifier */
        *(rj->do_update)= 1;
@@ -630,10 +639,11 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
        /* get a render result image, and make sure it is empty */
        ima= BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
        BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
+       BKE_image_backup_render(rj->scene, ima);
        rj->image= ima;
 
        /* setup new render */
-       re= RE_NewRender(scene->id.name, RE_SLOT_VIEW);
+       re= RE_NewRender(scene->id.name);
        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);
index 1b1e311..ee5363a 100644 (file)
@@ -189,7 +189,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, RE_SLOT_VIEW);
+       oglrender->re= RE_NewRender(scene->id.name);
        RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL);
 
        rr= RE_AcquireResultWrite(oglrender->re);
index 2b9526e..13f8b07 100644 (file)
@@ -470,7 +470,7 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int
                }
        }
 
-       re= RE_GetRender(name, RE_SLOT_DEFAULT);
+       re= RE_GetRender(name);
        RE_AcquireResultImage(re, &rres);
 
        if(rres.rectf) {
@@ -698,7 +698,7 @@ void BIF_view3d_previewrender(Scene *scene, ScrArea *sa)
                ri->status= 0;
                
                sprintf(name, "View3dPreview %p", sa);
-               re= ri->re= RE_NewRender(name, RE_SLOT_DEFAULT);
+               re= ri->re= RE_NewRender(name);
                //RE_display_draw_cb(re, view3d_previewrender_progress);
                //RE_stats_draw_cb(re, view3d_previewrender_stats);
                //RE_test_break_cb(re, qtest);
@@ -885,11 +885,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_SLOT_DEFAULT);
+       re= RE_GetRender(name);
        
        /* full refreshed render from first tile */
        if(re==NULL)
-               re= RE_NewRender(name, RE_SLOT_DEFAULT);
+               re= RE_NewRender(name);
                
        /* sce->r gets copied in RE_InitState! */
        sce->r.scemode &= ~(R_MATNODE_PREVIEW|R_TEXNODE_PREVIEW);
index 39a986a..ade0b7d 100644 (file)
@@ -86,14 +86,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, RE_SLOT_VIEW);
+                       Render *re= RE_GetRender(scene->id.name);
                        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, RE_SLOT_VIEW);
+                       Render *re= RE_GetRender(scene->id.name);
                        RenderResult rres;
                        ImBuf *ibuf;
                        
@@ -207,7 +207,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, RE_SLOT_VIEW);
+       Render *re= RE_GetRender(scene->id.name);
        RenderResult rres;
        
        RE_AcquireResultImage(re, &rres);
index 283d849..9f897c4 100644 (file)
@@ -527,12 +527,12 @@ static char *slot_menu()
        char *str;
        int a, slot;
        
-       str= MEM_callocN(RE_SLOT_MAX*32, "menu slots");
+       str= MEM_callocN(IMA_MAX_RENDER_SLOT*32, "menu slots");
        
        strcpy(str, "Slot %t");
        a= strlen(str);
 
-       for(slot=0; slot<RE_SLOT_MAX; slot++)
+       for(slot=0; slot<IMA_MAX_RENDER_SLOT; slot++)
                a += sprintf(str+a, "|Slot %d %%x%d", slot+1, slot);
        
        return str;
@@ -606,7 +606,6 @@ static void image_multi_cb(bContext *C, void *rr_v, void *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);
 }
@@ -707,7 +706,7 @@ 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, int render)
+static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w, short *render_slot)
 {
        uiBlock *block= uiLayoutGetBlock(layout);
        uiBut *but;
@@ -723,10 +722,9 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, Image
        wmenu3= (3*w)/6;
        
        /* menu buts */
-       if(render) {
+       if(render_slot) {
                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");
+               but= uiDefButS(block, MENU, 0, strp,                                    0, 0, wmenu1, 20, render_slot, 0,0,0,0, "Select Slot");
                uiButSetFunc(but, image_multi_cb, rr, iuser);
                MEM_freeN(strp);
        }
@@ -745,7 +743,7 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, Image
        }
 }
 
-static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int render)
+static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, short *render_slot)
 {
        uiBlock *block= uiLayoutGetBlock(layout);
        uiLayout *row;
@@ -766,7 +764,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, render);
+       uiblock_layer_pass_buttons(row, rr, iuser, 230, render_slot);
 
        /* decrease, increase arrows */
        but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT,        0,0,17,20, NULL, 0, 0, 0, 0, "Previous Pass");
@@ -875,9 +873,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, RE_SLOT_VIEW);
+                               Render *re= RE_GetRender(scene->id.name);
                                RenderResult *rr= RE_AcquireResultRead(re);
-                               uiblock_layer_pass_arrow_buttons(layout, rr, iuser, 1);
+                               uiblock_layer_pass_arrow_buttons(layout, rr, iuser, &ima->render_slot);
                                RE_ReleaseResult(re);
                        }
                }
@@ -904,7 +902,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, 0);
+                               uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser, NULL);
                        }
                        else if(ima->source != IMA_SRC_GENERATED) {
                                if(compact == 0) {
@@ -984,7 +982,7 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser
        /* render layers and passes */
        if(ima && iuser) {
                rr= BKE_image_acquire_renderresult(scene, ima);
-               uiblock_layer_pass_buttons(layout, rr, iuser, 160, ima->type==IMA_TYPE_R_RESULT);
+               uiblock_layer_pass_buttons(layout, rr, iuser, 160, (ima->type==IMA_TYPE_R_RESULT)? &ima->render_slot: NULL);
                BKE_image_release_renderresult(scene, ima);
        }
 }
index 33dfc99..6b2693e 100644 (file)
@@ -60,6 +60,8 @@
 #include "UI_view2d.h"
 
 
+#include "RE_pipeline.h"
+
 #include "image_intern.h"
 
 #define HEADER_HEIGHT 18
@@ -86,37 +88,35 @@ static void image_verify_buffer_float(SpaceImage *sima, Image *ima, ImBuf *ibuf,
        }
 }
 
-static void draw_render_info(Image *ima, ARegion *ar)
+static void draw_render_info(Scene *scene, Image *ima, ARegion *ar)
 {
+       RenderResult *rr;
        rcti rect;
        float colf[3];
-       int showspare= 0; // XXX BIF_show_render_spare();
-       
-       if(ima->render_text==NULL)
-               return;
-       
-       rect= ar->winrct;
-       rect.xmin= 0;
-       rect.ymin= ar->winrct.ymax - ar->winrct.ymin - HEADER_HEIGHT;
-       rect.xmax= ar->winrct.xmax - ar->winrct.xmin;
-       rect.ymax= ar->winrct.ymax - ar->winrct.ymin;
-       
-       /* clear header rect */
-       UI_GetThemeColor3fv(TH_BACK, colf);
-       glEnable(GL_BLEND);
-       glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
-       glColor4f(colf[0]+0.1f, colf[1]+0.1f, colf[2]+0.1f, 0.5f);
-       glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax+1);
-       glDisable(GL_BLEND);
        
-       UI_ThemeColor(TH_TEXT_HI);
+       rr= BKE_image_acquire_renderresult(scene, ima);
+
+       if(rr && rr->text) {
+               rect= ar->winrct;
+               rect.xmin= 0;
+               rect.ymin= ar->winrct.ymax - ar->winrct.ymin - HEADER_HEIGHT;
+               rect.xmax= ar->winrct.xmax - ar->winrct.xmin;
+               rect.ymax= ar->winrct.ymax - ar->winrct.ymin;
+               
+               /* clear header rect */
+               UI_GetThemeColor3fv(TH_BACK, colf);
+               glEnable(GL_BLEND);
+               glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+               glColor4f(colf[0]+0.1f, colf[1]+0.1f, colf[2]+0.1f, 0.5f);
+               glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax+1);
+               glDisable(GL_BLEND);
+               
+               UI_ThemeColor(TH_TEXT_HI);
 
-       if(showspare) {
-               UI_DrawString(12, rect.ymin + 5, "(Previous)");
-               UI_DrawString(72, rect.ymin + 5, ima->render_text);
+               UI_DrawString(12, rect.ymin + 5, rr->text);
        }
-       else
-               UI_DrawString(12, rect.ymin + 5, ima->render_text);
+
+       BKE_image_release_renderresult(scene, ima);
 }
 
 void draw_image_info(ARegion *ar, int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf)
@@ -659,10 +659,7 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
        /* paint helpers */
        draw_image_paint_helpers(sima, ar, scene, zoomx, zoomy);
 
-       /* render info */
-       if(ima && show_render)
-               draw_render_info(ima, ar);
-       
+
        /* XXX integrate this code */
 #if 0
        if(ibuf) {
@@ -681,5 +678,9 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
 #endif
 
        ED_space_image_release_buffer(sima, lock);
+
+       /* render info */
+       if(ima && show_render)
+               draw_render_info(scene, ima, ar);
 }
 
index 671bbe5..a223e24 100644 (file)
@@ -1979,21 +1979,21 @@ static int cycle_render_slot_poll(bContext *C)
 
 static int cycle_render_slot_exec(bContext *C, wmOperator *op)
 {
-       Scene *scene= CTX_data_scene(C);
-       int a, slot, cur= RE_GetViewSlot();
+       Image *ima= CTX_data_edit_image(C);
+       int a, slot, cur= ima->render_slot;
 
-       for(a=1; a<RE_SLOT_MAX; a++) {
-               slot= (cur+a)%RE_SLOT_MAX;
+       for(a=1; a<IMA_MAX_RENDER_SLOT; a++) {
+               slot= (cur+a)%IMA_MAX_RENDER_SLOT;
 
-               if(RE_GetRender(scene->id.name, slot)) {
-                       RE_SetViewSlot(slot);
+               if(ima->renders[slot] || slot == ima->last_render_slot) {
+                       ima->render_slot= slot;
                        break;
                }
        }
 
-       if(a == RE_SLOT_MAX)
-               RE_SetViewSlot((cur == 1)? 0: 1);
-
+       if(a == IMA_MAX_RENDER_SLOT)
+               ima->render_slot= ((cur == 1)? 0: 1);
+       
        WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
 
        return OPERATOR_FINISHED;
index eeab6a7..69b2cb9 100644 (file)
@@ -1650,7 +1650,7 @@ void node_read_renderlayers(SpaceNode *snode)
 void node_read_fullsamplelayers(SpaceNode *snode)
 {
        Scene *curscene= NULL; // XXX
-       Render *re= RE_NewRender(curscene->id.name, RE_SLOT_VIEW);
+       Render *re= RE_NewRender(curscene->id.name);
 
        WM_cursor_wait(1);
 
index 3a7933c..5aed1d0 100644 (file)
@@ -72,9 +72,12 @@ typedef struct Image {
        /* sources from: */
        struct anim *anim;
        struct RenderResult *rr;
+
+       struct RenderResult *renders[8]; /* IMA_MAX_RENDER_SLOT */
+       short render_slot, last_render_slot;
        
        short ok, flag;
-       short source, type, pad, pad1;
+       short source, type;
        int lastframe;
 
        /* texture page */
@@ -87,14 +90,13 @@ typedef struct Image {
        struct PackedFile * packedfile;
        struct PreviewImage * preview;
 
-       /* not saved in file, statistics for render result */
-       char *render_text;
-       
+       /* game engine tile animation */
        float lastupdate;
        int lastused;
        short animspeed;
        
-       short gen_x, gen_y, gen_type;   /* for generated images */
+       /* for generated images */
+       short gen_x, gen_y, gen_type;
        
        /* display aspect - for UV editing images resized for faster openGL display */
        float aspx, aspy;
@@ -124,9 +126,9 @@ typedef struct Image {
 
 /* ima->type and ima->source moved to BKE_image.h, for API */
 
-/* render_text maxlen */
-#define IMA_RW_MAXTEXT           512
-
+/* render */
+#define IMA_MAX_RENDER_TEXT            512
+#define IMA_MAX_RENDER_SLOT            8
 
 #endif
 
index 9a30252..7510a2d 100644 (file)
@@ -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, RE_SLOT_RENDERING);
+                       Render *re= RE_GetRender(scene->id.name);
                        RenderResult *rr= RE_AcquireResultWrite(re); 
                        if(rr) {
                                CompBuf *outbuf, *zbuf=NULL;
index be91eb6..f53e3d2 100644 (file)
@@ -354,7 +354,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, RE_SLOT_RENDERING): NULL;
+   Render *re= (sce)? RE_GetRender(sce->id.name): NULL;
    RenderData *rd= data;
    RenderResult *rr= NULL;
 
index 19f6dcf..2a65372 100644 (file)
@@ -129,6 +129,9 @@ typedef struct RenderResult {
        
        /* for render results in Image, verify validity for sequences */
        int framenr;
+
+       /* render info text */
+       char *text;
        
 } RenderResult;
 
@@ -146,21 +149,8 @@ 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, 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);
+struct Render *RE_NewRender (const char *name);
+struct Render *RE_GetRender(const char *name);
 
 /* returns 1 while render is working (or renders called from within render) */
 int RE_RenderInProgress(struct Render *re);
@@ -177,6 +167,7 @@ struct RenderResult *RE_AcquireResultWrite(struct Render *re);
 void RE_ReleaseResult(struct Render *re);
 void RE_AcquireResultImage(struct Render *re, struct RenderResult *rr);
 void RE_ReleaseResultImage(struct Render *re);
+void RE_SwapResult(struct Render *re, struct RenderResult **rr);
 struct RenderStats *RE_GetStats(struct Render *re);
 void RE_ResultGet32(struct Render *re, unsigned int *rect);
 struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name);
index 727f490..db242b0 100644 (file)
@@ -5727,7 +5727,7 @@ void RE_make_sticky(Scene *scene, View3D *v3d)
                return;
        }
        
-       re= RE_NewRender("_make sticky_", RE_SLOT_DEFAULT);
+       re= RE_NewRender("_make sticky_");
        RE_InitState(re, NULL, &scene->r, NULL, scene->r.xsch, scene->r.ysch, NULL);
        
        /* use renderdata and camera to set viewplane */
index 73c9aaf..a3d6edd 100644 (file)
@@ -122,7 +122,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
        Render *envre;
        int cuberes;
        
-       envre= RE_NewRender("Envmap", RE_SLOT_DEFAULT);
+       envre= RE_NewRender("Envmap");
        
        env->lastsize= re->r.size;
        cuberes = (env->cuberes * re->r.size) / 100;
index 3ff4e70..e814a6b 100644 (file)
 static struct {
        ListBase renderlist;
 
-       /* render slots */
-       int viewslot, renderingslot;
-
        /* commandline thread override */
        int threads;
-} RenderGlobal = {{NULL, NULL}, 0, 0, -1}; 
+} RenderGlobal = {{NULL, NULL}, -1}; 
 
 /* hardcopy of current render, used while rendering for speed */
 Render R;
@@ -191,6 +188,8 @@ void RE_FreeRenderResult(RenderResult *res)
                MEM_freeN(res->rectz);
        if(res->rectf)
                MEM_freeN(res->rectf);
+       if(res->text)
+               MEM_freeN(res->text);
        
        MEM_freeN(res);
 }
@@ -978,38 +977,15 @@ static void read_render_result(Render *re, int sample)
 
 /* *************************************************** */
 
-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_GetRender(const char *name)
 {
        Render *re;
 
-       slot= re_get_slot(slot);
-       
        /* search for existing renders */
-       for(re= RenderGlobal.renderlist.first; re; re= re->next) {
-               if(strncmp(re->name, name, RE_MAXNAME)==0 && re->slot==slot) {
+       for(re= RenderGlobal.renderlist.first; re; re= re->next)
+               if(strncmp(re->name, name, RE_MAXNAME)==0)
                        break;
-               }
-       }
+
        return re;
 }
 
@@ -1034,6 +1010,15 @@ RenderResult *RE_AcquireResultWrite(Render *re)
        return NULL;
 }
 
+void RE_SwapResult(Render *re, RenderResult **rr)
+{
+       /* for keeping render buffers */
+       if(re) {
+               SWAP(RenderResult*, re->result, *rr);
+       }
+}
+
+
 void RE_ReleaseResult(Render *re)
 {
        if(re)
@@ -1144,21 +1129,18 @@ RenderStats *RE_GetStats(Render *re)
        return &re->i;
 }
 
-Render *RE_NewRender(const char *name, int slot)
+Render *RE_NewRender(const char *name)
 {
        Render *re;
 
-       slot= re_get_slot(slot);
-       
        /* only one render per name exists */
-       re= RE_GetRender(name, slot);
+       re= RE_GetRender(name);
        if(re==NULL) {
                
                /* new render data struct */
                re= MEM_callocN(sizeof(Render), "new render");
                BLI_addtail(&RenderGlobal.renderlist, re);
                strncpy(re->name, name, RE_MAXNAME);
-               re->slot= slot;
                BLI_rw_mutex_init(&re->resultmutex);
        }
        
@@ -2201,7 +2183,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, RE_SLOT_RENDERING);
+       Render *resc= RE_NewRender(sce->id.name);
        int winx= re->winx, winy= re->winy;
        
        sce->r.cfra= cfra;
@@ -2490,7 +2472,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, RE_SLOT_RENDERING);
+       Render *re= RE_GetRender(scene->id.name);
 
        /* this is the basic trick to get the displayed float or char rect from render result */
        RE_AcquireResultImage(re, &rres);
@@ -2796,7 +2778,6 @@ static int render_initialize_from_scene(Render *re, Scene *scene, SceneRenderLay
 void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, unsigned int lay, int frame)
 {
        /* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */
-       RenderGlobal.renderingslot= re->slot;
        G.rendering= 1;
        
        scene->r.cfra= frame;
@@ -2807,7 +2788,6 @@ void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, unsigned i
        
        /* UGLY WARNING */
        G.rendering= 0;
-       RenderGlobal.renderingslot= RenderGlobal.viewslot;
 }
 
 static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, ReportList *reports)
@@ -2910,7 +2890,6 @@ void RE_BlenderAnim(Render *re, Scene *scene, unsigned int lay, int sfra, int ef
        /* 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;
        
        if(BKE_imtype_is_movie(scene->r.imtype))
                if(!mh->start_movie(scene, &re->r, re->rectx, re->recty, reports))
@@ -3007,7 +2986,6 @@ void RE_BlenderAnim(Render *re, Scene *scene, unsigned int lay, int sfra, int ef
        
        /* UGLY WARNING */
        G.rendering= 0;
-       RenderGlobal.renderingslot= RenderGlobal.viewslot;
 }
 
 /* note; repeated win/disprect calc... solve that nicer, also in compo */
@@ -3041,9 +3019,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_SLOT_VIEW);
+       re= RE_GetRender(scene->id.name);
        if(re==NULL)
-               re= RE_NewRender(scene->id.name, RE_SLOT_VIEW);
+               re= RE_NewRender(scene->id.name);
        RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect);
        re->scene= scene;
        
index df09b8d..185c98c 100644 (file)
@@ -679,7 +679,7 @@ static int render_frame(int argc, char **argv, void *data)
 
                if (argc > 1) {
                        int frame = atoi(argv[1]);
-                       Render *re = RE_NewRender(scene->id.name, RE_SLOT_DEFAULT);
+                       Render *re = RE_NewRender(scene->id.name);
                        ReportList reports;
 
                        BKE_reports_init(&reports, RPT_PRINT);
@@ -703,7 +703,7 @@ static int render_animation(int argc, char **argv, void *data)
        bContext *C = data;
        if (CTX_data_scene(C)) {
                Scene *scene= CTX_data_scene(C);
-               Render *re= RE_NewRender(scene->id.name, RE_SLOT_DEFAULT);
+               Render *re= RE_NewRender(scene->id.name);
                ReportList reports;
                BKE_reports_init(&reports, RPT_PRINT);
                RE_BlenderAnim(re, scene, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step, &reports);