Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_image.h3
-rw-r--r--source/blender/blenkernel/intern/displist.c6
-rw-r--r--source/blender/blenkernel/intern/image.c91
-rw-r--r--source/blender/blenkernel/intern/sequencer.c4
-rw-r--r--source/blender/blenloader/intern/readfile.c11
-rw-r--r--source/blender/blenloader/intern/writefile.c4
-rw-r--r--source/blender/editors/object/object_bake.c2
-rw-r--r--source/blender/editors/render/render_preview.c8
-rw-r--r--source/blender/editors/screen/screen_ops.c38
-rw-r--r--source/blender/editors/space_file/writeimage.c6
-rw-r--r--source/blender/editors/space_image/image_buttons.c24
-rw-r--r--source/blender/editors/space_image/image_draw.c52
-rw-r--r--source/blender/editors/space_image/image_ops.c18
-rw-r--r--source/blender/editors/space_node/node_edit.c2
-rw-r--r--source/blender/makesdna/DNA_image_types.h18
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_composite.c2
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_image.c2
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h21
-rw-r--r--source/blender/render/intern/source/convertblender.c2
-rw-r--r--source/blender/render/intern/source/envmap.c2
-rw-r--r--source/blender/render/intern/source/pipeline.c66
-rw-r--r--source/creator/creator.c4
22 files changed, 211 insertions, 175 deletions
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 153cf3f300e..8b6c57dba63 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -142,6 +142,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);
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 91716ce7266..5807e5fb381 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_", 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 */
}
@@ -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_", RE_SLOT_DEFAULT);
+ Render *re= RE_GetRender("_Shade View_");
if(re) {
RE_Database_Free(re);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index d6edb068fa0..b1a8ee16f28 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -236,7 +236,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;
@@ -250,6 +250,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);
@@ -260,9 +262,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;
+ }
}
}
@@ -1088,7 +1092,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)) {
@@ -1594,20 +1598,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 */
@@ -1917,17 +1949,26 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
{
Render *re= NULL;
RenderResult *rr= NULL;
+ int from_render= (ima->render_slot == ima->last_render_slot);
/* 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);
-
- /* release is done in BKE_image_release_ibuf using lock_r */
- *lock_r= re;
+ re= RE_GetRender(iuser->scene->id.name);
+
+ /* for the last render we get result for Render itself,
+ for others a RenderResult is stored in the Image */
+ if(from_render) {
+ rr= RE_AcquireResultRead(re);
+ /* release is done in BKE_image_release_ibuf using lock_r */
+ *lock_r= re;
+ }
+ else {
+ rr= ima->renders[ima->render_slot];
+ *lock_r= NULL;
+ }
}
if(rr==NULL)
@@ -1955,9 +1996,15 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
channels= 4;
layer= (iuser)? iuser->layer: 0;
pass= (iuser)? iuser->pass: 0;
+
+ memset(&rres, 0, sizeof(rres));
/* this gives active layer, composite or seqence result */
- RE_AcquireResultImage(RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW), &rres);
+ if(from_render)
+ RE_AcquireResultImage(RE_GetRender(iuser->scene->id.name), &rres);
+ else if(rr)
+ rres= *rr;
+
rect= (unsigned int *)rres.rect32;
rectf= rres.rectf;
rectz= rres.rectz;
@@ -2012,13 +2059,15 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
ibuf->flags |= IB_zbuffloat;
ibuf->dither= dither;
- RE_ReleaseResultImage(re);
+ if(from_render)
+ RE_ReleaseResultImage(re);
ima->ok= IMA_OK_LOADED;
return ibuf;
}
- RE_ReleaseResultImage(re);
+ if(from_render)
+ RE_ReleaseResultImage(re);
}
return NULL;
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 979cea5832d..d7d63e850de 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -2093,9 +2093,9 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
oldcfra = seq->scene->r.cfra;
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);
/* prevent eternal loop */
doseq= scene->r.scemode & R_DOSEQ;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 9fed1e5c5af..627e086ba94 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1191,6 +1191,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();
@@ -1200,6 +1201,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) {
@@ -1217,7 +1221,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++) {
@@ -1239,6 +1243,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) {
@@ -2660,7 +2666,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);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 3e3ca8dd174..7d2d1487c45 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -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;
}
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index a4f419cf996..dad5d533695 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_", 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. */
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 1563c5a8e1d..89a49b12751 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_SLOT_DEFAULT);
+ re= RE_GetRender(name);
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_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);
@@ -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_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);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 4addfc9cdda..54dd27c864f 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -2894,18 +2894,23 @@ 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, RE_SLOT_VIEW);
+ Render *re= RE_GetRender(scene->id.name);
+ Image *ima;
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, scene->r.sfra, scene->r.efra, scene->r.frame_step, op->reports);
else
RE_BlenderFrame(re, scene, NULL, scene->r.cfra);
-
+
// no redraw needed, we leave state as we entered it
ED_update_for_newframe(C, 1);
@@ -2934,7 +2939,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
@@ -2975,7 +2980,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");
@@ -2984,12 +2989,17 @@ 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;
@@ -3132,7 +3142,9 @@ static void render_startjob(void *rjv, short *stop, short *do_update)
// Workaround for Apple gcc 4.2.1 omp vs background thread bug
pthread_setspecific (gomp_tls_key, thread_tls_data);
#endif
-
+
+ BKE_image_backup_render(rj->scene, rj->image);
+
if(rj->anim)
RE_BlenderAnim(rj->re, rj->scene, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step, rj->reports);
else
@@ -3249,11 +3261,11 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
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);
-
+
rj->re= re;
G.afbreek= 0;
@@ -3411,7 +3423,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);
diff --git a/source/blender/editors/space_file/writeimage.c b/source/blender/editors/space_file/writeimage.c
index 07eb58bffbc..c5bdade6153 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, 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;
@@ -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, RE_SLOT_VIEW);
+ Render *re= RE_GetRender(scene->id.name);
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 01c53961f66..bd5f8754990 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -538,12 +538,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;
@@ -617,7 +617,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);
}
@@ -718,7 +717,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;
@@ -734,10 +733,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);
}
@@ -756,7 +754,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;
@@ -777,7 +775,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");
@@ -886,9 +884,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);
}
}
@@ -915,7 +913,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) {
@@ -995,7 +993,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);
}
}
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index cb942472b9e..bc07222c9fb 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -64,6 +64,8 @@
#include "WM_api.h"
+#include "RE_pipeline.h"
+
#include "image_intern.h"
#define HEADER_HEIGHT 18
@@ -90,37 +92,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->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)
@@ -654,7 +654,7 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
/* render info */
if(ibuf && ima && show_render)
- draw_render_info(ima, ar);
+ draw_render_info(scene, ima, ar);
/* XXX integrate this code */
#if 0
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index b69b6a552a6..eb87b5656bf 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1805,21 +1805,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;
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 473f706f6f8..06c62cf0268 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, RE_SLOT_VIEW);
+ Render *re= RE_NewRender(curscene->id.name);
WM_cursor_wait(1);
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index 3a7933cf425..5aed1d0c2d0 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -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
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c
index 76a78e46e3a..d9077d45e0c 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, RE_SLOT_RENDERING);
+ Render *re= RE_GetRender(scene->id.name);
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 aa3fa9db412..1ced4424121 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, RE_SLOT_RENDERING): NULL;
+ Render *re= (sce)? RE_GetRender(sce->id.name): 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 f9c4e9690a1..dafed36d8e5 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -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);
@@ -175,6 +165,7 @@ void RE_FreeRenderResult(struct RenderResult *rr);
struct RenderResult *RE_AcquireResultRead(struct Render *re);
struct RenderResult *RE_AcquireResultWrite(struct Render *re);
void RE_ReleaseResult(struct Render *re);
+void RE_SwapResult(struct Render *re, struct RenderResult **rr);
void RE_AcquireResultImage(struct Render *re, struct RenderResult *rr);
void RE_ReleaseResultImage(struct Render *re);
struct RenderStats *RE_GetStats(struct Render *re);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index c44d83f4f06..ef6b1a4ce77 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_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 */
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 5a69bcb45bd..d2c130508fa 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", RE_SLOT_DEFAULT);
+ envre= RE_NewRender("Envmap");
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 0122f1b5d65..225b9ce1aa6 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -111,12 +111,9 @@
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;
@@ -196,6 +193,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);
}
@@ -994,38 +993,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;
}
@@ -1050,6 +1026,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)
@@ -1158,21 +1143,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);
}
@@ -2215,7 +2197,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;
@@ -2505,7 +2487,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);
@@ -2814,7 +2796,6 @@ 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 */
- RenderGlobal.renderingslot= re->slot;
re->result_ok= 0;
G.rendering= 1;
@@ -2827,7 +2808,6 @@ void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, int frame)
/* UGLY WARNING */
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)
@@ -2931,7 +2911,6 @@ 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))
@@ -3028,7 +3007,6 @@ 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 */
@@ -3062,9 +3040,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;
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 2a4761e6688..68d0730a6f5 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -663,7 +663,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);
@@ -687,7 +687,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->r.sfra, scene->r.efra, scene->r.frame_step, &reports);