[Bf-blender-cvs] [eadfd901ad] master: Optimization: pass Main to BKE_library_foreach_ID_link() and use its relations.

Bastien Montagne noreply at git.blender.org
Mon Jan 30 22:34:54 CET 2017


Commit: eadfd901ad7c3af4d85b05618352a96a9b4ca9de
Author: Bastien Montagne
Date:   Mon Jan 30 21:41:44 2017 +0100
Branches: master
https://developer.blender.org/rBeadfd901ad7c3af4d85b05618352a96a9b4ca9de

Optimization: pass Main to BKE_library_foreach_ID_link() and use its relations.

Use Main->relations in BKE_library_foreach_ID_link(), when possible
(i.e. IDWALK_READONLY is set), and if the data is available of course.

This is quite minor optimization, no sensible improvements are expected,
but does not hurt either to avoid potentially tens of looping over e.g.
objects constraints and modifiers, or heap of drivers...

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

M	source/blender/blenkernel/BKE_library.h
M	source/blender/blenkernel/BKE_library_query.h
M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenkernel/intern/library.c
M	source/blender/blenkernel/intern/library_query.c
M	source/blender/blenkernel/intern/library_remap.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/editors/object/object_relations.c
M	source/blender/python/intern/bpy_rna_id_collection.c
M	source/blender/windowmanager/intern/wm_operators.c

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

diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 34035673f8..72ae2cf4ef 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -86,7 +86,7 @@ bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const boo
 bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
 bool id_copy(struct Main *bmain, struct ID *id, struct ID **newid, bool test);
 void id_sort_by_name(struct ListBase *lb, struct ID *id);
-void BKE_id_expand_local(struct ID *id);
+void BKE_id_expand_local(struct Main *bmain, struct ID *id);
 void BKE_id_copy_ensure_local(struct Main *bmain, struct ID *old_id, struct ID *new_id);
 
 bool new_id(struct ListBase *lb, struct ID *id, const char *name);
diff --git a/source/blender/blenkernel/BKE_library_query.h b/source/blender/blenkernel/BKE_library_query.h
index c80eb7b076..693d5e9a28 100644
--- a/source/blender/blenkernel/BKE_library_query.h
+++ b/source/blender/blenkernel/BKE_library_query.h
@@ -80,7 +80,8 @@ enum {
 };
 
 /* Loop over all of the ID's this datablock links to. */
-void BKE_library_foreach_ID_link(struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag);
+void BKE_library_foreach_ID_link(
+        struct Main *bmain, struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag);
 void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, const int cd_flag);
 
 int BKE_library_ID_use_ID(struct ID *id_user, struct ID *id_used);
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 0d509ecea0..57b707a31d 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -239,7 +239,7 @@ void BKE_brush_make_local(Main *bmain, Brush *brush, const bool lib_local)
 	if (lib_local || is_local) {
 		if (!is_lib) {
 			id_clear_lib_data(bmain, &brush->id);
-			BKE_id_expand_local(&brush->id);
+			BKE_id_expand_local(bmain, &brush->id);
 
 			/* enable fake user by default */
 			id_fake_user_set(&brush->id);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index bb426ac027..3f75bb8ec6 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -293,9 +293,9 @@ static int id_expand_local_callback(
 /**
  * Expand ID usages of given id as 'extern' (and no more indirect) linked data. Used by ID copy/make_local functions.
  */
-void BKE_id_expand_local(ID *id)
+void BKE_id_expand_local(Main *bmain, ID *id)
 {
-	BKE_library_foreach_ID_link(id, id_expand_local_callback, NULL, 0);
+	BKE_library_foreach_ID_link(bmain, id, id_expand_local_callback, NULL, IDWALK_READONLY);
 }
 
 /**
@@ -304,7 +304,7 @@ void BKE_id_expand_local(ID *id)
 void BKE_id_copy_ensure_local(Main *bmain, ID *old_id, ID *new_id)
 {
 	if (ID_IS_LINKED_DATABLOCK(old_id)) {
-		BKE_id_expand_local(new_id);
+		BKE_id_expand_local(bmain, new_id);
 		BKE_id_lib_local_paths(bmain, old_id->lib, new_id);
 	}
 }
@@ -331,7 +331,7 @@ void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, c
 	if (lib_local || is_local) {
 		if (!is_lib) {
 			id_clear_lib_data_ex(bmain, id, id_in_mainlist);
-			BKE_id_expand_local(id);
+			BKE_id_expand_local(bmain, id);
 		}
 		else {
 			ID *id_new;
@@ -1329,7 +1329,7 @@ void BKE_main_relations_create(Main *bmain)
 
 	for (a = set_listbasepointers(bmain, lbarray); a--; ) {
 		for (id = lbarray[a]->first; id; id = id->next) {
-			BKE_library_foreach_ID_link(id, main_relations_create_cb, bmain->relations, IDWALK_READONLY);
+			BKE_library_foreach_ID_link(NULL, id, main_relations_create_cb, bmain->relations, IDWALK_READONLY);
 		}
 	}
 }
@@ -1777,7 +1777,7 @@ void BKE_library_make_local(
 			 * some indirect usages. So instead of making a copy that se'll likely get rid of later, directly make
 			 * that data block local. Saves a tremendous amount of time with complex scenes... */
 			id_clear_lib_data_ex(bmain, id, true);
-			BKE_id_expand_local(id);
+			BKE_id_expand_local(bmain, id);
 			id->tag &= ~LIB_TAG_DOIT;
 		}
 		else {
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 28f66b5279..03c4b80335 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -282,7 +282,7 @@ static void library_foreach_ID_as_subdata_link(
 		}
 	}
 	else {
-		BKE_library_foreach_ID_link(id, callback, user_data, flag);
+		BKE_library_foreach_ID_link(NULL, id, callback, user_data, flag);
 	}
 
 	FOREACH_FINALIZE_VOID;
@@ -293,7 +293,7 @@ static void library_foreach_ID_as_subdata_link(
  *
  * \note: May be extended to be recursive in the future.
  */
-void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
+void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
 {
 	LibraryForeachIDData data;
 	int i;
@@ -321,10 +321,22 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
 #define CALLBACK_INVOKE(check_id_super, cb_flag) \
 	FOREACH_CALLBACK_INVOKE(&data, check_id_super, cb_flag)
 
-	do {
+	for (; id != NULL; id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL) {
 		data.self_id = id;
 		data.cd_flag = ID_IS_LINKED_DATABLOCK(id) ? IDWALK_INDIRECT_USAGE : 0;
 
+		if (bmain != NULL && bmain->relations != NULL && (flag & IDWALK_READONLY)) {
+			/* Note that this is minor optimization, even in worst cases (like id being an object with lots of
+			 * drivers and constraints and modifiers, or material etc. with huge node tree),
+			 * but we might as well use it (Main->relations is always assumed valid, it's responsability of code
+			 * creating it to free it, especially if/when it starts modifying Main database). */
+			MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->id_user_to_used, id);
+			for (; entry != NULL; entry = entry->next) {
+				FOREACH_CALLBACK_INVOKE_ID_PP(&data, entry->id_pointer, entry->usage_flag);
+			}
+			continue;
+		}
+
 		AnimData *adt = BKE_animdata_from_id(id);
 		if (adt) {
 			library_foreach_animationData(&data, adt);
@@ -899,7 +911,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
 				break;
 
 		}
-	} while ((id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL));
+	}
 
 FOREACH_FINALIZE:
 	if (data.ids_handled) {
@@ -1088,7 +1100,7 @@ int BKE_library_ID_use_ID(ID *id_user, ID *id_used)
 	iter.curr_id = id_user;
 	iter.count_direct = iter.count_indirect = 0;
 
-	BKE_library_foreach_ID_link(iter.curr_id, foreach_libblock_id_users_callback, (void *)&iter, IDWALK_NOP);
+	BKE_library_foreach_ID_link(NULL, iter.curr_id, foreach_libblock_id_users_callback, (void *)&iter, IDWALK_READONLY);
 
 	return iter.count_direct + iter.count_indirect;
 }
@@ -1117,7 +1129,7 @@ static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked)
 			}
 			iter.curr_id = id_curr;
 			BKE_library_foreach_ID_link(
-			            id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_NOP);
+			            bmain, id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_READONLY);
 
 			is_defined = ((check_linked ? iter.count_indirect : iter.count_direct) != 0);
 		}
@@ -1168,7 +1180,7 @@ void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *is_used_local, boo
 				continue;
 			}
 			iter.curr_id = id_curr;
-			BKE_library_foreach_ID_link(id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_NOP);
+			BKE_library_foreach_ID_link(bmain, id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_READONLY);
 
 			is_defined = (iter.count_direct != 0 && iter.count_indirect != 0);
 		}
@@ -1245,7 +1257,8 @@ void BKE_library_unused_linked_data_set_tag(Main *bmain, const bool do_init_tag)
 					/* Unused ID (so far), no need to check it further. */
 					continue;
 				}
-				BKE_library_foreach_ID_link(id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_NOP);
+				BKE_library_foreach_ID_link(
+				            bmain, id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_READONLY);
 			}
 		}
 	}
@@ -1272,7 +1285,8 @@ void BKE_library_indirectly_used_data_tag_clear(Main *bmain)
 					/* Local or non-indirectly-used ID (so far), no need to check it further. */
 					continue;
 				}
-				BKE_library_foreach_ID_link(id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_NOP);
+				BKE_library_foreach_ID_link(
+				            bmain, id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_READONLY);
 			}
 		}
 	}
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index 5fba7b75b1..ff66c37a09 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -438,7 +438,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
 #endif
 		r_id_remap_data->id = id;
 		libblock_remap_data_preprocess(r_id_remap_data);
-		BKE_library_foreach_ID_link(id, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
+		BKE_library_foreach_ID_link(NULL, id, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
 	}
 	else {
 		i = set_listbasepointers(bmain, lb_array);
@@ -460,7 +460,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
 				r_id_remap_data->id = id_curr;
 				libblock_remap_data_preprocess(r_id_remap_data);
 				BKE_library_foreach_ID_link(
-				            id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
+				            NULL, id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
 			}
 		}
 	}
@@ -719,7 +719,7 @@ void BKE_libblock_relink_to_newid(ID *id)
 	if (ID_IS_LINKED_DATABLOCK(id))
 		return;
 
-	BKE_library_foreach_ID_link(id, id_relink_to_newid_looper, NULL, 0);
+	BKE_library_foreach_ID_link(NULL, id, id_relink_to_newid_looper, NULL, 0);
 }
 
 void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id)
diff --git a/sourc

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list