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:
Diffstat (limited to 'source/blender/render/intern/source/pipeline.c')
-rw-r--r--source/blender/render/intern/source/pipeline.c422
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;
}