[Bf-blender-cvs] [b47a234f98d] master: BKE_Main: Add clear separation between 'temp' mains and global main.

Bastien Montagne noreply at git.blender.org
Wed Oct 5 14:27:07 CEST 2022


Commit: b47a234f98dd7e6e0b53ad96b5b4d278635874d8
Author: Bastien Montagne
Date:   Wed Oct 5 12:55:32 2022 +0200
Branches: master
https://developer.blender.org/rBb47a234f98dd7e6e0b53ad96b5b4d278635874d8

BKE_Main: Add clear separation between 'temp' mains and global main.

Blender is using more and more temporary Main data-base (historically
for reading linked data, but also now when resyncing liboverrides, for
temp data in asset code, etc.).

This commit aims at making this a bit more formal and defined, by:
* Adding a dedicated flag in Main struct to mark a Main as global.
* Adding some API to replace, or temporarily swap the current global
  Main (`G_MAIN`) by another one.

NOTE: Having to temporarily replace `G_MAIN` is a workaround for the
limitation of current RNA, ideally this should be fixed in RNA itself,
but for now at least having an API helps tracking those cases (since
this is potentially risky operation).

This work is also a preparation for more usages of temp mains in the near
future (Asset Brushes and its presets system e.g. will most likely use
temp mains too).

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D15977

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

M	source/blender/blenkernel/BKE_blender.h
M	source/blender/blenkernel/BKE_main.h
M	source/blender/blenkernel/intern/blender.c
M	source/blender/blenkernel/intern/blendfile.c
M	source/blender/blenkernel/intern/lib_override.cc
M	source/blender/blenkernel/intern/main.c
M	source/blender/blenloader/intern/versioning_280.c

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

diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 940dec2fcd5..1f0919bb3e6 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -11,6 +11,9 @@
 extern "C" {
 #endif
 
+#include "BLI_compiler_attrs.h"
+
+struct Main;
 struct UserDef;
 
 /**
@@ -21,6 +24,16 @@ void BKE_blender_free(void);
 void BKE_blender_globals_init(void);
 void BKE_blender_globals_clear(void);
 
+/** Replace current global Main by the given one, freeing existing one. */
+void BKE_blender_globals_main_replace(struct Main *bmain);
+/**
+ * Replace current global Main by the given one, returning the old one.
+ *
+ * \warning Advanced, risky workaround addressing the issue that current RNA is not able to process
+ * correectly non-G_MAIN data, use with (a lot of) care.
+ */
+struct Main *BKE_blender_globals_main_swap(struct Main *new_gmain);
+
 void BKE_blender_userdef_data_swap(struct UserDef *userdef_a, struct UserDef *userdef_b);
 void BKE_blender_userdef_data_set(struct UserDef *userdef);
 void BKE_blender_userdef_data_set_and_free(struct UserDef *userdef);
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 0048ad4dde5..7c3a64f1cad 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -138,6 +138,14 @@ typedef struct Main {
    */
   bool is_locked_for_linking;
 
+  /**
+   * True if this main is the 'GMAIN' of current Blender.
+   *
+   * \note There should always be only one global main, all others generated temporarily for
+   * various data management process must have this property set to false..
+   */
+  bool is_global_main;
+
   BlendThumbnail *blen_thumb;
 
   struct Library *curlib;
@@ -202,6 +210,12 @@ typedef struct Main {
   struct MainLock *lock;
 } Main;
 
+/**
+ * Create a new Main data-base.
+ *
+ * \note Always generate a non-global Main, use #BKE_blender_globals_main_replace to put a newly
+ * created one in `G_MAIN`.
+ */
 struct Main *BKE_main_new(void);
 void BKE_main_free(struct Main *mainvar);
 
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 947cdc0c8bf..23cf368af01 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -62,8 +62,7 @@ void BKE_blender_free(void)
   /* Needs to run before main free as wm is still referenced for icons preview jobs. */
   BKE_studiolight_free();
 
-  BKE_main_free(G_MAIN);
-  G_MAIN = NULL;
+  BKE_blender_globals_clear();
 
   if (G.log.file != NULL) {
     fclose(G.log.file);
@@ -146,7 +145,7 @@ void BKE_blender_globals_init(void)
 
   U.savetime = 1;
 
-  G_MAIN = BKE_main_new();
+  BKE_blender_globals_main_replace(BKE_main_new());
 
   strcpy(G.ima, "//");
 
@@ -161,11 +160,34 @@ void BKE_blender_globals_init(void)
 
 void BKE_blender_globals_clear(void)
 {
+  if (G_MAIN == NULL) {
+    return;
+  }
+  BLI_assert(G_MAIN->is_global_main);
   BKE_main_free(G_MAIN); /* free all lib data */
 
   G_MAIN = NULL;
 }
 
+void BKE_blender_globals_main_replace(Main *bmain)
+{
+  BLI_assert(!bmain->is_global_main);
+  BKE_blender_globals_clear();
+  bmain->is_global_main = true;
+  G_MAIN = bmain;
+}
+
+Main *BKE_blender_globals_main_swap(Main *new_gmain)
+{
+  Main *old_gmain = G_MAIN;
+  BLI_assert(old_gmain->is_global_main);
+  BLI_assert(!new_gmain->is_global_main);
+  new_gmain->is_global_main = true;
+  G_MAIN = new_gmain;
+  old_gmain->is_global_main = false;
+  return old_gmain;
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index ba208f688ee..6546659f6cd 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -287,11 +287,8 @@ static void setup_app_data(bContext *C,
     }
   }
 
-  /* free G_MAIN Main database */
-  //  CTX_wm_manager_set(C, NULL);
-  BKE_blender_globals_clear();
-
-  bmain = G_MAIN = bfd->main;
+  BKE_blender_globals_main_replace(bfd->main);
+  bmain = G_MAIN;
   bfd->main = NULL;
 
   CTX_data_main_set(C, bmain);
diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc
index e2f991a4026..04679b72b2d 100644
--- a/source/blender/blenkernel/intern/lib_override.cc
+++ b/source/blender/blenkernel/intern/lib_override.cc
@@ -23,6 +23,7 @@
 
 #include "BKE_anim_data.h"
 #include "BKE_armature.h"
+#include "BKE_blender.h"
 #include "BKE_collection.h"
 #include "BKE_fcurve.h"
 #include "BKE_global.h"
@@ -3829,9 +3830,8 @@ void BKE_lib_override_library_main_update(Main *bmain)
 
   /* This temporary swap of G_MAIN is rather ugly,
    * but necessary to avoid asserts checks in some RNA assignment functions,
-   * since those always use on G_MAIN when they need access to a Main database. */
-  Main *orig_gmain = G_MAIN;
-  G_MAIN = bmain;
+   * since those always use G_MAIN when they need access to a Main database. */
+  Main *orig_gmain = BKE_blender_globals_main_swap(bmain);
 
   BLI_assert(BKE_main_namemap_validate(bmain));
 
@@ -3844,7 +3844,9 @@ void BKE_lib_override_library_main_update(Main *bmain)
 
   BLI_assert(BKE_main_namemap_validate(bmain));
 
-  G_MAIN = orig_gmain;
+  Main *tmp_gmain = BKE_blender_globals_main_swap(orig_gmain);
+  BLI_assert(tmp_gmain == bmain);
+  UNUSED_VARS_NDEBUG(tmp_gmain);
 }
 
 bool BKE_lib_override_library_id_is_user_deletable(Main *bmain, ID *id)
diff --git a/source/blender/blenkernel/intern/main.c b/source/blender/blenkernel/intern/main.c
index 239aacf28d6..3e8ff957d53 100644
--- a/source/blender/blenkernel/intern/main.c
+++ b/source/blender/blenkernel/intern/main.c
@@ -29,11 +29,12 @@
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
 
-Main *BKE_main_new(void)
+Main *BKE_main_new()
 {
   Main *bmain = MEM_callocN(sizeof(Main), "new main");
   bmain->lock = MEM_mallocN(sizeof(SpinLock), "main lock");
   BLI_spin_init((SpinLock *)bmain->lock);
+  bmain->is_global_main = false;
   return bmain;
 }
 
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 3e26516cd69..a9048037513 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -53,6 +53,7 @@
 #include "DNA_world_types.h"
 
 #include "BKE_animsys.h"
+#include "BKE_blender.h"
 #include "BKE_brush.h"
 #include "BKE_cloth.h"
 #include "BKE_collection.h"
@@ -1613,12 +1614,13 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
       if (me->totface && !me->totpoly) {
         /* temporarily switch main so that reading from
          * external CustomData works */
-        Main *gmain = G_MAIN;
-        G_MAIN = bmain;
+        Main *orig_gmain = BKE_blender_globals_main_swap(bmain);
 
         BKE_mesh_do_versions_convert_mfaces_to_mpolys(me);
 
-        G_MAIN = gmain;
+        Main *tmp_gmain = BKE_blender_globals_main_swap(orig_gmain);
+        BLI_assert(tmp_gmain == bmain);
+        UNUSED_VARS_NDEBUG(tmp_gmain);
       }
 
       /* Deprecated, only kept for conversion. */



More information about the Bf-blender-cvs mailing list