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:
-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 */