[Bf-blender-cvs] [bc3aab3fa54] blender-v2.83-release: Fix T75893: Undo causes crash with "Load UI" disabled.

Bastien Montagne noreply at git.blender.org
Tue Apr 21 18:29:06 CEST 2020


Commit: bc3aab3fa547e60d2361d5a50cdc79885bdc7355
Author: Bastien Montagne
Date:   Tue Apr 21 18:26:32 2020 +0200
Branches: blender-v2.83-release
https://developer.blender.org/rBbc3aab3fa547e60d2361d5a50cdc79885bdc7355

Fix T75893: Undo causes crash with "Load UI" disabled.

We need to re-generate a new session uuid for the UI-related data-blocks
that are kept across file reading, when load UI is disabled. Otherwise
there will be several IDs with same uuid, which is an ensured way to
crash in new undo code.

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

M	source/blender/blenkernel/BKE_lib_id.h
M	source/blender/blenkernel/intern/blendfile.c
M	source/blender/blenkernel/intern/lib_id.c

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

diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h
index 9f36798fbd5..0c91ba6231b 100644
--- a/source/blender/blenkernel/BKE_lib_id.h
+++ b/source/blender/blenkernel/BKE_lib_id.h
@@ -74,6 +74,7 @@ void BKE_libblock_init_empty(struct ID *id) ATTR_NONNULL(1);
 
 void BKE_lib_libblock_session_uuid_reset(void);
 void BKE_lib_libblock_session_uuid_ensure(struct ID *id);
+void BKE_lib_libblock_session_uuid_renew(struct ID *id);
 
 void *BKE_id_new(struct Main *bmain, const short type, const char *name);
 void *BKE_id_new_nomain(const short type, const char *name);
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index 2a53a0b69a4..5c000fbcb36 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -201,6 +201,27 @@ static void setup_app_data(bContext *C,
     SWAP(ListBase, bmain->workspaces, bfd->main->workspaces);
     SWAP(ListBase, bmain->screens, bfd->main->screens);
 
+    /* In case of actual new file reading without loading UI, we need to regenerate the session
+     * uuid of the UI-related datablocks we are keeping from previous session, otherwise their uuid
+     * will collide with some generated for newly read data. */
+    if (mode != LOAD_UNDO) {
+      ID *id;
+      FOREACH_MAIN_LISTBASE_ID_BEGIN (&bfd->main->wm, id) {
+        BKE_lib_libblock_session_uuid_renew(id);
+      }
+      FOREACH_MAIN_LISTBASE_ID_END;
+
+      FOREACH_MAIN_LISTBASE_ID_BEGIN (&bfd->main->workspaces, id) {
+        BKE_lib_libblock_session_uuid_renew(id);
+      }
+      FOREACH_MAIN_LISTBASE_ID_END;
+
+      FOREACH_MAIN_LISTBASE_ID_BEGIN (&bfd->main->screens, id) {
+        BKE_lib_libblock_session_uuid_renew(id);
+      }
+      FOREACH_MAIN_LISTBASE_ID_END;
+    }
+
     /* we re-use current window and screen */
     win = CTX_wm_window(C);
     curscreen = CTX_wm_screen(C);
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 80f29a55b28..d1337620de8 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -1087,6 +1087,18 @@ void BKE_lib_libblock_session_uuid_ensure(ID *id)
   }
 }
 
+/**
+ * Re-generate a new session-wise uuid for the given \a id.
+ *
+ * \warning This has a very specific use-case (to handle UI-related data-blocks that are kept
+ * across new file reading, when we do keep existing UI). No other usage is expected currently.
+ */
+void BKE_lib_libblock_session_uuid_renew(ID *id)
+{
+  id->session_uuid = MAIN_ID_SESSION_UUID_UNSET;
+  BKE_lib_libblock_session_uuid_ensure(id);
+}
+
 /**
  * Generic helper to create a new empty data-block of given type in given \a bmain database.
  *



More information about the Bf-blender-cvs mailing list