Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <bastien@blender.org>2021-02-04 17:21:29 +0300
committerBastien Montagne <bastien@blender.org>2021-02-08 17:59:08 +0300
commit302625eb37e6df6a7a5a889c9dd7edbaa640e086 (patch)
treeaf03df3b555614a46e4134bebca0b9ac01eb8f81 /source/blender
parentf5c781af5643b4660c0ce27468221b37248d8372 (diff)
Fix (studio-reported) crash in readfile code.
Essentially, `lib_link_all` would perform some post-processing over data in given `bmain` that **may** fail when not all data from all libraries has been properly loaded yet. This happens when `lib_link_all` is called from `read_libraries`, where the bmains are split by libraries. Now those post-processing is put into its own utils function, which asserts that it is only called on a merged bmain. Bonus point, this will avoid re-runing those not-so-cheap operations more than once on the same data. Reproducible in r1442 of Sprite repository when opening `pro/animation_test/rex/performance/rex_crowdcamping/rex_crowdcamping.lighting.blend` NOTE: Not so sure why we have to call `lib_link_all` several times (once for each library, and then once on the whole merged bmain, including local IDs then). So that it can get called for libs while we still have that specific .blend file handle around? In any case, the overhead here is minimal since we do ensure a data-block is never lib-linked more than once, so this is not a serious concern right now. Differential Revision: https://developer.blender.org/D10307
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenloader/intern/readfile.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 89d4fe0b222..b86896b1a8e 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3918,6 +3918,24 @@ static void lib_link_all(FileData *fd, Main *bmain)
}
FOREACH_MAIN_ID_END;
+#ifndef NDEBUG
+ /* Double check we do not have any 'need link' tag remaining, this should never be the case once
+ * this function has run. */
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ BLI_assert((id->tag & LIB_TAG_NEED_LINK) == 0);
+ }
+ FOREACH_MAIN_ID_END;
+#endif
+}
+
+/* Checks to perform after `lib_link_all`.
+ * Those operations cannot perfom properly in a split bmain case, since some data from other
+ * bmain's (aka libraries) may not have been processed yet. */
+static void after_liblink_merged_bmain_process(Main *bmain)
+{
+ /* We only expect a merged Main here, not a split one. */
+ BLI_assert((bmain->prev == NULL) && (bmain->next == NULL));
+
/* Check for possible cycles in scenes' 'set' background property. */
lib_link_scenes_check_set(bmain);
@@ -3928,15 +3946,6 @@ static void lib_link_all(FileData *fd, Main *bmain)
/* We have to rebuild that runtime information *after* all data-blocks have been properly linked.
*/
BKE_main_collections_parent_relations_rebuild(bmain);
-
-#ifndef NDEBUG
- /* Double check we do not have any 'need link' tag remaining, this should never be the case once
- * this function has run. */
- FOREACH_MAIN_ID_BEGIN (bmain, id) {
- BLI_assert((id->tag & LIB_TAG_NEED_LINK) == 0);
- }
- FOREACH_MAIN_ID_END;
-#endif
}
/** \} */
@@ -4159,6 +4168,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
blo_join_main(&mainlist);
lib_link_all(fd, bfd->main);
+ after_liblink_merged_bmain_process(bfd->main);
/* Skip in undo case. */
if (fd->memfile == NULL) {
@@ -5107,6 +5117,7 @@ static void library_link_end(Main *mainl,
mainl = NULL; /* blo_join_main free's mainl, cant use anymore */
lib_link_all(*fd, mainvar);
+ after_liblink_merged_bmain_process(mainvar);
/* Some versioning code does expect some proper userrefcounting, e.g. in conversion from
* groups to collections... We could optimize out that first call when we are reading a