[Bf-blender-cvs] [ed37c27] depsgraph_refactor: Depsgraph: Rework the way how layer visibility are handled

Sergey Sharybin noreply at git.blender.org
Mon Feb 23 17:03:56 CET 2015


Commit: ed37c279512fc3fbba204091d2183eb620833c85
Author: Sergey Sharybin
Date:   Mon Feb 23 19:44:20 2015 +0500
Branches: depsgraph_refactor
https://developer.blender.org/rBed37c279512fc3fbba204091d2183eb620833c85

Depsgraph: Rework the way how layer visibility are handled

The main goals of this commit are:

- Get rid of list of IDs which were tagged for update but are not visible
- Make it possible to have proper time dependency re-tags of invisible objects

This change is really quite the same as previous one: just uses ob->recalc
flags to check whether object was updated or not. It might be a bit of an issue
with materials, but they're always "visible", so should not cause any missing
updates.

In any case, we really need to get rid of all this temp sets and arrays, they
might become quite huge in production files.

===================================================================

M	source/blender/depsgraph/DEG_depsgraph.h
M	source/blender/depsgraph/intern/depsgraph.cpp
M	source/blender/depsgraph/intern/depsgraph.h
M	source/blender/depsgraph/intern/depsgraph_build.cpp
M	source/blender/depsgraph/intern/depsgraph_eval.cpp
M	source/blender/depsgraph/intern/depsgraph_tag.cpp
M	source/blender/depsgraph/intern/depsnode.cpp
M	source/blender/depsgraph/intern/depsnode.h

===================================================================

diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index e89312f..c61cd32 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -128,8 +128,7 @@ void DEG_ids_clear_recalc(struct Main *bmain);
 /* Flush updates */
 void DEG_graph_flush_updates(struct Main *bmain,
                              struct EvaluationContext *eval_ctx,
-                             Depsgraph *graph,
-                             const int layers);
+                             Depsgraph *graph);
 
 /* Check if something was changed in the database and inform
  * editors about this.
diff --git a/source/blender/depsgraph/intern/depsgraph.cpp b/source/blender/depsgraph/intern/depsgraph.cpp
index d7e9cd2..a293967 100644
--- a/source/blender/depsgraph/intern/depsgraph.cpp
+++ b/source/blender/depsgraph/intern/depsgraph.cpp
@@ -431,15 +431,6 @@ void Depsgraph::clear_all_nodes()
 	}
 }
 
-/* Layers Visibility -------------------------------------- */
-
-/* Tag a specific invisible node as needing updates when becoming visible. */
-void Depsgraph::add_invisible_entry_tag(OperationDepsNode *node)
-{
-	BLI_assert(node != NULL);
-	invisible_entry_tags.insert(node);
-}
-
 /* ************************************************** */
 /* Public Graph API */
 
diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h
index 2170904..7cc9677 100644
--- a/source/blender/depsgraph/intern/depsgraph.h
+++ b/source/blender/depsgraph/intern/depsgraph.h
@@ -185,22 +185,9 @@ struct Depsgraph {
 
 	/* Layers Visibility .................. */
 
-	/* Tag a specific invisible node as needing updates when becoming visible. */
-	void add_invisible_entry_tag(OperationDepsNode *node);
-
 	/* Visible layers bitfield, used for skipping invisible objects updates. */
 	int layers;
 
-	/* Invisible nodes which have been tagged as "directly modified".
-	 * They're being flushed for update after graph visibility changes.
-	 *
-	 * TODO(sergey): This is a tempotrary solution for until we'll have storage
-	 * associated with the IDs, so we can keep dirty/tagged for update/etc flags
-	 * in there. This would also solve issues with accessing .updated ID flag
-	 * from python.
-	 */
-	EntryTags invisible_entry_tags;
-
 	// XXX: additional stuff like eval contexts, mempools for allocating nodes from, etc.
 };
 
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cpp b/source/blender/depsgraph/intern/depsgraph_build.cpp
index b96f263..c22034d 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cpp
+++ b/source/blender/depsgraph/intern/depsgraph_build.cpp
@@ -539,17 +539,14 @@ static void deg_graph_build_finalize(Depsgraph *graph)
 			if (id->flag & LIB_ID_RECALC_ALL &&
 			    id->flag & LIB_DOIT)
 			{
-				id_node->tag_update(graph);
+				bool do_time = false;
 				if (GS(id->name) == ID_OB) {
 					Object *object = (Object *)id;
 					if (object->recalc & OB_RECALC_TIME) {
-						ComponentDepsNode *anim_comp =
-						        id_node->find_component(DEPSNODE_TYPE_ANIMATION);
-						if (anim_comp != NULL) {
-							anim_comp->tag_update(graph);
-						}
+						do_time = true;
 					}
 				}
+				id_node->tag_update(graph, do_time);
 				id->flag &= ~LIB_DOIT;
 			}
 		}
@@ -796,7 +793,6 @@ void DEG_scene_relations_update(Main *bmain, Scene *scene)
 	graph->clear_all_nodes();
 	graph->operations.clear();
 	graph->entry_tags.clear();
-	graph->invisible_entry_tags.clear();
 
 	/* Build new nodes and relations. */
 	DEG_graph_build_from_scene(graph, bmain, scene);
diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cpp b/source/blender/depsgraph/intern/depsgraph_eval.cpp
index 23033a2..c038f8f 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.cpp
+++ b/source/blender/depsgraph/intern/depsgraph_eval.cpp
@@ -310,7 +310,7 @@ void DEG_evaluate_on_refresh_ex(EvaluationContext *eval_ctx,
 	/* Recursively push updates out to all nodes dependent on this,
 	 * until all affected are tagged and/or scheduled up for eval
 	 */
-	DEG_graph_flush_updates(bmain, eval_ctx, graph, layers);
+	DEG_graph_flush_updates(bmain, eval_ctx, graph);
 
 	calculate_pending_parents(graph, layers);
 
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cpp b/source/blender/depsgraph/intern/depsgraph_tag.cpp
index 8865467..48b4f12 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cpp
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cpp
@@ -231,8 +231,7 @@ typedef std::queue<OperationDepsNode*> FlushQueue;
 /* Flush updates from tagged nodes outwards until all affected nodes are tagged. */
 void DEG_graph_flush_updates(Main *bmain,
                              EvaluationContext *eval_ctx,
-                             Depsgraph *graph,
-                             const int layers)
+                             Depsgraph *graph)
 {
 	/* sanity check */
 	if (graph == NULL)
@@ -250,14 +249,8 @@ void DEG_graph_flush_updates(Main *bmain,
 	{
 		OperationDepsNode *node = *it;
 		IDDepsNode *id_node = node->owner->owner;
-		if (id_node->layers & layers) {
-			queue.push(node);
-			deg_editors_id_update(bmain, id_node->id);
-		}
-		else {
-			node->flag &= ~DEPSOP_FLAG_NEEDS_UPDATE;
-			graph->add_invisible_entry_tag(node);
-		}
+		queue.push(node);
+		deg_editors_id_update(bmain, id_node->id);
 	}
 
 	while (!queue.empty()) {
@@ -277,10 +270,27 @@ void DEG_graph_flush_updates(Main *bmain,
 			DepsRelation *rel = *it;
 			OperationDepsNode *to_node = (OperationDepsNode *)rel->to;
 			IDDepsNode *id_node = to_node->owner->owner;
-
-			if ((id_node->layers & layers) != 0 &&
-			    (to_node->flag & DEPSOP_FLAG_NEEDS_UPDATE) == 0)
-			{
+			if ((to_node->flag & DEPSOP_FLAG_NEEDS_UPDATE) == 0) {
+				ID *id = id_node->id;
+				/* This code is used to preserve those areas which does direct
+				 * object update,
+				 *
+				 * Plus it ensures visibility changes and relations and layers
+				 * visibility update has proper flags to work with.
+				 */
+				if (GS(id->name) == ID_OB) {
+					Object *object = (Object *)id;
+					ComponentDepsNode *comp_node = to_node->owner;
+					if (comp_node->type == DEPSNODE_TYPE_ANIMATION) {
+						object->recalc |= OB_RECALC_TIME;
+					}
+					else if (comp_node->type == DEPSNODE_TYPE_TRANSFORM) {
+						object->recalc |= OB_RECALC_OB;
+					}
+					else {
+						object->recalc |= OB_RECALC_DATA;
+					}
+				}
 				to_node->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
 				queue.push(to_node);
 				deg_editors_id_update(bmain, id_node->id);
@@ -338,22 +348,6 @@ void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
 		graph->layers = (1 << 20) - 1;
 	}
 	if (old_layers != graph->layers) {
-		/* Re-tag nodes which became visible. */
-		for (Depsgraph::EntryTags::const_iterator it = graph->invisible_entry_tags.begin();
-		     it != graph->invisible_entry_tags.end();
-		     ++it)
-		{
-			OperationDepsNode *node = *it;
-			/* TODO(sergey): For the simplicity we're trying to re-schedule
-			 * all the nodes, regardless of their layers visibility.
-			 *
-			 * In the future when storage for such flags becomes more permanent
-			 * we'll optimize this out.
-			 */
-			node->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
-			graph->add_entry_tag(node);
-		}
-		graph->invisible_entry_tags.clear();
 		/* Tag all objects which becomes visible (or which becomes needed for dependencies)
 		 * for recalc.
 		 *
@@ -366,9 +360,26 @@ void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
 		{
 			OperationDepsNode *node = *it;
 			IDDepsNode *id_node = node->owner->owner;
-			if ((id_node->layers & scene->lay_updated) == 0) {
+			ID *id = id_node->id;
+			if ((id->flag & LIB_ID_RECALC_ALL) != 0 ||
+			    (id_node->layers & scene->lay_updated) == 0)
+			{
 				id_node->tag_update(graph);
 			}
+			/* A bit of magic: if object->recalc is set it means somebody tagged
+			 * it for update. If corresponding ID recalc flags are zero it means
+			 * graph has been evaluated after that and the recalc was skipped
+			 * because of visibility check.
+			 */
+			if (GS(id->name) == ID_OB) {
+				Object *object = (Object *)id;
+				if ((id->flag & LIB_ID_RECALC_ALL) == 0 &&
+				    (object->recalc & OB_RECALC_ALL) != 0)
+				{
+					id_node->tag_update(graph,
+					                    (object->recalc & OB_RECALC_TIME) != 0);
+				}
+			}
 		}
 	}
 	scene->lay_updated |= graph->layers;
diff --git a/source/blender/depsgraph/intern/depsnode.cpp b/source/blender/depsgraph/intern/depsnode.cpp
index c618d54..0e52868 100644
--- a/source/blender/depsgraph/intern/depsnode.cpp
+++ b/source/blender/depsgraph/intern/depsnode.cpp
@@ -225,7 +225,7 @@ void IDDepsNode::clear_components()
 	components.clear();
 }
 
-void IDDepsNode::tag_update(Depsgraph *graph)
+void IDDepsNode::tag_update(Depsgraph *graph, bool do_time)
 {
 	for (ComponentMap::const_iterator it = components.begin();
 	     it != components.end();
@@ -235,7 +235,7 @@ void IDDepsNode::tag_update(Depsgraph *graph)
 		/* Animation component should only be tagged for update by the time
 		 * updates or by tagging the animation itself.
 		 */
-		if (comp_node->type != DEPSNODE_TYPE_ANIMATION) {
+		if (do_time || comp_node->type != DEPSNODE_TYPE_ANIMATION) {
 			comp_node->tag_update(graph);
 		}
 	}
diff --git a/source/blender/depsgraph/intern/depsnode.h b/source/blender/depsgraph/intern/depsnode.h
index 1dd1379..4dcc837 100644
--- a/source/blender/depsgraph/intern/depsnode.h
+++ b/source/blender/depsgraph/intern/depsnode.h
@@ -180,7 +180,7 @@ struct IDDepsNode : public DepsNode {
 	void remove_component(eDepsNode_Type type, const string &name = "");
 	void clear_components();
 
-	void tag_update(Depsgraph *graph);
+	void tag_update(Depsgraph *graph, bool do_time = false);
 
 	/* ID Block referenced. */
 	ID *id;




More information about the Bf-blender-cvs mailing list