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
path: root/source
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2019-05-20 16:14:10 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2019-05-23 17:22:25 +0300
commitb432209f63f873a025a7f4c3a79aa1d697dc9b98 (patch)
treedbba9e8605777f91b1db73aa821a18647464819f /source
parent0ec6fa782b63a05e52df2d013ffbf547b178ffd1 (diff)
Render: Use dependency graph for compositor/sequencer
This change makes it so a minimal dependency graph which only includes compositor and sequencer is built for the render pipeline purposes. Tricky part here is that it's only compositor itself and sequencer who to use this dependency graph and IDs from it. Render engines are still to be provided original IDs because: - They will create dependency graph for the given scene, and currently it is not possible to create dependency graph from CoW scene. - IDs from the compositor/sequencer dependency graph are "stripped", as in, they wouldn't have all view layers, collections or objects required for proper final render. This creates annoying mess of mixing evaluated and original scene access in various parts of the pipeline. Fixes T63927: Compositing nodes - drivers don't really work Reviewers: brecht Maniphest Tasks: T63927 Differential Revision: https://developer.blender.org/D4911
Diffstat (limited to 'source')
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_build.h11
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_map.h6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc30
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc23
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc17
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc20
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc7
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc3
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc86
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc24
-rw-r--r--source/blender/render/intern/include/render_types.h5
-rw-r--r--source/blender/render/intern/source/pipeline.c60
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(&deg_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(&deg_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 */