diff options
Diffstat (limited to 'source/blender/render/intern/source/pipeline.c')
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 422 |
1 files changed, 235 insertions, 187 deletions
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 46fb0603038..93666bd2a48 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -34,7 +34,9 @@ #include <string.h> #include <stdlib.h> #include <stddef.h> +#include <errno.h> +#include "DNA_anim_types.h" #include "DNA_image_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" @@ -59,6 +61,7 @@ #include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */ #include "BKE_camera.h" +#include "BKE_colortools.h" #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_image.h" @@ -135,7 +138,7 @@ Render R; /* ********* alloc and free ******** */ -static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const size_t totvideos, const char *name_override); +static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const int totvideos, const char *name_override); static volatile int g_break = 0; static int thread_break(void *UNUSED(arg)) @@ -196,6 +199,39 @@ static void stats_background(void *UNUSED(arg), RenderStats *rs) fflush(stdout); } +static void render_print_save_message( + ReportList *reports, const char *name, int ok, int err) +{ + if (ok) { + /* no need to report, just some helpful console info */ + printf("Saved: '%s'\n", name); + } + else { + /* report on error since users will want to know what failed */ + BKE_reportf(reports, RPT_ERROR, "Render error (%s) cannot save: '%s'", strerror(err), name); + } +} + +static int render_imbuf_write_stamp_test( + ReportList *reports, + Scene *scene, struct RenderResult *rr, ImBuf *ibuf, const char *name, + const ImageFormatData *imf, bool stamp) +{ + int ok; + + if (stamp) { + /* writes the name of the individual cameras */ + ok = BKE_imbuf_write_stamp(scene, rr, ibuf, name, imf); + } + else { + ok = BKE_imbuf_write(ibuf, name, imf); + } + + render_print_save_message(reports, name, ok, errno); + + return ok; +} + void RE_FreeRenderResult(RenderResult *res) { render_result_free(res); @@ -416,6 +452,8 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr, const int view_id) rr->xof = re->disprect.xmin; rr->yof = re->disprect.ymin; + + rr->stamp_data = re->result->stamp_data; } } } @@ -430,7 +468,7 @@ void RE_ReleaseResultImage(Render *re) void RE_ResultGet32(Render *re, unsigned int *rect) { RenderResult rres; - const size_t view_id = BKE_scene_multiview_view_id_get(&re->r, re->viewname); + const int view_id = BKE_scene_multiview_view_id_get(&re->r, re->viewname); RE_AcquireResultImageViews(re, &rres); render_result_rect_get_pixels(&rres, rect, re->rectx, re->recty, &re->scene->view_settings, &re->scene->display_settings, view_id); @@ -505,6 +543,8 @@ void RE_FreeRender(Render *re) BLI_freelistN(&re->r.layers); BLI_freelistN(&re->r.views); + curvemapping_free_data(&re->r.mblur_shutter_curve); + /* main dbase can already be invalid now, some database-free code checks it */ re->main = NULL; re->scene = NULL; @@ -533,6 +573,17 @@ void RE_FreeAllRender(void) #endif } +void RE_FreeAllPersistentData(void) +{ + Render *re; + for (re = RenderGlobal.renderlist.first; re != NULL; re = re->next) { + if ((re->r.mode & R_PERSISTENT_DATA) != 0 && re->engine != NULL) { + RE_engine_free(re->engine); + re->engine = NULL; + } + } +} + /* on file load, free all re */ void RE_FreeAllRenderResults(void) { @@ -637,6 +688,19 @@ static void re_init_resolution(Render *re, Render *source, re->clipcrop = 1.0f + 2.0f / (float)(re->winx > re->winy ? re->winy : re->winx); } +void render_copy_renderdata(RenderData *to, RenderData *from) +{ + BLI_freelistN(&to->layers); + BLI_freelistN(&to->views); + curvemapping_free_data(&to->mblur_shutter_curve); + + *to = *from; + + BLI_duplicatelist(&to->layers, &from->layers); + BLI_duplicatelist(&to->views, &from->views); + curvemapping_copy_data(&to->mblur_shutter_curve, &from->mblur_shutter_curve); +} + /* what doesn't change during entire render sequence */ /* disprect is optional, if NULL it assumes full window render */ void RE_InitState(Render *re, Render *source, RenderData *rd, @@ -650,11 +714,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, re->i.starttime = PIL_check_seconds_timer(); /* copy render data and render layers for thread safety */ - BLI_freelistN(&re->r.layers); - BLI_freelistN(&re->r.views); - re->r = *rd; - BLI_duplicatelist(&re->r.layers, &rd->layers); - BLI_duplicatelist(&re->r.views, &rd->views); + render_copy_renderdata(&re->r, rd); if (source) { /* reuse border flags from source renderer */ @@ -1443,7 +1503,6 @@ void RE_TileProcessor(Render *re) static void do_render_3d(Render *re) { RenderView *rv; - int cfra_backup; re->current_scene_update(re->suh, re->scene); @@ -1455,12 +1514,20 @@ static void do_render_3d(Render *re) RE_parts_clamp(re); /* add motion blur and fields offset to frames */ - cfra_backup = re->scene->r.cfra; + const int cfra_backup = re->scene->r.cfra; + const float subframe_backup = re->scene->r.subframe; - BKE_scene_frame_set(re->scene, (double)re->scene->r.cfra + (double)re->mblur_offs + (double)re->field_offs); + BKE_scene_frame_set( + re->scene, (double)re->scene->r.cfra + (double)re->scene->r.subframe + + (double)re->mblur_offs + (double)re->field_offs); /* init main render result */ main_render_result_new(re); + if (re->result == NULL) { + BKE_report(re->reports, RPT_ERROR, "Failed allocate render result, out of memory"); + G.is_break = true; + return; + } #ifdef WITH_FREESTYLE if (re->r.mode & R_EDGE_FRS) { @@ -1509,7 +1576,7 @@ static void do_render_3d(Render *re) main_render_result_end(re); re->scene->r.cfra = cfra_backup; - re->scene->r.subframe = 0.f; + re->scene->r.subframe = subframe_backup; } /* called by blur loop, accumulate RGBA key alpha */ @@ -1996,7 +2063,7 @@ static void tag_scenes_for_render(Render *re) #endif for (sce = re->main->scene.first; sce; sce = sce->id.next) { - sce->id.flag &= ~LIB_DOIT; + sce->id.tag &= ~LIB_TAG_DOIT; #ifdef DEPSGRAPH_WORKAROUND_HACK tag_dependend_objects_for_render(sce, renderlay); #endif @@ -2005,7 +2072,7 @@ static void tag_scenes_for_render(Render *re) #ifdef WITH_FREESTYLE if (re->freestyle_bmain) { for (sce = re->freestyle_bmain->scene.first; sce; sce = sce->id.next) { - sce->id.flag &= ~LIB_DOIT; + sce->id.tag &= ~LIB_TAG_DOIT; #ifdef DEPSGRAPH_WORKAROUND_HACK tag_dependend_objects_for_render(sce, renderlay); #endif @@ -2014,7 +2081,7 @@ static void tag_scenes_for_render(Render *re) #endif if (RE_GetCamera(re) && composite_needs_render(re->scene, 1)) { - re->scene->id.flag |= LIB_DOIT; + re->scene->id.tag |= LIB_TAG_DOIT; #ifdef DEPSGRAPH_WORKAROUND_HACK tag_dependend_objects_for_render(re->scene, renderlay); #endif @@ -2022,7 +2089,7 @@ static void tag_scenes_for_render(Render *re) if (re->scene->nodetree == NULL) return; - /* check for render-layers nodes using other scenes, we tag them LIB_DOIT */ + /* check for render-layers nodes using other scenes, we tag them LIB_TAG_DOIT */ for (node = re->scene->nodetree->nodes.first; node; node = node->next) { node->flag &= ~NODE_TEST; if (node->type == CMP_NODE_R_LAYERS && (node->flag & NODE_MUTED) == 0) { @@ -2043,11 +2110,11 @@ static void tag_scenes_for_render(Render *re) } if (node->id != (ID *)re->scene) { - if ((node->id->flag & LIB_DOIT) == 0) { + if ((node->id->tag & LIB_TAG_DOIT) == 0) { Scene *scene = (Scene *) node->id; if (render_scene_has_layers_to_render(scene)) { node->flag |= NODE_TEST; - node->id->flag |= LIB_DOIT; + node->id->tag |= LIB_TAG_DOIT; #ifdef DEPSGRAPH_WORKAROUND_HACK tag_dependend_objects_for_render(scene, renderlay); #endif @@ -2097,9 +2164,10 @@ static void ntree_render_scenes(Render *re) /* bad call... need to think over proper method still */ static void render_composit_stats(void *UNUSED(arg), const char *str) { - R.i.infostr = str; - R.stats_draw(R.sdh, &R.i); - R.i.infostr = NULL; + RenderStats i; + memcpy(&i, &R.i, sizeof(i)); + i.infostr = str; + R.stats_draw(R.sdh, &i); } #ifdef WITH_FREESTYLE @@ -2265,7 +2333,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) tag_scenes_for_render(re); for (sce = re->main->scene.first; sce; sce = sce->id.next) { - if (sce->id.flag & LIB_DOIT) { + if (sce->id.tag & LIB_TAG_DOIT) { re1 = RE_GetRender(sce->id.name); if (re1 && (re1->r.scemode & R_FULL_SAMPLE)) { @@ -2366,7 +2434,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) /* garbage collection */ while (rectfs->first) { - RenderView *rv = rectfs->first; + rv = rectfs->first; BLI_remlink(rectfs, rv); MEM_freeN(rv); } @@ -2390,12 +2458,12 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) /* tag scenes unread */ for (scene = re->main->scene.first; scene; scene = scene->id.next) - scene->id.flag |= LIB_DOIT; + scene->id.tag |= LIB_TAG_DOIT; #ifdef WITH_FREESTYLE if (re->freestyle_bmain) { for (scene = re->freestyle_bmain->scene.first; scene; scene = scene->id.next) - scene->id.flag &= ~LIB_DOIT; + scene->id.tag &= ~LIB_TAG_DOIT; } #endif @@ -2404,18 +2472,18 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) Scene *nodescene = (Scene *)node->id; if (nodescene == NULL) nodescene = sce; - if (nodescene->id.flag & LIB_DOIT) { + if (nodescene->id.tag & LIB_TAG_DOIT) { nodescene->r.mode |= R_OSA; /* render struct needs tables */ RE_ReadRenderResult(sce, nodescene); - nodescene->id.flag &= ~LIB_DOIT; + nodescene->id.tag &= ~LIB_TAG_DOIT; } } } /* own render result should be read/allocated */ - if (re->scene->id.flag & LIB_DOIT) { + if (re->scene->id.tag & LIB_TAG_DOIT) { RE_ReadRenderResult(re->scene, re->scene); - re->scene->id.flag &= ~LIB_DOIT; + re->scene->id.tag &= ~LIB_TAG_DOIT; } /* and now we can draw (result is there) */ @@ -2533,8 +2601,10 @@ static void do_render_composite_fields_blur_3d(Render *re) #endif /* weak... the display callback wants an active renderlayer pointer... */ - re->result->renlay = render_get_active_layer(re, re->result); - re->display_update(re->duh, re->result, NULL); + if (re->result != NULL) { + re->result->renlay = render_get_active_layer(re, re->result); + re->display_update(re->duh, re->result, NULL); + } } static void renderresult_stampinfo(Render *re) @@ -2548,7 +2618,13 @@ static void renderresult_stampinfo(Render *re) for (rv = re->result->views.first;rv;rv = rv->next, nr++) { RE_SetActiveRenderView(re, rv->name); RE_AcquireResultImage(re, &rres, nr); - BKE_image_stamp_buf(re->scene, RE_GetCamera(re), (unsigned char *)rres.rect32, rres.rectf, rres.rectx, rres.recty, 4); + BKE_image_stamp_buf(re->scene, + RE_GetCamera(re), + (re->r.stamp & R_STAMP_STRIPMETA) ? rres.stamp_data : NULL, + (unsigned char *)rres.rect32, + rres.rectf, + rres.rectx, rres.recty, + 4); RE_ReleaseResultImage(re); } } @@ -2578,7 +2654,7 @@ static void do_render_seq(Render *re) RenderResult *rr; /* don't assign re->result here as it might change during give_ibuf_seq */ int cfra = re->r.cfra; SeqRenderData context; - size_t view_id, tot_views; + int view_id, tot_views; struct ImBuf **ibuf_arr; int re_x, re_y; @@ -2640,7 +2716,7 @@ static void do_render_seq(Render *re) if (ibuf_arr[view_id]) { /* copy ibuf into combined pixel rect */ - render_result_rect_from_ibuf(rr, &re->r, ibuf_arr[view_id], view_id); + RE_render_result_rect_from_ibuf(rr, &re->r, ibuf_arr[view_id], view_id); if (ibuf_arr[view_id]->metadata && (re->r.stamp & R_STAMP_STRIPMETA)) { /* ensure render stamp info first */ @@ -2725,15 +2801,17 @@ static void do_render_all_options(Render *re) re->stats_draw(re->sdh, &re->i); /* save render result stamp if needed */ - camera = RE_GetCamera(re); - /* sequence rendering should have taken care of that already */ - if (!(render_seq && (re->r.stamp & R_STAMP_STRIPMETA))) - BKE_render_result_stamp_info(re->scene, camera, re->result, false); + if (re->result != NULL) { + camera = RE_GetCamera(re); + /* sequence rendering should have taken care of that already */ + if (!(render_seq && (re->r.stamp & R_STAMP_STRIPMETA))) + BKE_render_result_stamp_info(re->scene, camera, re->result, false); - /* stamp image info here */ - if ((re->r.stamp & R_STAMP_ALL) && (re->r.stamp & R_STAMP_DRAW)) { - renderresult_stampinfo(re); - re->display_update(re->duh, re->result, NULL); + /* stamp image info here */ + if ((re->r.stamp & R_STAMP_ALL) && (re->r.stamp & R_STAMP_DRAW)) { + renderresult_stampinfo(re); + re->display_update(re->duh, re->result, NULL); + } } } @@ -2759,13 +2837,14 @@ static bool check_valid_compositing_camera(Scene *scene, Object *camera_override while (node) { if (node->type == CMP_NODE_R_LAYERS && (node->flag & NODE_MUTED) == 0) { Scene *sce = node->id ? (Scene *)node->id : scene; - - if (!sce->camera && !BKE_scene_camera_find(sce)) { + if (sce->camera == NULL) { + sce->camera = BKE_scene_camera_find(sce); + } + if (sce->camera == NULL) { /* all render layers nodes need camera */ return false; } } - node = node->next; } @@ -2814,6 +2893,8 @@ static bool check_valid_camera_multiview(Scene *scene, Object *camera, ReportLis static int check_valid_camera(Scene *scene, Object *camera_override, ReportList *reports) { + const char *err_msg = "No camera found in scene \"%s\""; + if (camera_override == NULL && scene->camera == NULL) scene->camera = BKE_scene_camera_find(scene); @@ -2825,14 +2906,17 @@ static int check_valid_camera(Scene *scene, Object *camera_override, ReportList Sequence *seq = scene->ed->seqbase.first; while (seq) { - if (seq->type == SEQ_TYPE_SCENE && seq->scene) { + if ((seq->type == SEQ_TYPE_SCENE) && + ((seq->flag & SEQ_SCENE_STRIPS) == 0) && + (seq->scene != NULL)) + { if (!seq->scene_camera) { if (!seq->scene->camera && !BKE_scene_camera_find(seq->scene)) { /* camera could be unneeded due to composite nodes */ Object *override = (seq->scene == scene) ? camera_override : NULL; if (!check_valid_compositing_camera(seq->scene, override)) { - BKE_reportf(reports, RPT_ERROR, "No camera found in scene \"%s\"", seq->scene->id.name+2); + BKE_reportf(reports, RPT_ERROR, err_msg, seq->scene->id.name + 2); return false; } } @@ -2846,7 +2930,7 @@ static int check_valid_camera(Scene *scene, Object *camera_override, ReportList } } else if (!check_valid_compositing_camera(scene, camera_override)) { - BKE_report(reports, RPT_ERROR, "No camera found in scene"); + BKE_reportf(reports, RPT_ERROR, err_msg, scene->id.name + 2); return false; } @@ -2990,16 +3074,13 @@ static void update_physics_cache(Render *re, Scene *scene, int UNUSED(anim_init) { PTCacheBaker baker; + memset(&baker, 0, sizeof(baker)); baker.main = re->main; baker.scene = scene; - baker.pid = NULL; baker.bake = 0; baker.render = 1; baker.anim_init = 1; baker.quick_step = 1; - baker.break_test = re->test_break; - baker.break_data = re->tbh; - baker.progressbar = NULL; BKE_ptcache_bake(&baker); } @@ -3157,11 +3238,17 @@ void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render void RE_RenderFreestyleExternal(Render *re) { if (!re->test_break(re->tbh)) { - RE_Database_FromScene(re, re->main, re->scene, re->lay, 1); - RE_Database_Preprocess(re); + RenderView *rv; + init_freestyle(re); - add_freestyle(re, 1); - RE_Database_Free(re); + + for (rv = re->result->views.first; rv; rv = rv->next) { + RE_SetActiveRenderView(re, rv->name); + RE_Database_FromScene(re, re->main, re->scene, re->lay, 1); + RE_Database_Preprocess(re); + add_freestyle(re, 1); + RE_Database_Free(re); + } } } #endif @@ -3180,15 +3267,15 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen if (ELEM(rd->im_format.imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER) && rd->im_format.views_format == R_IMF_VIEWS_MULTIVIEW) { - RE_WriteRenderResult(reports, rr, name, &rd->im_format, true, NULL); - printf("Saved: %s\n", name); + ok = RE_WriteRenderResult(reports, rr, name, &rd->im_format, true, NULL); + render_print_save_message(reports, name, ok, errno); } /* mono, legacy code */ else if (is_mono || (rd->im_format.views_format == R_IMF_VIEWS_INDIVIDUAL)) { RenderView *rv; - size_t view_id; + int view_id; char filepath[FILE_MAX]; BLI_strncpy(filepath, name, sizeof(filepath)); @@ -3199,8 +3286,8 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen } if (rd->im_format.imtype == R_IMF_IMTYPE_MULTILAYER) { - RE_WriteRenderResult(reports, rr, name, &rd->im_format, false, rv->name); - printf("Saved: %s\n", name); + ok = RE_WriteRenderResult(reports, rr, name, &rd->im_format, false, rv->name); + render_print_save_message(reports, name, ok, errno); } else { ImBuf *ibuf = render_result_rect_to_ibuf(rr, rd, view_id); @@ -3208,18 +3295,7 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen IMB_colormanagement_imbuf_for_write(ibuf, true, false, &scene->view_settings, &scene->display_settings, &rd->im_format); - if (stamp) { - /* writes the name of the individual cameras */ - ok = BKE_imbuf_write_stamp(scene, rr, ibuf, name, &rd->im_format); - } - else { - ok = BKE_imbuf_write(ibuf, name, &rd->im_format); - } - - if (ok == false) { - printf("Render error: cannot save %s\n", name); - } - else printf("Saved: %s\n", name); + ok = render_imbuf_write_stamp_test(reports, scene, rr, ibuf, name, &rd->im_format, stamp); /* optional preview images for exr */ if (ok && rd->im_format.imtype == R_IMF_IMTYPE_OPENEXR && (rd->im_format.flag & R_IMF_FLAG_PREVIEW_JPG)) { @@ -3234,14 +3310,7 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen IMB_colormanagement_imbuf_for_write(ibuf, true, false, &scene->view_settings, &scene->display_settings, &imf); - if (stamp) { - /* writes the name of the individual cameras */ - ok = BKE_imbuf_write_stamp(scene, rr, ibuf, name, &imf); - } - else { - ok = BKE_imbuf_write(ibuf, name, &imf); - } - printf("Saved: %s\n", name); + ok = render_imbuf_write_stamp_test(reports, scene, rr, ibuf, name, &imf, stamp); } /* imbuf knows which rects are not part of ibuf */ @@ -3270,15 +3339,7 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen ibuf_arr[2] = IMB_stereo3d_ImBuf(&scene->r.im_format, ibuf_arr[0], ibuf_arr[1]); - if (stamp) - ok = BKE_imbuf_write_stamp(scene, rr, ibuf_arr[2], name, &rd->im_format); - else - ok = BKE_imbuf_write(ibuf_arr[2], name, &rd->im_format); - - if (ok == false) - printf("Render error: cannot save %s\n", name); - else - printf("Saved: %s\n", name); + ok = render_imbuf_write_stamp_test(reports, scene, rr, ibuf_arr[2], name, &rd->im_format, stamp); /* optional preview images for exr */ if (ok && rd->im_format.imtype == R_IMF_IMTYPE_OPENEXR && @@ -3296,12 +3357,7 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen IMB_colormanagement_imbuf_for_write(ibuf_arr[2], true, false, &scene->view_settings, &scene->display_settings, &imf); - if (stamp) - ok = BKE_imbuf_write_stamp(scene, rr, ibuf_arr[2], name, &rd->im_format); - else - ok = BKE_imbuf_write(ibuf_arr[2], name, &imf); - - printf("Saved: %s\n", name); + ok = render_imbuf_write_stamp_test(reports, scene, rr, ibuf_arr[2], name, &rd->im_format, stamp); } /* imbuf knows which rects are not part of ibuf */ @@ -3314,8 +3370,9 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen return ok; } -bool RE_WriteRenderViewsMovie(ReportList *reports, RenderResult *rr, Scene *scene, RenderData *rd, bMovieHandle *mh, - const size_t width, const size_t height, void **movie_ctx_arr, const size_t totvideos, bool preview) +bool RE_WriteRenderViewsMovie( + ReportList *reports, RenderResult *rr, Scene *scene, RenderData *rd, bMovieHandle *mh, + void **movie_ctx_arr, const int totvideos, bool preview) { bool is_mono; bool ok = true; @@ -3326,32 +3383,17 @@ bool RE_WriteRenderViewsMovie(ReportList *reports, RenderResult *rr, Scene *scen is_mono = BLI_listbase_count_ex(&rr->views, 2) < 2; if (is_mono || (scene->r.im_format.views_format == R_IMF_VIEWS_INDIVIDUAL)) { - size_t view_id; + int view_id; for (view_id = 0; view_id < totvideos; view_id++) { - bool do_free = false; const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, view_id); ImBuf *ibuf = render_result_rect_to_ibuf(rr, &scene->r, view_id); - /* note; the way it gets 32 bits rects is weak... */ - if (ibuf->rect == NULL) { - ibuf->rect = MEM_mapallocN(sizeof(int) * rr->rectx * rr->recty, "temp 32 bits rect"); - ibuf->mall |= IB_rect; - render_result_rect_get_pixels(rr, ibuf->rect, width, height, &scene->view_settings, &scene->display_settings, view_id); - do_free = true; - } - IMB_colormanagement_imbuf_for_write(ibuf, true, false, &scene->view_settings, &scene->display_settings, &scene->r.im_format); ok &= mh->append_movie(movie_ctx_arr[view_id], rd, preview ? scene->r.psfra : scene->r.sfra, scene->r.cfra, (int *) ibuf->rect, ibuf->x, ibuf->y, suffix, reports); - if (do_free) { - MEM_freeN(ibuf->rect); - ibuf->rect = NULL; - ibuf->mall &= ~IB_rect; - } - /* imbuf knows which rects are not part of ibuf */ IMB_freeImBuf(ibuf); } @@ -3360,8 +3402,7 @@ bool RE_WriteRenderViewsMovie(ReportList *reports, RenderResult *rr, Scene *scen else { /* R_IMF_VIEWS_STEREO_3D */ const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; ImBuf *ibuf_arr[3] = {NULL}; - bool do_free[2] = {false, false}; - size_t i; + int i; BLI_assert((totvideos == 1) && (scene->r.im_format.views_format == R_IMF_VIEWS_STEREO_3D)); @@ -3369,14 +3410,6 @@ bool RE_WriteRenderViewsMovie(ReportList *reports, RenderResult *rr, Scene *scen int view_id = BLI_findstringindex(&rr->views, names[i], offsetof(RenderView, name)); ibuf_arr[i] = render_result_rect_to_ibuf(rr, &scene->r, view_id); - /* note; the way it gets 32 bits rects is weak... */ - if (ibuf_arr[i]->rect == NULL) { - ibuf_arr[i]->rect = MEM_mapallocN(sizeof(int) * width * height, "temp 32 bits rect"); - ibuf_arr[i]->mall |= IB_rect; - render_result_rect_get_pixels(rr, ibuf_arr[i]->rect, width, height, &scene->view_settings, &scene->display_settings, view_id); - do_free[i] = true; - } - IMB_colormanagement_imbuf_for_write(ibuf_arr[i], true, false, &scene->view_settings, &scene->display_settings, &scene->r.im_format); } @@ -3387,12 +3420,6 @@ bool RE_WriteRenderViewsMovie(ReportList *reports, RenderResult *rr, Scene *scen ibuf_arr[2]->x, ibuf_arr[2]->y, "", reports); for (i = 0; i < 2; i++) { - if (do_free[i]) { - MEM_freeN(ibuf_arr[i]->rect); - ibuf_arr[i]->rect = NULL; - ibuf_arr[i]->mall &= ~IB_rect; - } - /* imbuf knows which rects are not part of ibuf */ IMB_freeImBuf(ibuf_arr[i]); } @@ -3401,7 +3428,7 @@ bool RE_WriteRenderViewsMovie(ReportList *reports, RenderResult *rr, Scene *scen return ok; } -static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const size_t totvideos, const char *name_override) +static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const int totvideos, const char *name_override) { char name[FILE_MAX]; RenderResult rres; @@ -3412,7 +3439,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie /* write movie or image */ if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { - RE_WriteRenderViewsMovie(re->reports, &rres, scene, &re->r, mh, re->rectx, re->recty, re->movie_ctx_arr, totvideos, false); + RE_WriteRenderViewsMovie(re->reports, &rres, scene, &re->r, mh, re->movie_ctx_arr, totvideos, false); } else { if (name_override) @@ -3448,7 +3475,9 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie return ok; } -static void get_videos_dimensions(Render *re, RenderData *rd, size_t *r_width, size_t *r_height) +static void get_videos_dimensions( + Render *re, RenderData *rd, + size_t *r_width, size_t *r_height) { size_t width, height; if (re->r.mode & R_BORDER) { @@ -3469,6 +3498,18 @@ static void get_videos_dimensions(Render *re, RenderData *rd, size_t *r_width, s BKE_scene_multiview_videos_dimensions_get(rd, width, height, r_width, r_height); } +static void re_movie_free_all(Render *re, bMovieHandle *mh, int totvideos) +{ + int i; + + for (i = 0; i < totvideos; i++) { + mh->end_movie(re->movie_ctx_arr[i]); + mh->context_free(re->movie_ctx_arr[i]); + } + + MEM_SAFE_FREE(re->movie_ctx_arr); +} + /* saves images to disk */ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_override, unsigned int lay_override, int sfra, int efra, int tfra) @@ -3477,7 +3518,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri bMovieHandle *mh = NULL; int cfrao = scene->r.cfra; int nfra, totrendered = 0, totskipped = 0; - const size_t totvideos = BKE_scene_multiview_num_videos_get(&rd); + const int totvideos = BKE_scene_multiview_num_videos_get(&rd); const bool is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype); const bool is_multiview_name = ((scene->r.scemode & R_MULTIVIEW) != 0 && (scene->r.im_format.views_format == R_IMF_VIEWS_INDIVIDUAL)); @@ -3488,24 +3529,28 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri if (!render_initialize_from_main(re, &rd, bmain, scene, NULL, camera_override, lay_override, 0, 1)) return; - /* we don't support Frame Server and streaming of individual views */ + /* MULTIVIEW_TODO: + * in case a new video format is added that implements get_next_frame multiview has to be addressed + * or the error throwing for R_IMF_IMTYPE_FRAMESERVER has to be extended for those cases as well + */ if ((rd.im_format.imtype == R_IMF_IMTYPE_FRAMESERVER) && (totvideos > 1)) { BKE_report(re->reports, RPT_ERROR, "Frame Server only support stereo output for multiview rendering"); return; } - - /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ - /* is also set by caller renderwin.c */ - G.is_rendering = true; - - re->flag |= R_ANIMATION; if (is_movie) { - size_t i, width, height; + size_t width, height; + int i; + bool is_error = false; get_videos_dimensions(re, &rd, &width, &height); mh = BKE_movie_handle_get(scene->r.im_format.imtype); + if (mh == NULL) { + BKE_report(re->reports, RPT_ERROR, "Movie format unsupported"); + return; + } + re->movie_ctx_arr = MEM_mallocN(sizeof(void *) * totvideos, "Movies' Context"); for (i = 0; i < totvideos; i++) { @@ -3513,49 +3558,63 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri re->movie_ctx_arr[i] = mh->context_create(); - if (!mh->start_movie(re->movie_ctx_arr[i], scene, &re->r, width, height, re->reports, false, suffix)) - G.is_break = true; + if (!mh->start_movie(re->movie_ctx_arr[i], scene, &re->r, width, height, re->reports, false, suffix)) { + is_error = true; + break; + } } - } - - if (mh && mh->get_next_frame) { - /* MULTIVIEW_TODO: - * in case a new video format is added that implements get_next_frame multiview has to be addressed - * or the error throwing for R_IMF_IMTYPE_FRAMESERVER has to be extended for those cases as well - */ - BLI_assert(totvideos < 2); - while (!(G.is_break == 1)) { - int nf = mh->get_next_frame(re->movie_ctx_arr[0], &re->r, re->reports); - if (nf >= 0 && nf >= scene->r.sfra && nf <= scene->r.efra) { - scene->r.cfra = re->r.cfra = nf; + if (is_error) { + /* report is handled above */ + re_movie_free_all(re, mh, i + 1); + return; + } + } - BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE); + /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ + /* is also set by caller renderwin.c */ + G.is_rendering = true; - do_render_all_options(re); - totrendered++; + re->flag |= R_ANIMATION; - if (re->test_break(re->tbh) == 0) { - if (!do_write_image_or_movie(re, bmain, scene, mh, totvideos, NULL)) - G.is_break = true; - } + { + for (nfra = sfra, scene->r.cfra = sfra; scene->r.cfra <= efra; scene->r.cfra++) { + char name[FILE_MAX]; - if (G.is_break == false) { - BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */ - BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_WRITE); + /* Special case for 'mh->get_next_frame' + * this overrides regular frame stepping logic */ + if (mh && mh->get_next_frame) { + while (G.is_break == false) { + int nfra_test = mh->get_next_frame(re->movie_ctx_arr[0], &re->r, re->reports); + if (nfra_test >= 0 && nfra_test >= sfra && nfra_test <= efra) { + nfra = nfra_test; + break; + } + else { + if (re->test_break(re->tbh)) { + G.is_break = true; + } + } } } - else { - if (re->test_break(re->tbh)) { - G.is_break = true; - } + + /* Here is a feedback loop exists -- render initialization requires updated + * render layers settings which could be animated, but scene evaluation for + * the frame happens later because it depends on what layers are visible to + * render engine. + * + * The idea here is to only evaluate animation data associated with the scene, + * which will make sure render layer settings are up-to-date, initialize the + * render database itself and then perform full scene update with only needed + * layers. + * -sergey- + */ + { + float ctime = BKE_scene_frame_get(scene); + AnimData *adt = BKE_animdata_from_id(&scene->id); + BKE_animsys_evaluate_animdata(scene, &scene->id, adt, ctime, ADT_RECALC_ALL); } - } - } - else { - for (nfra = sfra, scene->r.cfra = sfra; scene->r.cfra <= efra; scene->r.cfra++) { - char name[FILE_MAX]; - + /* only border now, todo: camera lens. (ton) */ render_initialize_from_main(re, &rd, bmain, scene, NULL, camera_override, lay_override, 1, 0); @@ -3701,15 +3760,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri /* end movie */ if (is_movie) { - size_t i; - for (i = 0; i < totvideos; i++) { - mh->end_movie(re->movie_ctx_arr[i]); - mh->context_free(re->movie_ctx_arr[i]); - } - - if (re->movie_ctx_arr) { - MEM_freeN(re->movie_ctx_arr); - } + re_movie_free_all(re, mh, totvideos); } if (totskipped && totrendered == 0) @@ -3930,13 +3981,10 @@ bool RE_layers_have_name(struct RenderResult *rr) switch (BLI_listbase_count_ex(&rr->layers, 2)) { case 0: return false; - break; case 1: return (((RenderLayer *)rr->layers.first)->name[0] != '\0'); - break; default: return true; - break; } return false; } |