[Bf-blender-cvs] [abf3ce811f6] master: LayerCollections: Add a way to prevent their resync with Collection hierarchy.

Bastien Montagne noreply at git.blender.org
Mon Jul 26 17:36:53 CEST 2021


Commit: abf3ce811f6e33213a51941b477668750d45c5b4
Author: Bastien Montagne
Date:   Mon Jul 12 16:03:46 2021 +0200
Branches: master
https://developer.blender.org/rBabf3ce811f6e33213a51941b477668750d45c5b4

LayerCollections: Add a way to prevent their resync with Collection hierarchy.

This is an easy & safe, yet not-so-nice way to address the
LayerCollections vs. Collections hierarchy resync problem.

Currently this resync is enforced everytime something changes in the
Collections hierarchy, which is extremely inneficient, and can even
produce 'loss' of LayerCollection data during complex Collection
processes.

Current example is during Library Overrides resync process. New code:
 * Makes resync significantly faster (between 10 and 15%).
 * Fixes 'disappearing' layer collections settings on sub-collections'
   layers.

NOTE: This is not a proper fix for the underlying issue. However,
implementing and testing the 'lazy update' solution as proposed by
{T73411} requires a significant amount of time (especially in testing
and tracking all places where code would need to ensure LayerCollections
are up-to-date), which is not possible currently.

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

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

M	source/blender/blenkernel/BKE_layer.h
M	source/blender/blenkernel/intern/layer.c
M	source/blender/blenkernel/intern/lib_override.c

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

diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 404f344919c..c8af1a91725 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -98,6 +98,9 @@ struct LayerCollection *BKE_layer_collection_from_index(struct ViewLayer *view_l
                                                         const int index);
 int BKE_layer_collection_findindex(struct ViewLayer *view_layer, const struct LayerCollection *lc);
 
+void BKE_layer_collection_resync_forbid(void);
+void BKE_layer_collection_resync_allow(void);
+
 void BKE_main_collection_sync(const struct Main *bmain);
 void BKE_scene_collection_sync(const struct Scene *scene);
 void BKE_layer_collection_sync(const struct Scene *scene, struct ViewLayer *view_layer);
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 28282aaa823..0a0705649bc 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -737,6 +737,35 @@ int BKE_layer_collection_findindex(ViewLayer *view_layer, const LayerCollection
  * in at least one layer collection. That list is also synchronized here, and
  * stores state like selection. */
 
+/* This API allows to temporarily forbid resync of LayerCollections.
+ *
+ * This can greatly improve performances in cases where those functions get
+ * called a lot (e.g. during massive remappings of IDs).
+ *
+ * Usage of these should be done very carefully though. In particular, calling
+ * code must ensures it resync LayerCollections before any UI/Eevnt loop
+ * handling can happen.
+ *
+ * WARNING: This is not threadsafe at all, only use from main thread.
+ *
+ * NOTE: This is a quick and safe band-aid around the long-known issue
+ *       regarding this resync process.
+ *       Proper fix would be to make resync itself lazy, i.e. only happen
+ *       when actually needed.
+ *       See also T73411.
+ */
+static bool no_resync = false;
+
+void BKE_layer_collection_resync_forbid(void)
+{
+  no_resync = true;
+}
+
+void BKE_layer_collection_resync_allow(void)
+{
+  no_resync = false;
+}
+
 static void layer_collection_objects_sync(ViewLayer *view_layer,
                                           LayerCollection *layer,
                                           ListBase *r_lb_new_object_bases,
@@ -933,6 +962,10 @@ static void layer_collection_sync(ViewLayer *view_layer,
  */
 void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
 {
+  if (no_resync) {
+    return;
+  }
+
   if (!scene->master_collection) {
     /* Happens for old files that don't have versioning applied yet. */
     return;
@@ -997,6 +1030,10 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
 
 void BKE_scene_collection_sync(const Scene *scene)
 {
+  if (no_resync) {
+    return;
+  }
+
   LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
     BKE_layer_collection_sync(scene, view_layer);
   }
@@ -1004,6 +1041,10 @@ void BKE_scene_collection_sync(const Scene *scene)
 
 void BKE_main_collection_sync(const Main *bmain)
 {
+  if (no_resync) {
+    return;
+  }
+
   /* TODO: if a single collection changed, figure out which
    * scenes it belongs to and only update those. */
 
@@ -1018,6 +1059,10 @@ void BKE_main_collection_sync(const Main *bmain)
 
 void BKE_main_collection_sync_remap(const Main *bmain)
 {
+  if (no_resync) {
+    return;
+  }
+
   /* On remapping of object or collection pointers free caches. */
   /* TODO: try to make this faster */
 
@@ -1320,6 +1365,10 @@ static void layer_collection_local_sync(ViewLayer *view_layer,
 
 void BKE_layer_collection_local_sync(ViewLayer *view_layer, const View3D *v3d)
 {
+  if (no_resync) {
+    return;
+  }
+
   const unsigned short local_collections_uuid = v3d->local_collections_uuid;
 
   /* Reset flags and set the bases visible by default. */
@@ -1337,6 +1386,10 @@ void BKE_layer_collection_local_sync(ViewLayer *view_layer, const View3D *v3d)
  */
 void BKE_layer_collection_local_sync_all(const Main *bmain)
 {
+  if (no_resync) {
+    return;
+  }
+
   LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
     LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
       LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 9871bf5dc83..0ef9692f7e5 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -1722,6 +1722,11 @@ void BKE_lib_override_library_main_resync(Main *bmain,
                                               COLLECTION_RESTRICT_RENDER;
   }
 
+  /* Necessary to improve performances, and prevent layers matching override sub-collections to be
+   * lost when re-syncing the parent override collection.
+   * Ref. T73411. */
+  BKE_layer_collection_resync_forbid();
+
   int library_indirect_level = lib_override_libraries_index_define(bmain);
   while (library_indirect_level >= 0) {
     /* Update overrides from each indirect level separately. */
@@ -1734,6 +1739,8 @@ void BKE_lib_override_library_main_resync(Main *bmain,
     library_indirect_level--;
   }
 
+  BKE_layer_collection_resync_allow();
+
   /* Essentially ensures that potentially new overrides of new objects will be instantiated. */
   lib_override_library_create_post_process(
       bmain, scene, view_layer, NULL, NULL, override_resync_residual_storage, true);



More information about the Bf-blender-cvs mailing list