diff options
Diffstat (limited to 'source/blender/blenkernel/intern/image.c')
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 136 |
1 files changed, 118 insertions, 18 deletions
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index b6b3dd31096..3e7a9de6968 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -342,19 +342,18 @@ void BKE_image_free_buffers(Image *ima) /** Free (or release) any data used by this image (does not free the image itself). */ void BKE_image_free(Image *ima) { - int a; - /* Also frees animdata. */ BKE_image_free_buffers(ima); image_free_packedfiles(ima); - for (a = 0; a < IMA_MAX_RENDER_SLOT; a++) { - if (ima->renders[a]) { - RE_FreeRenderResult(ima->renders[a]); - ima->renders[a] = NULL; + LISTBASE_FOREACH(RenderSlot *, slot, &ima->renderslots) { + if (slot->render) { + RE_FreeRenderResult(slot->render); + slot->render = NULL; } } + BLI_freelistN(&ima->renderslots); BKE_image_free_views(ima); MEM_SAFE_FREE(ima->stereo3d_format); @@ -380,6 +379,12 @@ static void image_init(Image *ima, short source, short type) if (source == IMA_SRC_VIEWER) ima->flag |= IMA_VIEW_AS_RENDER; + if (type == IMA_TYPE_R_RESULT) { + for (int i = 0; i < 8; i++) { + BKE_image_add_renderslot(ima, NULL); + } + } + BKE_color_managed_colorspace_settings_init(&ima->colorspace_settings); ima->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Image Stereo Format"); } @@ -466,8 +471,10 @@ void BKE_image_copy_data(Main *UNUSED(bmain), Image *ima_dst, const Image *ima_s /* Cleanup stuff that cannot be copied. */ ima_dst->cache = NULL; ima_dst->rr = NULL; - for (int i = 0; i < IMA_MAX_RENDER_SLOT; i++) { - ima_dst->renders[i] = NULL; + + BLI_duplicatelist(&ima_dst->renderslots, &ima_src->renderslots); + LISTBASE_FOREACH(RenderSlot *, slot, &ima_dst->renderslots) { + slot->render = NULL; } BLI_listbase_clear(&ima_dst->anims); @@ -2997,7 +3004,7 @@ RenderResult *BKE_image_acquire_renderresult(Scene *scene, Image *ima) if (ima->render_slot == ima->last_render_slot) rr = RE_AcquireResultRead(RE_GetSceneRender(scene)); else - rr = ima->renders[ima->render_slot]; + rr = BKE_image_get_renderslot(ima, ima->render_slot)->render; /* set proper views */ image_init_multilayer_multiview(ima, rr); @@ -3031,22 +3038,23 @@ bool BKE_image_is_openexr(struct Image *ima) void BKE_image_backup_render(Scene *scene, Image *ima, bool free_current_slot) { - /* called right before rendering, ima->renders contains render + /* called right before rendering, ima->renderslots contains render * result pointers for everything but the current render */ Render *re = RE_GetSceneRender(scene); int slot = ima->render_slot, last = ima->last_render_slot; if (slot != last) { - ima->renders[last] = NULL; - RE_SwapResult(re, &ima->renders[last]); + RenderSlot *last_slot = BKE_image_get_renderslot(ima, last); + last_slot->render = NULL; + RE_SwapResult(re, &last_slot->render); - if (ima->renders[slot]) { + RenderSlot *cur_slot = BKE_image_get_renderslot(ima, slot); + if (cur_slot->render) { if (free_current_slot) { - RE_FreeRenderResult(ima->renders[slot]); - ima->renders[slot] = NULL; + BKE_image_clear_renderslot(ima, NULL, slot); } else { - RE_SwapResult(re, &ima->renders[slot]); + RE_SwapResult(re, &cur_slot->render); } } } @@ -3669,11 +3677,12 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc if (BKE_image_is_stereo(ima) && (iuser->flag & IMA_SHOW_STEREO)) actview = iuser->multiview_eye; + RenderSlot *slot; if (from_render) { RE_AcquireResultImage(re, &rres, actview); } - else if (ima->renders[ima->render_slot]) { - rres = *(ima->renders[ima->render_slot]); + else if ((slot = BKE_image_get_renderslot(ima, ima->render_slot))->render) { + rres = *(slot->render); rres.have_combined = ((RenderView *)rres.views.first)->rectf != NULL; } else @@ -4703,3 +4712,94 @@ static void image_update_views_format(Image *ima, ImageUser *iuser) } } } + +RenderSlot *BKE_image_add_renderslot(Image *ima, const char *name) +{ + RenderSlot *slot = MEM_callocN(sizeof(RenderSlot), "Image new Render Slot"); + if (name && name[0]) { + BLI_strncpy(slot->name, name, sizeof(slot->name)); + } + else { + int n = BLI_listbase_count(&ima->renderslots) + 1; + BLI_snprintf(slot->name, sizeof(slot->name), "Slot %d", n); + } + BLI_addtail(&ima->renderslots, slot); + return slot; +} + +bool BKE_image_remove_renderslot(Image *ima, ImageUser *iuser, int index) +{ + int num_slots = BLI_listbase_count(&ima->renderslots); + if (index >= num_slots || num_slots == 1) { + return false; + } + + RenderSlot *remove_slot = BLI_findlink(&ima->renderslots, index); + RenderSlot *current_slot = BLI_findlink(&ima->renderslots, ima->render_slot); + RenderSlot *current_last_slot = BLI_findlink(&ima->renderslots, ima->last_render_slot); + + RenderSlot *next_slot; + if (current_slot == remove_slot) + next_slot = BLI_findlink(&ima->renderslots, (index == num_slots-1)? index-1 : index+1); + else + next_slot = current_slot; + + /* If the slot to be removed is the slot with the last render, make another slot the last render slot. */ + if (remove_slot == current_last_slot) { + /* Choose the currently selected slot unless that one is being removed, in that case take the next one. */ + RenderSlot *next_last_slot; + if (current_slot == remove_slot) + next_last_slot = next_slot; + else + next_last_slot = current_slot; + + if (!iuser) return false; + Render *re = RE_GetSceneRender(iuser->scene); + if (!re) return false; + RE_SwapResult(re, ¤t_last_slot->render); + RE_SwapResult(re, &next_last_slot->render); + current_last_slot = next_last_slot; + } + + current_slot = next_slot; + + BLI_remlink(&ima->renderslots, remove_slot); + + ima->render_slot = BLI_findindex(&ima->renderslots, current_slot); + ima->last_render_slot = BLI_findindex(&ima->renderslots, current_last_slot); + + if (remove_slot->render) { + RE_FreeRenderResult(remove_slot->render); + } + MEM_freeN(remove_slot); + + return true; +} + +bool BKE_image_clear_renderslot(Image *ima, ImageUser *iuser, int index) +{ + if (index == ima->last_render_slot) { + if (!iuser) return false; + if (G.is_rendering) return false; + Render *re = RE_GetSceneRender(iuser->scene); + if (!re) return false; + RE_ClearResult(re); + return true; + } + else { + RenderSlot *slot = BLI_findlink(&ima->renderslots, index); + if (!slot) return false; + if (slot->render) { + RE_FreeRenderResult(slot->render); + slot->render = NULL; + } + return true; + } +} + +RenderSlot *BKE_image_get_renderslot(Image *ima, int index) +{ + RenderSlot *slot = BLI_findlink(&ima->renderslots, index); + BLI_assert(slot); + return slot; +} |