LibOverride: Further improve creation/resync pre-process speed.
Fully get rid of `BKE_collection_object_find` in `lib_override_group_tag_data_object_to_collection_init`, even if only used a few times this function was still noticeable in profiling data. Now instead loop over collections' objects to build required object-to-collections mapping. Adds an extra 5-10% speed-up compared to previous commit rB0624fad0f3ff. Related to T94059.
This commit is contained in:
parent
9765ddf4eb
commit
197b3502b0
Notes:
blender-bot
2023-02-13 22:38:46 +01:00
Referenced by issue #94059, Library Override Resync Performance
|
@ -460,6 +460,25 @@ typedef struct LibOverrideGroupTagData {
|
|||
MemArena *mem_arena;
|
||||
} LibOverrideGroupTagData;
|
||||
|
||||
static void lib_override_group_tag_data_object_to_collection_init_collection_process(
|
||||
LibOverrideGroupTagData *data, Collection *collection)
|
||||
{
|
||||
LISTBASE_FOREACH (CollectionObject *, collection_object, &collection->gobject) {
|
||||
Object *ob = collection_object->ob;
|
||||
if (!ID_IS_LINKED(ob)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LinkNodePair **collections_linkedlist_p;
|
||||
if (!BLI_ghash_ensure_p(
|
||||
data->linked_object_to_instantiating_collections, ob, &collections_linkedlist_p)) {
|
||||
*collections_linkedlist_p = BLI_memarena_calloc(data->mem_arena,
|
||||
sizeof(**collections_linkedlist_p));
|
||||
}
|
||||
BLI_linklist_append_arena(*collections_linkedlist_p, collection, data->mem_arena);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize complex data, `data` is expected to be already initialized with basic pointers and
|
||||
* other simple data.
|
||||
*
|
||||
|
@ -471,21 +490,12 @@ static void lib_override_group_tag_data_object_to_collection_init(LibOverrideGro
|
|||
|
||||
data->linked_object_to_instantiating_collections = BLI_ghash_new(
|
||||
BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
|
||||
LISTBASE_FOREACH (Object *, ob, &data->bmain->objects) {
|
||||
if (!ID_IS_LINKED(ob)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LinkNodePair collections_linkedlist = {NULL};
|
||||
Collection *instantiating_collection = NULL;
|
||||
while ((instantiating_collection = BKE_collection_object_find(
|
||||
data->bmain, data->scene, instantiating_collection, ob)) != NULL) {
|
||||
BLI_linklist_append_arena(
|
||||
&collections_linkedlist, instantiating_collection, data->mem_arena);
|
||||
}
|
||||
|
||||
BLI_ghash_insert(
|
||||
data->linked_object_to_instantiating_collections, ob, collections_linkedlist.list);
|
||||
if (data->scene != NULL) {
|
||||
lib_override_group_tag_data_object_to_collection_init_collection_process(
|
||||
data, data->scene->master_collection);
|
||||
}
|
||||
LISTBASE_FOREACH (Collection *, collection, &data->bmain->collections) {
|
||||
lib_override_group_tag_data_object_to_collection_init_collection_process(data, collection);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -651,23 +661,27 @@ static void lib_override_linked_group_tag(LibOverrideGroupTagData *data)
|
|||
Collection *instantiating_collection_override_candidate = NULL;
|
||||
/* Loop over all collections instantiating the object, if we already have a 'locale' one we
|
||||
* have nothing to do, otherwise try to find a 'linked' one that we can override too. */
|
||||
LinkNode *instantiating_collection_linknode = BLI_ghash_lookup(
|
||||
LinkNodePair *instantiating_collection_linklist = BLI_ghash_lookup(
|
||||
data->linked_object_to_instantiating_collections, ob);
|
||||
for (; instantiating_collection_linknode != NULL;
|
||||
instantiating_collection_linknode = instantiating_collection_linknode->next) {
|
||||
instantiating_collection = instantiating_collection_linknode->link;
|
||||
/* In (recursive) resync case, if a collection of a 'parent' lib instantiates the linked
|
||||
* object, it is also fine. */
|
||||
if (!ID_IS_LINKED(instantiating_collection) ||
|
||||
(is_resync && ID_IS_LINKED(id_root) &&
|
||||
instantiating_collection->id.lib->temp_index < id_root->lib->temp_index)) {
|
||||
break;
|
||||
if (instantiating_collection_linklist != NULL) {
|
||||
for (LinkNode *instantiating_collection_linknode =
|
||||
instantiating_collection_linklist->list;
|
||||
instantiating_collection_linknode != NULL;
|
||||
instantiating_collection_linknode = instantiating_collection_linknode->next) {
|
||||
instantiating_collection = instantiating_collection_linknode->link;
|
||||
/* In (recursive) resync case, if a collection of a 'parent' lib instantiates the
|
||||
* linked object, it is also fine. */
|
||||
if (!ID_IS_LINKED(instantiating_collection) ||
|
||||
(is_resync && ID_IS_LINKED(id_root) &&
|
||||
instantiating_collection->id.lib->temp_index < id_root->lib->temp_index)) {
|
||||
break;
|
||||
}
|
||||
if (ID_IS_LINKED(instantiating_collection) &&
|
||||
(!is_resync || instantiating_collection->id.lib == id_root->lib)) {
|
||||
instantiating_collection_override_candidate = instantiating_collection;
|
||||
}
|
||||
instantiating_collection = NULL;
|
||||
}
|
||||
if (ID_IS_LINKED(instantiating_collection) &&
|
||||
(!is_resync || instantiating_collection->id.lib == id_root->lib)) {
|
||||
instantiating_collection_override_candidate = instantiating_collection;
|
||||
}
|
||||
instantiating_collection = NULL;
|
||||
}
|
||||
|
||||
if (instantiating_collection == NULL &&
|
||||
|
|
Loading…
Reference in New Issue