From 263148dbacc496b922a46397fd94e558e0d1e9ac Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 20 Aug 2020 16:29:34 +0200 Subject: Depsgraph: refactor tagging after time changes This reverts {rB1693a5efe91999b60b3dc0bdff727473b3bd00bb} and implements an alternative solution. The old patch had the problem that the depsgraph would always evaluate at the current frame of the original scene (even when `DEG_evaluate_on_framechange` was used). Now it is possible to evaluate the depsgraph at a specific frame without having to change the original scene. Reviewers: sergey, sybren Differential Revision: https://developer.blender.org/D8616 --- source/blender/depsgraph/DEG_depsgraph.h | 8 +++-- source/blender/depsgraph/intern/depsgraph.cc | 6 +++- source/blender/depsgraph/intern/depsgraph.h | 5 +-- source/blender/depsgraph/intern/depsgraph_eval.cc | 37 +++++++++++----------- source/blender/depsgraph/intern/depsgraph_tag.cc | 29 +++++++++-------- .../depsgraph/intern/eval/deg_eval_flush.cc | 11 +++---- .../blender/depsgraph/intern/node/deg_node_time.cc | 10 +++++- .../blender/depsgraph/intern/node/deg_node_time.h | 4 +++ source/blender/editors/screen/screen_edit.c | 2 +- source/blender/makesdna/DNA_ID.h | 4 --- 10 files changed, 64 insertions(+), 52 deletions(-) (limited to 'source/blender') diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h index 8f33e9f480d..0ded511b8f8 100644 --- a/source/blender/depsgraph/DEG_depsgraph.h +++ b/source/blender/depsgraph/DEG_depsgraph.h @@ -127,6 +127,12 @@ void DEG_graph_id_tag_update(struct Main *bmain, struct ID *id, int flag); +/* Tag all dependency graphs when time has changed. */ +void DEG_time_tag_update(struct Main *bmain); + +/* Tag a dependency graph when time has changed. */ +void DEG_graph_time_tag_update(struct Depsgraph *depsgraph); + /* Mark a particular datablock type as having changing. This does * not cause any updates but is used by external render engines to detect if for * example a datablock was removed. */ @@ -155,8 +161,6 @@ void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime); /* Data changed recalculation entry point. */ void DEG_evaluate_on_refresh(Depsgraph *graph); -bool DEG_needs_eval(Depsgraph *graph); - /* Editors Integration -------------------------- */ /* Mechanism to allow editors to be informed of depsgraph updates, diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 4a9c840dd9f..c0feab2262a 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -63,7 +63,6 @@ namespace deg { Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode) : time_source(nullptr), need_update(true), - need_update_time(false), bmain(bmain), scene(scene), view_layer(view_layer), @@ -103,6 +102,11 @@ TimeSourceNode *Depsgraph::find_time_source() const return time_source; } +void Depsgraph::tag_time_source() +{ + time_source->tag_update(this, DEG_UPDATE_SOURCE_TIME); +} + IDNode *Depsgraph::find_id_node(const ID *id) const { return id_hash.lookup_default(id, nullptr); diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index ea579a4958e..e03846f81e2 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -68,6 +68,7 @@ struct Depsgraph { TimeSourceNode *add_time_source(); TimeSourceNode *find_time_source() const; + void tag_time_source(); IDNode *find_id_node(const ID *id) const; IDNode *add_id_node(ID *id, ID *id_cow_hint = nullptr); @@ -121,10 +122,6 @@ struct Depsgraph { /* Nodes which have been tagged as "directly modified". */ Set entry_tags; - /* Special entry tag for time source. Allows to tag invisible dependency graphs for update when - * scene frame changes, so then when dependency graph becomes visible it is on a proper state. */ - bool need_update_time; - /* Convenience Data ................... */ /* XXX: should be collected after building (if actually needed?) */ diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index 0c116f5863c..1ad3fdbc9da 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -47,38 +47,37 @@ namespace deg = blender::deg; -/* Evaluate all nodes tagged for updating. */ -void DEG_evaluate_on_refresh(Depsgraph *graph) +static void deg_flush_updates_and_refresh(deg::Depsgraph *deg_graph) { - deg::Depsgraph *deg_graph = reinterpret_cast(graph); - deg_graph->ctime = BKE_scene_frame_get(deg_graph->scene); - /* Update time in scene. */ + /* Update the time on the cow scene. */ if (deg_graph->scene_cow) { BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime); } + deg::deg_graph_flush_updates(deg_graph); deg::deg_evaluate_on_refresh(deg_graph); - deg_graph->need_update_time = false; } -/* Frame-change happened for root scene that graph belongs to. */ -void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime) +/* Evaluate all nodes tagged for updating. */ +void DEG_evaluate_on_refresh(Depsgraph *graph) { deg::Depsgraph *deg_graph = reinterpret_cast(graph); - deg_graph->ctime = ctime; - deg_graph->need_update_time = true; - deg::deg_graph_flush_updates(deg_graph); - /* Update time in scene. */ - if (deg_graph->scene_cow) { - BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime); + const Scene *scene = DEG_get_input_scene(graph); + const float ctime = BKE_scene_frame_get(scene); + + if (ctime != deg_graph->ctime) { + deg_graph->tag_time_source(); + deg_graph->ctime = ctime; } - /* Perform recalculation updates. */ - deg::deg_evaluate_on_refresh(deg_graph); - deg_graph->need_update_time = false; + + deg_flush_updates_and_refresh(deg_graph); } -bool DEG_needs_eval(Depsgraph *graph) +/* Frame-change happened for root scene that graph belongs to. */ +void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime) { deg::Depsgraph *deg_graph = reinterpret_cast(graph); - return !deg_graph->entry_tags.is_empty() || deg_graph->need_update_time; + deg_graph->tag_time_source(); + deg_graph->ctime = ctime; + deg_flush_updates_and_refresh(deg_graph); } diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 4a2d47f9379..868f88d8fcd 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -66,6 +66,7 @@ #include "intern/node/deg_node_factory.h" #include "intern/node/deg_node_id.h" #include "intern/node/deg_node_operation.h" +#include "intern/node/deg_node_time.h" namespace deg = blender::deg; @@ -230,9 +231,6 @@ void depsgraph_tag_to_component_opcode(const ID *id, case ID_RECALC_SOURCE: *component_type = NodeType::PARAMETERS; break; - case ID_RECALC_TIME: - BLI_assert(!"Should be handled outside of this function"); - break; case ID_RECALC_ALL: case ID_RECALC_PSYS_ALL: BLI_assert(!"Should not happen"); @@ -372,12 +370,6 @@ void graph_id_tag_update_single_flag(Main *bmain, } return; } - if (tag == ID_RECALC_TIME) { - if (graph != nullptr) { - graph->need_update_time = true; - } - return; - } /* Get description of what is to be tagged. */ NodeType component_type; OperationCode operation_code; @@ -462,8 +454,8 @@ const char *update_source_as_string(eUpdateSource source) int deg_recalc_flags_for_legacy_zero() { - return ID_RECALC_ALL & ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION | ID_RECALC_SOURCE | - ID_RECALC_TIME | ID_RECALC_EDITORS); + return ID_RECALC_ALL & + ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION | ID_RECALC_SOURCE | ID_RECALC_EDITORS); } int deg_recalc_flags_effective(Depsgraph *graph, int flags) @@ -734,8 +726,6 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag) return "AUDIO"; case ID_RECALC_PARAMETERS: return "PARAMETERS"; - case ID_RECALC_TIME: - return "TIME"; case ID_RECALC_SOURCE: return "SOURCE"; case ID_RECALC_ALL: @@ -772,6 +762,19 @@ void DEG_graph_id_tag_update(struct Main *bmain, deg::graph_id_tag_update(bmain, graph, id, flag, deg::DEG_UPDATE_SOURCE_USER_EDIT); } +void DEG_time_tag_update(struct Main *bmain) +{ + for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) { + DEG_graph_time_tag_update(reinterpret_cast<::Depsgraph *>(depsgraph)); + } +} + +void DEG_graph_time_tag_update(struct Depsgraph *depsgraph) +{ + deg::Depsgraph *deg_graph = reinterpret_cast(depsgraph); + deg_graph->tag_time_source(); +} + /* Mark a particular datablock type as having changing. */ void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type) { diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index dea23c9f96d..5ccdcbec858 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -357,14 +357,9 @@ void deg_graph_flush_updates(Depsgraph *graph) BLI_assert(graph != nullptr); Main *bmain = graph->bmain; + graph->time_source->flush_update_tag(graph); + /* Nothing to update, early out. */ - if (graph->need_update_time) { - const Scene *scene_orig = graph->scene; - const float ctime = BKE_scene_frame_get(scene_orig); - TimeSourceNode *time_source = graph->find_time_source(); - graph->ctime = ctime; - time_source->tag_update(graph, DEG_UPDATE_SOURCE_TIME); - } if (graph->entry_tags.is_empty()) { return; } @@ -412,6 +407,8 @@ void deg_graph_clear_tags(Depsgraph *graph) } /* Clear any entry tags which haven't been flushed. */ graph->entry_tags.clear(); + + graph->time_source->tagged_for_update = false; } } // namespace deg diff --git a/source/blender/depsgraph/intern/node/deg_node_time.cc b/source/blender/depsgraph/intern/node/deg_node_time.cc index af931fbae34..4f7f70fef33 100644 --- a/source/blender/depsgraph/intern/node/deg_node_time.cc +++ b/source/blender/depsgraph/intern/node/deg_node_time.cc @@ -31,8 +31,16 @@ namespace blender { namespace deg { -void TimeSourceNode::tag_update(Depsgraph *graph, eUpdateSource /*source*/) +void TimeSourceNode::tag_update(Depsgraph * /*graph*/, eUpdateSource /*source*/) { + tagged_for_update = true; +} + +void TimeSourceNode::flush_update_tag(Depsgraph *graph) +{ + if (!tagged_for_update) { + return; + } for (Relation *rel : outlinks) { Node *node = rel->to; node->tag_update(graph, DEG_UPDATE_SOURCE_TIME); diff --git a/source/blender/depsgraph/intern/node/deg_node_time.h b/source/blender/depsgraph/intern/node/deg_node_time.h index fe17684abb0..79ad92f336f 100644 --- a/source/blender/depsgraph/intern/node/deg_node_time.h +++ b/source/blender/depsgraph/intern/node/deg_node_time.h @@ -30,10 +30,14 @@ namespace deg { /* Time Source Node. */ struct TimeSourceNode : public Node { + bool tagged_for_update = false; + // TODO: evaluate() operation needed virtual void tag_update(Depsgraph *graph, eUpdateSource source) override; + void flush_update_tag(Depsgraph *graph); + DEG_DEPSNODE_DECLARE; }; diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index dbf84cad80b..a2509c7a330 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1576,7 +1576,7 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph) { Scene *scene = DEG_get_input_scene(depsgraph); - DEG_id_tag_update_ex(bmain, &scene->id, ID_RECALC_TIME); + DEG_time_tag_update(bmain); #ifdef DURIAN_CAMERA_SWITCH void *camera = BKE_scene_camera_switch_find(scene); diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index feda4ba43eb..e16a22f5459 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -686,10 +686,6 @@ typedef enum IDRecalcFlag { ID_RECALC_PARAMETERS = (1 << 21), - /* Makes it so everything what depends on time. - * Basically, the same what changing frame in a timeline will do. */ - ID_RECALC_TIME = (1 << 22), - /* Input has changed and datablock is to be reload from disk. * Applies to movie clips to inform that copy-on-written version is to be refreshed for the new * input file or for color space changes. */ -- cgit v1.2.3