diff options
Diffstat (limited to 'source')
16 files changed, 228 insertions, 80 deletions
diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h index 2d0bc6ff15b..15abc0c0a64 100644 --- a/source/blender/depsgraph/DEG_depsgraph_build.h +++ b/source/blender/depsgraph/DEG_depsgraph_build.h @@ -52,14 +52,19 @@ extern "C" { /* Graph Building -------------------------------- */ -/* Build depsgraph for the given scene, and dump results in given - * graph container. - */ +/* Build depsgraph for the given scene, and dump results in given graph container. */ void DEG_graph_build_from_view_layer(struct Depsgraph *graph, struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer); +/* Special version of builder which produces dependency graph suitable for the render pipeline. + * It will contain sequencer and compositor (if needed) and all their dependencies. */ +void DEG_graph_build_for_render_pipeline(struct Depsgraph *graph, + struct Main *bmain, + struct Scene *scene, + struct ViewLayer *view_layer); + /* Tag relations from the given graph for update. */ void DEG_graph_tag_relations_update(struct Depsgraph *graph); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_map.h b/source/blender/depsgraph/intern/builder/deg_builder_map.h index 1199b517f0c..dd124e07a00 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_map.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_map.h @@ -38,8 +38,12 @@ class BuilderMap { TAG_TRANSFORM = (1 << 2), TAG_GEOMETRY = (1 << 3), + TAG_SCENE_COMPOSITOR = (1 << 4), + TAG_SCENE_SEQUENCER = (1 << 5), + /* All ID components has been built. */ - TAG_COMPLETE = (TAG_ANIMATION | TAG_PARAMETERS | TAG_TRANSFORM | TAG_GEOMETRY), + TAG_COMPLETE = (TAG_ANIMATION | TAG_PARAMETERS | TAG_TRANSFORM | TAG_GEOMETRY | + TAG_SCENE_COMPOSITOR | TAG_SCENE_SEQUENCER), }; BuilderMap(); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 10bcfcf04d7..cc9e1d2a9da 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -543,7 +543,10 @@ void DepsgraphNodeBuilder::build_object(int base_index, IDNode *id_node = add_id_node(&object->id); Object *object_cow = get_cow_datablock(object); id_node->linked_state = linked_state; - if (object == scene_->camera) { + /* NOTE: Scene is NULL when building dependency graph for render pipeline. + * Probably need to assign that to something non-NULL, but then the logic here will still be + * somewhat weird. */ + if (scene_ != NULL && object == scene_->camera) { id_node->is_directly_visible = true; } else { @@ -1366,8 +1369,16 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree) build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY, true); } else if (id_type == ID_SCE) { - /* Scenes are used by compositor trees, and handled by render - * pipeline. No need to build dependencies for them here. */ + Scene *node_scene = (Scene *)id; + build_scene_parameters(node_scene); + /* Camera is used by defocus node. + * + * On the one hand it's annoying to always pull it in, but on another hand it's also annoying + * to have hardcoded node-type exception here. */ + if (node_scene->camera != NULL) { + /* TODO(sergey): Use visibility of owner of the node tree. */ + build_object(-1, node_scene->camera, DEG_ID_LINKED_INDIRECTLY, true); + } } else if (id_type == ID_TXT) { /* Ignore script nodes. */ @@ -1442,19 +1453,6 @@ void DepsgraphNodeBuilder::build_image(Image *image) &image->id, NodeType::GENERIC_DATABLOCK, OperationCode::GENERIC_DATABLOCK_UPDATE); } -void DepsgraphNodeBuilder::build_compositor(Scene *scene) -{ - /* For now, just a plain wrapper? */ - // TODO: create compositing component? - // XXX: component type undefined! - // graph->get_node(&scene->id, NULL, NodeType::COMPOSITING, NULL); - - /* for now, nodetrees are just parameters; compositing occurs in internals - * of renderer... */ - add_component_node(&scene->id, NodeType::PARAMETERS); - build_nodetree(scene->nodetree); -} - void DepsgraphNodeBuilder::build_gpencil(bGPdata *gpd) { if (built_map_.checkIsBuiltAndTag(gpd)) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 8b9578915a1..c3a04a9ad88 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -153,7 +153,9 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { void build_id(ID *id); + void build_scene_render(Scene *scene); void build_scene_parameters(Scene *scene); + void build_scene_compositor(Scene *scene); void build_layer_collections(ListBase *lb); void build_view_layer(Scene *scene, @@ -203,7 +205,6 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { void build_texture(Tex *tex); void build_image(Image *image); void build_world(World *world); - void build_compositor(Scene *scene); void build_gpencil(bGPdata *gpd); void build_cachefile(CacheFile *cache_file); void build_mask(Mask *mask); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc index 5fd1b4e8332..4d2fe48e974 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc @@ -27,6 +27,18 @@ namespace DEG { +void DepsgraphNodeBuilder::build_scene_render(Scene *scene) +{ + const bool build_compositor = (scene->r.scemode & R_DOCOMP); + IDNode *id_node = add_id_node(&scene->id); + id_node->linked_state = DEG_ID_LINKED_DIRECTLY; + add_time_source(); + build_scene_parameters(scene); + if (build_compositor) { + build_scene_compositor(scene); + } +} + void DepsgraphNodeBuilder::build_scene_parameters(Scene *scene) { if (built_map_.checkIsBuiltAndTag(scene, BuilderMap::TAG_PARAMETERS)) { @@ -36,4 +48,15 @@ void DepsgraphNodeBuilder::build_scene_parameters(Scene *scene) add_operation_node(&scene->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL); } +void DepsgraphNodeBuilder::build_scene_compositor(Scene *scene) +{ + if (built_map_.checkIsBuiltAndTag(scene, BuilderMap::TAG_SCENE_COMPOSITOR)) { + return; + } + if (scene->nodetree == NULL) { + return; + } + build_nodetree(scene->nodetree); +} + } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc index 675933a38e3..baebd682f3f 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc @@ -125,9 +125,7 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene, build_world(scene->world); } /* Compositor nodes */ - if (scene->nodetree != NULL) { - build_compositor(scene); - } + build_scene_compositor(scene); /* Cache file. */ LISTBASE_FOREACH (CacheFile *, cachefile, &bmain_->cachefiles) { build_cachefile(cachefile); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 10e81faf333..79f28973dc3 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2131,8 +2131,15 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree) build_object(NULL, (Object *)id); } else if (id_type == ID_SCE) { - /* Scenes are used by compositor trees, and handled by render - * pipeline. No need to build dependencies for them here. */ + Scene *node_scene = (Scene *)id; + build_scene_parameters(node_scene); + /* Camera is used by defocus node. + * + * On the one hand it's annoying to always pull it in, but on another hand it's also annoying + * to have hardcoded node-type exception here. */ + if (node_scene->camera != NULL) { + build_object(NULL, node_scene->camera); + } } else if (id_type == ID_TXT) { /* Ignore script nodes. */ @@ -2220,12 +2227,6 @@ void DepsgraphRelationBuilder::build_image(Image *image) build_parameters(&image->id); } -void DepsgraphRelationBuilder::build_compositor(Scene *scene) -{ - /* For now, just a plain wrapper? */ - build_nodetree(scene->nodetree); -} - void DepsgraphRelationBuilder::build_gpencil(bGPdata *gpd) { if (built_map_.checkIsBuiltAndTag(gpd)) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index c97c8a4b375..7d302092119 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -195,7 +195,9 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder { void build_id(ID *id); + void build_scene_render(Scene *scene); void build_scene_parameters(Scene *scene); + void build_scene_compositor(Scene *scene); void build_layer_collections(ListBase *lb); void build_view_layer(Scene *scene, ViewLayer *view_layer); @@ -261,7 +263,6 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder { void build_material(Material *ma); void build_texture(Tex *tex); void build_image(Image *image); - void build_compositor(Scene *scene); void build_gpencil(bGPdata *gpd); void build_cachefile(CacheFile *cache_file); void build_mask(Mask *mask); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc index d8672d35ddb..beada644f71 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc @@ -27,6 +27,15 @@ namespace DEG { +void DepsgraphRelationBuilder::build_scene_render(Scene *scene) +{ + const bool build_compositor = (scene->r.scemode & R_DOCOMP); + build_scene_parameters(scene); + if (build_compositor) { + build_scene_compositor(scene); + } +} + void DepsgraphRelationBuilder::build_scene_parameters(Scene *scene) { if (built_map_.checkIsBuiltAndTag(scene, BuilderMap::TAG_PARAMETERS)) { @@ -38,4 +47,15 @@ void DepsgraphRelationBuilder::build_scene_parameters(Scene *scene) add_relation(parameters_eval_key, scene_eval_key, "Parameters -> Scene Eval"); } +void DepsgraphRelationBuilder::build_scene_compositor(Scene *scene) +{ + if (built_map_.checkIsBuiltAndTag(scene, BuilderMap::TAG_SCENE_COMPOSITOR)) { + return; + } + if (scene->nodetree == NULL) { + return; + } + build_nodetree(scene->nodetree); +} + } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc index a744ecc0f50..8f705fcaae5 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc @@ -106,10 +106,6 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la if (scene->world != NULL) { build_world(scene->world); } - /* Compositor nodes. */ - if (scene->nodetree != NULL) { - build_compositor(scene); - } /* Masks. */ LISTBASE_FOREACH (Mask *, mask, &bmain_->masks) { build_mask(mask); @@ -128,7 +124,8 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la build_collection(NULL, NULL, fls->group); } } - /* Scene parameters. */ + /* Scene parameters, compositor and such. */ + build_scene_compositor(scene); build_scene_parameters(scene); /* Build all set scenes. */ if (scene->set != NULL) { diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index e2a9dde1eea..5d96bfad95e 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -73,7 +73,8 @@ Depsgraph::Depsgraph(Scene *scene, ViewLayer *view_layer, eEvaluationMode mode) ctime(BKE_scene_frame_get(scene)), scene_cow(NULL), is_active(false), - debug_is_evaluating(false) + debug_is_evaluating(false), + is_render_pipeline_depsgraph(false) { BLI_spin_init(&lock); id_hash = BLI_ghash_ptr_new("Depsgraph id hash"); diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 2dcbb6b5574..073ec99b3aa 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -194,6 +194,12 @@ struct Depsgraph { bool debug_is_evaluating; + /* Is set to truth for dependency graph which are used for post-processing (compositor and + * sequencer). + * Such dependency graph needs all view layers (so render pipeline can access names), but it + * does not need any bases. */ + bool is_render_pipeline_depsgraph; + /* Cached list of colliders/effectors for collections and the scene * created along with relations, for fast lookup during evaluation. */ GHash *physics_relations[DEG_PHYSICS_RELATIONS_NUM]; diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index dd2979160cd..138b23888b4 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -222,9 +222,33 @@ struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *node_handle) /* ******************** */ /* Graph Building API's */ -/* Build depsgraph for the given scene layer, and dump results in given - * graph container. - */ +static void graph_build_finalize_common(DEG::Depsgraph *deg_graph, Main *bmain) +{ + /* Detect and solve cycles. */ + DEG::deg_graph_detect_cycles(deg_graph); + /* Simplify the graph by removing redundant relations (to optimize + * traversal later). */ + /* TODO: it would be useful to have an option to disable this in cases where + * it is causing trouble. */ + if (G.debug_value == 799) { + DEG::deg_graph_transitive_reduction(deg_graph); + } + /* Store pointers to commonly used valuated datablocks. */ + deg_graph->scene_cow = (Scene *)deg_graph->get_cow_id(°_graph->scene->id); + /* Flush visibility layer and re-schedule nodes for update. */ + DEG::deg_graph_build_finalize(bmain, deg_graph); + DEG_graph_on_visible_update(bmain, reinterpret_cast<::Depsgraph *>(deg_graph)); +#if 0 + if (!DEG_debug_consistency_check(deg_graph)) { + printf("Consistency validation failed, ABORTING!\n"); + abort(); + } +#endif + /* Relations are up to date. */ + deg_graph->need_update = false; +} + +/* Build depsgraph for the given scene layer, and dump results in given graph container. */ void DEG_graph_build_from_view_layer(Depsgraph *graph, Main *bmain, Scene *scene, @@ -245,34 +269,46 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph, node_builder.begin_build(); node_builder.build_view_layer(scene, view_layer, DEG::DEG_ID_LINKED_DIRECTLY); node_builder.end_build(); - /* Hook up relationships between operations - to determine evaluation - * order. */ + /* Hook up relationships between operations - to determine evaluation order. */ DEG::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache); relation_builder.begin_build(); relation_builder.build_view_layer(scene, view_layer); relation_builder.build_copy_on_write_relations(); - /* Detect and solve cycles. */ - DEG::deg_graph_detect_cycles(deg_graph); - /* Simplify the graph by removing redundant relations (to optimize - * traversal later). */ - /* TODO: it would be useful to have an option to disable this in cases where - * it is causing trouble. */ - if (G.debug_value == 799) { - DEG::deg_graph_transitive_reduction(deg_graph); + /* Finalize building. */ + graph_build_finalize_common(deg_graph, bmain); + /* Finish statistics. */ + if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { + printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time); } - /* Store pointers to commonly used valuated datablocks. */ - deg_graph->scene_cow = (Scene *)deg_graph->get_cow_id(°_graph->scene->id); - /* Flush visibility layer and re-schedule nodes for update. */ - DEG::deg_graph_build_finalize(bmain, deg_graph); - DEG_graph_on_visible_update(bmain, graph); -#if 0 - if (!DEG_debug_consistency_check(deg_graph)) { - printf("Consistency validation failed, ABORTING!\n"); - abort(); +} + +void DEG_graph_build_for_render_pipeline(Depsgraph *graph, + Main *bmain, + Scene *scene, + ViewLayer * /*view_layer*/) +{ + double start_time = 0.0; + if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { + start_time = PIL_check_seconds_timer(); } -#endif - /* Relations are up to date. */ - deg_graph->need_update = false; + DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); + /* Perform sanity checks. */ + BLI_assert(deg_graph->scene == scene); + deg_graph->is_render_pipeline_depsgraph = true; + DEG::DepsgraphBuilderCache builder_cache; + /* Generate all the nodes in the graph first */ + DEG::DepsgraphNodeBuilder node_builder(bmain, deg_graph, &builder_cache); + node_builder.begin_build(); + node_builder.build_scene_render(scene); + node_builder.end_build(); + /* Hook up relationships between operations - to determine evaluation + * order. */ + DEG::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache); + relation_builder.begin_build(); + relation_builder.build_scene_render(scene); + relation_builder.build_copy_on_write_relations(); + /* Finalize building. */ + graph_build_finalize_common(deg_graph, bmain); /* Finish statistics. */ if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) { printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time); diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index 98c50bf6fdf..d714a913b96 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -327,7 +327,7 @@ ViewLayer *get_original_view_layer(const Depsgraph *depsgraph, const IDNode *id_ return BKE_view_layer_default_render(scene_orig); } /* Is possible to have scene linked indirectly (i.e. via the driver) which - * we need to support. Currently there aer issues somewhere else, which + * we need to support. Currently there are issues somewhere else, which * makes testing hard. This is a reported problem, so will eventually be * properly fixed. * @@ -341,11 +341,17 @@ void scene_remove_unused_view_layers(const Depsgraph *depsgraph, Scene *scene_cow) { const ViewLayer *view_layer_input; - /* Indirectly linked scenes means it's not an input scene and not a set scene, and is pulled via - * some driver. Such scenes should not have view layers after copy. */ if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) { + /* Indirectly linked scenes means it's not an input scene and not a set scene, and is pulled + * via some driver. Such scenes should not have view layers after copy. */ view_layer_input = NULL; } + else if (depsgraph->is_render_pipeline_depsgraph) { + /* If the dependency graph is used for post-processing (such as compositor) we do need to + * have access to its view layer names so can not remove any view layers. + * On a more positive side we can remove all the bases from all the view layers. */ + return; + } else { view_layer_input = get_original_view_layer(depsgraph, id_node); } @@ -372,6 +378,13 @@ void scene_remove_unused_view_layers(const Depsgraph *depsgraph, scene_cow->view_layers.last = view_layer_eval; } +void scene_remove_all_bases(Scene *scene_cow) +{ + LISTBASE_FOREACH (ViewLayer *, view_layer, &scene_cow->view_layers) { + BLI_freelistN(&view_layer->object_bases); + } +} + /* Makes it so given view layer only has bases corresponding to enabled * objects. */ void view_layer_remove_disabled_bases(const Depsgraph *depsgraph, ViewLayer *view_layer) @@ -425,6 +438,11 @@ void scene_setup_view_layers_before_remap(const Depsgraph *depsgraph, Scene *scene_cow) { scene_remove_unused_view_layers(depsgraph, id_node, scene_cow); + /* If dependency graph is used for post-processing we don't need any bases and can free of them. + * Do it before re-mapping to make that process faster. */ + if (depsgraph->is_render_pipeline_depsgraph) { + scene_remove_all_bases(scene_cow); + } } void scene_setup_view_layers_after_remap(const Depsgraph *depsgraph, diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index e4a2afa4349..efa328cf14d 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -118,6 +118,11 @@ struct Render { /* render engine */ struct RenderEngine *engine; + /* NOTE: This is a minimal dependency graph and evaluated scene which is enough to access view + * layer visibility and use for post-precessing (compositor and sequencer). */ + Depsgraph *pipeline_depsgraph; + Scene *pipeline_scene_eval; + #ifdef WITH_FREESTYLE struct Main *freestyle_bmain; ListBase freestyle_renders; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 9c1c713ab94..76767d0d1d8 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -74,6 +74,7 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_debug.h" #include "DEG_depsgraph_query.h" #include "PIL_time.h" @@ -1430,10 +1431,10 @@ static void free_all_freestyle_renders(void) /* returns fully composited render-result on given time step (in RenderData) */ static void do_render_composite(Render *re) { - bNodeTree *ntree = re->scene->nodetree; + bNodeTree *ntree = re->pipeline_scene_eval->nodetree; int update_newframe = 0; - if (composite_needs_render(re->scene, 1)) { + if (composite_needs_render(re->pipeline_scene_eval, 1)) { /* save memory... free all cached images */ ntreeFreeCache(ntree); @@ -1471,7 +1472,7 @@ static void do_render_composite(Render *re) if (!re->test_break(re->tbh)) { if (ntree) { - ntreeCompositTagRender(re->scene); + ntreeCompositTagRender(re->pipeline_scene_eval); } if (ntree && re->scene->use_nodes && re->r.scemode & R_DOCOMP) { @@ -1494,7 +1495,7 @@ static void do_render_composite(Render *re) RenderView *rv; for (rv = re->result->views.first; rv; rv = rv->next) { - ntreeCompositExecTree(re->scene, + ntreeCompositExecTree(re->pipeline_scene_eval, ntree, &re->r, true, @@ -1595,12 +1596,8 @@ static void do_render_seq(Render *re) tot_views = BKE_scene_multiview_num_views_get(&re->r); ibuf_arr = MEM_mallocN(sizeof(ImBuf *) * tot_views, "Sequencer Views ImBufs"); - /* TODO(sergey): Currently depsgraph is only used to check whether it is an active - * edit window or not to deal with unkeyed changes. We don't have depsgraph here yet, - * but we also dont' deal with unkeyed changes. But still nice to get proper depsgraph - * within tjhe render pipeline, somehow. - */ - BKE_sequencer_new_render_data(re->main, NULL, re->scene, re_x, re_y, 100, true, &context); + BKE_sequencer_new_render_data( + re->main, re->pipeline_depsgraph, re->scene, re_x, re_y, 100, true, &context); /* the renderresult gets destroyed during the rendering, so we first collect all ibufs * and then we populate the final renderesult */ @@ -1613,7 +1610,7 @@ static void do_render_seq(Render *re) ibuf_arr[view_id] = IMB_dupImBuf(out); IMB_metadata_copy(ibuf_arr[view_id], out); IMB_freeImBuf(out); - BKE_sequencer_imbuf_from_sequencer_space(re->scene, ibuf_arr[view_id]); + BKE_sequencer_imbuf_from_sequencer_space(re->pipeline_scene_eval, ibuf_arr[view_id]); } else { ibuf_arr[view_id] = NULL; @@ -1641,9 +1638,9 @@ static void do_render_seq(Render *re) } if (recurs_depth == 0) { /* with nested scenes, only free on toplevel... */ - Editing *ed = re->scene->ed; + Editing *ed = re->pipeline_scene_eval->ed; if (ed) { - BKE_sequencer_free_imbuf(re->scene, &ed->seqbase, true); + BKE_sequencer_free_imbuf(re->pipeline_scene_eval, &ed->seqbase, true); } } IMB_freeImBuf(ibuf_arr[view_id]); @@ -2071,6 +2068,32 @@ void RE_SetReports(Render *re, ReportList *reports) re->reports = reports; } +static void render_update_depsgraph(Render *re) +{ + Scene *scene = re->scene; + /* TODO(sergey): This doesn't run any callbacks and doesn't do sound update. But we can not use + * BKE_scene_graph_update_for_newframe() because that one builds dependency graph for view layer + * and not for the render pipeline. */ + DEG_evaluate_on_framechange(re->main, re->pipeline_depsgraph, CFRA); +} + +static void render_init_depsgraph(Render *re) +{ + Scene *scene = re->scene; + ViewLayer *view_layer = BKE_view_layer_default_render(re->scene); + + re->pipeline_depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER); + DEG_debug_name_set(re->pipeline_depsgraph, "RENDER PIPELINE"); + + /* Make sure there is a correct evaluated scene pointer. */ + DEG_graph_build_for_render_pipeline(re->pipeline_depsgraph, re->main, scene, view_layer); + + /* Update immediately so we have proper evaluated scene. */ + render_update_depsgraph(re); + + re->pipeline_scene_eval = DEG_get_evaluated_scene(re->pipeline_depsgraph); +} + /* general Blender frame render call */ void RE_RenderFrame(Render *re, Main *bmain, @@ -2093,6 +2116,8 @@ void RE_RenderFrame(Render *re, const RenderData rd = scene->r; MEM_reset_peak_memory(); + render_init_depsgraph(re); + BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE); do_render_all_options(re); @@ -2490,6 +2515,8 @@ void RE_RenderAnim(Render *re, return; } + render_init_depsgraph(re); + if (is_movie) { size_t width, height; int i; @@ -2556,6 +2583,8 @@ void RE_RenderAnim(Render *re, BKE_animsys_evaluate_animdata(NULL, scene, &scene->id, adt, ctime, ADT_RECALC_ALL); } + render_update_depsgraph(re); + /* only border now, todo: camera lens. (ton) */ render_initialize_from_main(re, &rd, bmain, scene, single_layer, camera_override, 1, 0); @@ -2746,6 +2775,11 @@ void RE_CleanAfterRender(Render *re) { /* Destroy the opengl context in the correct thread. */ RE_gl_context_destroy(re); + if (re->pipeline_depsgraph != NULL) { + DEG_graph_free(re->pipeline_depsgraph); + } + re->pipeline_depsgraph = NULL; + re->pipeline_scene_eval = NULL; } /* note; repeated win/disprect calc... solve that nicer, also in compo */ |