diff options
Diffstat (limited to 'source/blender/blenkernel/intern/image.c')
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 208 |
1 files changed, 150 insertions, 58 deletions
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 76cf7317b19..b5abdcae2d4 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -82,6 +82,7 @@ #include "BKE_scene.h" #include "BKE_node.h" #include "BKE_sequencer.h" /* seq_foreground_frame_get() */ +#include "BKE_workspace.h" #include "BLF_api.h" @@ -341,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); @@ -369,7 +369,6 @@ static void image_init(Image *ima, short source, short type) ima->ok = IMA_OK; - ima->xrep = ima->yrep = 1; ima->aspx = ima->aspy = 1.0; ima->gen_x = 1024; ima->gen_y = 1024; ima->gen_type = IMA_GENTYPE_GRID; @@ -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,18 +471,17 @@ 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); - ima_dst->totbind = 0; for (int i = 0; i < TEXTARGET_COUNT; i++) { - ima_dst->bindcode[i] = 0; ima_dst->gputexture[i] = NULL; } - ima_dst->repbind = NULL; if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) { BKE_previewimg_id_copy(&ima_dst->id, &ima_src->id); @@ -540,16 +544,14 @@ bool BKE_image_scale(Image *image, int width, int height) return (ibuf != NULL); } -bool BKE_image_has_bindcode(Image *ima) +bool BKE_image_has_opengl_texture(Image *ima) { - bool has_bindcode = false; for (int i = 0; i < TEXTARGET_COUNT; i++) { - if (ima->bindcode[i]) { - has_bindcode = true; - break; + if (ima->gputexture[i]) { + return true; } } - return has_bindcode; + return false; } static void image_init_color_management(Image *ima) @@ -932,21 +934,6 @@ void BKE_image_tag_time(Image *ima) ima->lastused = PIL_check_seconds_timer_i(); } -#if 0 -static void tag_all_images_time(Main *bmain) -{ - Image *ima; - int ctime = PIL_check_seconds_timer_i(); - - ima = bmain->image.first; - while (ima) { - if (ima->bindcode || ima->repbind || ima->ibufs.first) { - ima->lastused = ctime; - } - } -} -#endif - static uintptr_t image_mem_size(Image *image) { uintptr_t size = 0; @@ -1208,7 +1195,6 @@ bool BKE_imtype_is_movie(const char imtype) case R_IMF_IMTYPE_H264: case R_IMF_IMTYPE_THEORA: case R_IMF_IMTYPE_XVID: - case R_IMF_IMTYPE_FRAMESERVER: return true; } return false; @@ -1349,7 +1335,6 @@ char BKE_imtype_from_arg(const char *imtype_arg) else if (STREQ(imtype_arg, "MULTILAYER")) return R_IMF_IMTYPE_MULTILAYER; #endif else if (STREQ(imtype_arg, "FFMPEG")) return R_IMF_IMTYPE_FFMPEG; - else if (STREQ(imtype_arg, "FRAMESERVER")) return R_IMF_IMTYPE_FRAMESERVER; #ifdef WITH_CINEON else if (STREQ(imtype_arg, "CINEON")) return R_IMF_IMTYPE_CINEON; else if (STREQ(imtype_arg, "DPX")) return R_IMF_IMTYPE_DPX; @@ -2654,19 +2639,19 @@ void BKE_image_walk_all_users(const Main *mainp, void *customdata, } } + for (Camera *cam = mainp->camera.first; cam; cam = cam->id.next) { + for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) { + callback(bgpic->ima, &bgpic->iuser, customdata); + } + } + /* image window, compo node users */ for (wm = mainp->wm.first; wm; wm = wm->id.next) { /* only 1 wm */ for (win = wm->windows.first; win; win = win->next) { - ScrArea *sa; - for (sa = win->screen->areabase.first; sa; sa = sa->next) { - if (sa->spacetype == SPACE_VIEW3D) { - View3D *v3d = sa->spacedata.first; - BGpic *bgpic; - for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { - callback(bgpic->ima, &bgpic->iuser, customdata); - } - } - else if (sa->spacetype == SPACE_IMAGE) { + const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); + + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + if (sa->spacetype == SPACE_IMAGE) { SpaceImage *sima = sa->spacedata.first; callback(sima->image, &sima->iuser, customdata); } @@ -3019,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); @@ -3053,27 +3038,39 @@ 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]); + /* Ensure we always have a valid render slot. */ + if (!ima->renderslots.first) { + BKE_image_add_renderslot(ima, NULL); + ima->render_slot = 0; + ima->last_render_slot = 0; + } + else if (ima->render_slot >= BLI_listbase_count(&ima->renderslots)) { + ima->render_slot = 0; + ima->last_render_slot = 0; + } + + RenderSlot *last_slot = BKE_image_get_renderslot(ima, ima->last_render_slot); + RenderSlot *cur_slot = BKE_image_get_renderslot(ima, ima->render_slot); - if (ima->renders[slot]) { + if (last_slot && ima->render_slot != ima->last_render_slot) { + last_slot->render = NULL; + RE_SwapResult(re, &last_slot->render); + + if (cur_slot->render) { if (free_current_slot) { - RE_FreeRenderResult(ima->renders[slot]); - ima->renders[slot] = NULL; + BKE_image_clear_renderslot(ima, NULL, ima->render_slot); } else { - RE_SwapResult(re, &ima->renders[slot]); + RE_SwapResult(re, &cur_slot->render); } } } - ima->last_render_slot = slot; + ima->last_render_slot = ima->render_slot; } /**************************** multiview load openexr *********************************/ @@ -3691,11 +3688,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 @@ -4725,3 +4723,97 @@ static void image_update_views_format(Image *ima, ImageUser *iuser) } } } + +/**************************** Render Slots ***************************/ + +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) +{ + /* Can be NULL for images without render slots. */ + return BLI_findlink(&ima->renderslots, index); +} |