[Bf-blender-cvs] [414cc821d8d] blender2.8: Depsgraph: Initial implementation of more granular tagging

Sergey Sharybin noreply at git.blender.org
Wed Jul 19 17:33:47 CEST 2017


Commit: 414cc821d8d0e3156a3c1057ed382c32cf4b5031
Author: Sergey Sharybin
Date:   Tue Jul 18 15:42:53 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB414cc821d8d0e3156a3c1057ed382c32cf4b5031

Depsgraph: Initial implementation of more granular tagging

This commit makes it so that only ID components which correspond to the tag
flag are tagged for update (previously the whole ID would have been updated
in the most of cases).

This allows us to have more granular tag flags and prevent tagging of things
we don't want to be tagged.

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

M	source/blender/depsgraph/DEG_depsgraph.h
M	source/blender/depsgraph/intern/depsgraph_intern.h
M	source/blender/depsgraph/intern/depsgraph_tag.cc
M	source/blender/depsgraph/intern/nodes/deg_node.cc

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

diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index 2e7e1cd6ff5..76681e6611c 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -136,11 +136,6 @@ void DEG_graph_on_visible_update(struct Main *bmain, struct Scene *scene);
 /* Update all dependency graphs when visible scenes/layers changes. */
 void DEG_on_visible_update(struct Main *bmain, const bool do_time);
 
-/* Tag node(s) associated with changed data for later updates */
-void DEG_graph_id_tag_update(struct Main *bmain,
-                             Depsgraph *graph,
-                             struct ID *id);
-
 /* Tag given ID for an update in all the dependency graphs. */
 enum {
 	/* Object transformation changed, corresponds to OB_RECALC_OB. */
diff --git a/source/blender/depsgraph/intern/depsgraph_intern.h b/source/blender/depsgraph/intern/depsgraph_intern.h
index ad55c219dc7..5ab090f3b3d 100644
--- a/source/blender/depsgraph/intern/depsgraph_intern.h
+++ b/source/blender/depsgraph/intern/depsgraph_intern.h
@@ -118,11 +118,18 @@ void deg_editors_scene_update(struct Main *bmain, struct Scene *scene, bool upda
 void lib_id_recalc_tag(struct Main *bmain, struct ID *id);
 void lib_id_recalc_data_tag(struct Main *bmain, struct ID *id);
 
-#define DEG_DEBUG_PRINTF(...) \
-	do { \
-		if (G.debug & G_DEBUG_DEPSGRAPH) { \
-			fprintf(stderr, __VA_ARGS__); \
-		} \
+#define DEG_DEBUG_PRINTF(...)               \
+	do {                                    \
+		if (G.debug & G_DEBUG_DEPSGRAPH) {  \
+			fprintf(stderr, __VA_ARGS__);   \
+			fflush(stderr);                 \
+		}                                   \
+	} while (0)
+
+#define DEG_ERROR_PRINTF(...)               \
+	do {                                    \
+		fprintf(stderr, __VA_ARGS__);       \
+		fflush(stderr);                     \
 	} while (0)
 
 }  // namespace DEG
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index 17d7cbf5187..07593cc55c8 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -90,67 +90,168 @@ namespace {
 
 void lib_id_recalc_tag_flag(Main *bmain, ID *id, int flag)
 {
+	/* This bit of code ensures legacy object->recalc flags are still filled in
+	 * the same way as it was expected with the old dependency graph.
+	 *
+	 * This is because some areas like motion paths and likely some other
+	 * physics baking process are doing manual scene update on all the frames,
+	 * trying to minimize number of updates.
+	 *
+	 * But this flag will also let us to re-construct entry nodes for update
+	 * after relations update and after layer visibility changes.
+	 */
 	if (flag) {
-		/* This bit of code ensures legacy object->recalc flags
-		 * are still filled in the same way as it was expected
-		 * with the old dependency graph.
-		 *
-		 * This is because some areas like motion paths and likely
-		 * some other physics baking process are doing manual scene
-		 * update on all the frames, trying to minimize number of
-		 * updates.
-		 *
-		 * But this flag will also let us to re-construct entry
-		 * nodes for update after relations update and after layer
-		 * visibility changes.
-		 */
 		short idtype = GS(id->name);
 		if (idtype == ID_OB) {
 			Object *object = (Object *)id;
 			object->recalc |= (flag & OB_RECALC_ALL);
 		}
-
-		if (flag & OB_RECALC_OB)
+		if (flag & OB_RECALC_OB) {
 			lib_id_recalc_tag(bmain, id);
-		if (flag & (OB_RECALC_DATA | PSYS_RECALC))
+		}
+		if (flag & (OB_RECALC_DATA | PSYS_RECALC)) {
 			lib_id_recalc_data_tag(bmain, id);
+		}
 	}
 	else {
 		lib_id_recalc_tag(bmain, id);
 	}
 }
 
+/* Special tagging  */
+void id_tag_update_special_zero_flag(Depsgraph *graph, IDDepsNode *id_node)
+{
+	/* NOTE: Full ID node update for now, need to minimize that i9n the future. */
+	id_node->tag_update(graph);
+}
+
+/* Tag corresponding to OB_RECALC_OB. */
+void id_tag_update_object_transform(Depsgraph *graph, IDDepsNode *id_node)
+{
+	ComponentDepsNode *transform_comp =
+	        id_node->find_component(DEG_NODE_TYPE_TRANSFORM);
+	if (transform_comp == NULL) {
+		DEG_ERROR_PRINTF("ERROR: Unable to find transform component for %s\n",
+		                 id_node->id_orig->name);
+		BLI_assert(!"This is not supposed to happen!");
+		return;
+	}
+	transform_comp->tag_update(graph);
+}
+
+/* Tag corresponding to OB_RECALC_DATA. */
+void id_tag_update_object_data(Depsgraph *graph, IDDepsNode *id_node)
+{
+	const short idtype = GS(id_node->id_orig->name);
+	ComponentDepsNode *data_comp = NULL;
+	switch (idtype) {
+		case ID_OB:
+		{
+			const Object *object = (Object *)id_node->id_orig;
+			switch (object->type) {
+				case OB_MESH:
+				case OB_CURVE:
+				case OB_SURF:
+				case OB_FONT:
+					data_comp = id_node->find_component(DEG_NODE_TYPE_GEOMETRY);
+					break;
+				case OB_ARMATURE:
+					data_comp = id_node->find_component(DEG_NODE_TYPE_EVAL_POSE);
+					break;
+				/* TODO(sergey): More cases here? */
+			}
+			break;
+		}
+		case ID_ME:
+			data_comp = id_node->find_component(DEG_NODE_TYPE_GEOMETRY);
+			break;
+	}
+	if (data_comp == NULL) {
+		DEG_ERROR_PRINTF("ERROR: Unable to find data component for %s\n",
+		                 id_node->id_orig->name);
+		BLI_assert(!"This is not supposed to happen!");
+		return;
+	}
+	data_comp->tag_update(graph);
+}
+
+/* Tag corresponding to OB_RECALC_TIME. */
+void id_tag_update_object_time(Depsgraph *graph, IDDepsNode *id_node)
+{
+	ComponentDepsNode *animation_comp =
+	        id_node->find_component(DEG_NODE_TYPE_ANIMATION);
+	if (animation_comp == NULL) {
+		/* It's not necessarily we've got animation component in cases when
+		 * we are tagging for time updates.
+		 */
+		return;
+	}
+	animation_comp->tag_update(graph);
+	/* TODO(sergey): More components to tag here? */
+}
+
 #ifdef WITH_COPY_ON_WRITE
-void id_tag_copy_on_write_update(Main *bmain, Depsgraph *graph, ID *id)
+/* Tag corresponding to DEG_TAG_COPY_ON_WRITE. */
+void id_tag_update_copy_on_write(Depsgraph *graph, IDDepsNode *id_node)
 {
-	lib_id_recalc_tag(bmain, id);
-	Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
-	IDDepsNode *id_node = deg_graph->find_id_node(id);
 	ComponentDepsNode *cow_comp =
-	        id_node->find_component(DEG::DEG_NODE_TYPE_COPY_ON_WRITE);
+	        id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
 	OperationDepsNode *cow_node = cow_comp->get_entry_operation();
-	cow_node->tag_update(deg_graph);
+	cow_node->tag_update(graph);
 	cow_node->flag |= DEPSOP_FLAG_SKIP_FLUSH;
 }
 #endif
 
-}  /* namespace */
-
-}  // namespace DEG
+void deg_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, int flag)
+{
+	Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
+	IDDepsNode *id_node = deg_graph->find_id_node(id);
+	/* Make sure legacy flags are all nicely update. */
+	lib_id_recalc_tag_flag(bmain, id, flag);
+	if (id_node == NULL) {
+		/* Shouldn't happen, but better be sure here. */
+		return;
+	}
+	/* Tag components based on flags. */
+	if (flag == 0) {
+		id_tag_update_special_zero_flag(graph, id_node);
+		return;
+	}
+	if (flag & OB_RECALC_OB) {
+		id_tag_update_object_transform(graph, id_node);
+	}
+	if (flag & OB_RECALC_DATA) {
+		id_tag_update_object_data(graph, id_node);
+	}
+	if (flag & OB_RECALC_TIME) {
+		id_tag_update_object_time(graph, id_node);
+	}
+#ifdef WITH_COPY_ON_WRITE
+	if (flag & DEG_TAG_COPY_ON_WRITE) {
+		id_tag_update_copy_on_write(graph, id_node);
+	}
+#endif
+	// node->tag_update(deg_graph);
+}
 
-/* Tag all nodes in ID-block for update.
- * This is a crude measure, but is most convenient for old code.
- */
-void DEG_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id)
+void deg_id_tag_update(Main *bmain, ID *id, int flag)
 {
-	DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
-	DEG::IDDepsNode *node = deg_graph->find_id_node(id);
-	DEG::lib_id_recalc_tag(bmain, id);
-	if (node != NULL) {
-		node->tag_update(deg_graph);
+	lib_id_recalc_tag_flag(bmain, id, flag);
+	for (Scene *scene = (Scene *)bmain->scene.first;
+	     scene != NULL;
+	     scene = (Scene *)scene->id.next)
+	{
+		if (scene->depsgraph_legacy != NULL) {
+			Depsgraph *graph = (Depsgraph *)scene->depsgraph_legacy;
+			deg_graph_id_tag_update(bmain, graph, id, flag);
+		}
 	}
 }
 
+}  /* namespace */
+
+}  // namespace DEG
+
 /* Tag given ID for an update in all the dependency graphs. */
 void DEG_id_tag_update(ID *id, int flag)
 {
@@ -164,42 +265,7 @@ void DEG_id_tag_update_ex(Main *bmain, ID *id, int flag)
 		return;
 	}
 	DEG_DEBUG_PRINTF("%s: id=%s flag=%d\n", __func__, id->name, flag);
-	DEG::lib_id_recalc_tag_flag(bmain, id, flag);
-	for (Scene *scene = (Scene *)bmain->scene.first;
-	     scene != NULL;
-	     scene = (Scene *)scene->id.next)
-	{
-		if (scene->depsgraph_legacy) {
-			Depsgraph *graph = scene->depsgraph_legacy;
-			if (flag == 0) {
-				/* TODO(sergey): Currently blender is still tagging IDs
-				 * for recalc just using flag=0. This isn't totally correct
-				 * but we'd better deal with such cases and don't fail.
-				 */
-				DEG_graph_id_tag_update(bmain, graph, id);
-				continue;
-			}
-			if (flag & OB_RECALC_DATA && GS(id->name) == ID_OB) {
-				Object *object = (Object *)id;
-				if (object->data != NULL) {
-					DEG_graph_id_tag_update(bmain,
-					                        graph,
-					                        (ID *)object->data);
-				}
-			}
-			if (flag & (OB_RECALC_OB | OB_RECALC_DATA)) {
-				DEG_graph_id_tag_update(bmain, graph, id);
-			}
-			else if (flag & OB_RECALC_TIME) {
-				DEG_graph_id_tag_update(bmain, graph, id);
-			}
-			else if (flag & DEG_TAG_COPY_ON_WRITE) {
-#ifdef WITH_COPY_ON_WRITE
-				id_tag_copy_on_write_update(bmain, graph, id);
-#endif
-			}
-		}
-	}
+	DEG::deg_id_tag_update(bmain, id, flag);
 }
 
 /* Tag given ID type for update. */
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc
index 07aae7e15c4..a652cf284b1 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node.cc
@@ -128,8 +128,8 @@ IDDepsNode::C

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list