[Bf-blender-cvs] [b3c42ddd6d4] undo-experiments: Undo experiments: proof-of-concept of reusable depsgraph across undo steps.

Bastien Montagne noreply at git.blender.org
Fri Nov 15 09:23:19 CET 2019


Commit: b3c42ddd6d40dd455d5e60d13743d0c4f97f661b
Author: Bastien Montagne
Date:   Thu Nov 14 16:44:28 2019 +0100
Branches: undo-experiments
https://developer.blender.org/rBb3c42ddd6d40dd455d5e60d13743d0c4f97f661b

Undo experiments: proof-of-concept of reusable depsgraph across undo steps.

This is still very sketchy, but seems to work in basic cases. useless
currently, though, as objects are always changed still currently in undo
steps...

Not Yet Working (r)

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

M	source/blender/blenkernel/BKE_scene.h
M	source/blender/blenkernel/intern/scene.c
M	source/blender/blenkernel/intern/undo_system.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/readfile.h
M	source/blender/blenloader/intern/undofile.c
M	source/blender/depsgraph/DEG_depsgraph.h
M	source/blender/depsgraph/intern/depsgraph.cc

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

diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 51abc7390b8..00a36dbd8d5 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -30,6 +30,7 @@ extern "C" {
 struct AviCodecData;
 struct Collection;
 struct Depsgraph;
+struct GHash;
 struct Main;
 struct Object;
 struct RenderData;
@@ -228,6 +229,9 @@ struct Depsgraph *BKE_scene_get_depsgraph(struct Main *bmain,
                                           struct ViewLayer *view_layer,
                                           bool allocate);
 
+struct GHash *BKE_scene_undo_depsgraphs_extract(struct Main *bmain);
+void BKE_scene_undo_depsgraphs_restore(struct Main *bmain, struct GHash *depsgraph_extract);
+
 void BKE_scene_transform_orientation_remove(struct Scene *scene,
                                             struct TransformOrientation *orientation);
 struct TransformOrientation *BKE_scene_transform_orientation_find(const struct Scene *scene,
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 53e5f1fdfe5..4da795b223c 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -2063,12 +2063,16 @@ void BKE_scene_free_depsgraph_hash(Scene *scene)
 
 /* Query depsgraph for a specific contexts. */
 
-Depsgraph *BKE_scene_get_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, bool allocate)
+static Depsgraph **scene_get_depsgraph_p(Main *bmain,
+                                         Scene *scene,
+                                         ViewLayer *view_layer,
+                                         const bool allocate_ghash_entry,
+                                         const bool allocate_depsgraph)
 {
   BLI_assert(scene != NULL);
   BLI_assert(view_layer != NULL);
   /* Make sure hash itself exists. */
-  if (allocate) {
+  if (allocate_ghash_entry) {
     BKE_scene_ensure_depsgraph_hash(scene);
   }
   if (scene->depsgraph_hash == NULL) {
@@ -2079,29 +2083,102 @@ Depsgraph *BKE_scene_get_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_la
    */
   DepsgraphKey key;
   key.view_layer = view_layer;
-  Depsgraph *depsgraph;
-  if (allocate) {
+  Depsgraph **depsgraph_ptr;
+  if (allocate_ghash_entry) {
     DepsgraphKey **key_ptr;
-    Depsgraph **depsgraph_ptr;
     if (!BLI_ghash_ensure_p_ex(
             scene->depsgraph_hash, &key, (void ***)&key_ptr, (void ***)&depsgraph_ptr)) {
       *key_ptr = MEM_mallocN(sizeof(DepsgraphKey), __func__);
       **key_ptr = key;
-      *depsgraph_ptr = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_VIEWPORT);
-      /* TODO(sergey): Would be cool to avoid string format print,
-       * but is a bit tricky because we can't know in advance  whether
-       * we will ever enable debug messages for this depsgraph.
-       */
-      char name[1024];
-      BLI_snprintf(name, sizeof(name), "%s :: %s", scene->id.name, view_layer->name);
-      DEG_debug_name_set(*depsgraph_ptr, name);
+      if (allocate_depsgraph) {
+        *depsgraph_ptr = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_VIEWPORT);
+        /* TODO(sergey): Would be cool to avoid string format print,
+         * but is a bit tricky because we can't know in advance  whether
+         * we will ever enable debug messages for this depsgraph.
+         */
+        char name[1024];
+        BLI_snprintf(name, sizeof(name), "%s :: %s", scene->id.name, view_layer->name);
+        DEG_debug_name_set(*depsgraph_ptr, name);
+      }
+      else {
+        *depsgraph_ptr = NULL;
+      }
     }
-    depsgraph = *depsgraph_ptr;
   }
   else {
-    depsgraph = BLI_ghash_lookup(scene->depsgraph_hash, &key);
+    depsgraph_ptr = (Depsgraph **)BLI_ghash_lookup_p(scene->depsgraph_hash, &key);
   }
-  return depsgraph;
+  return depsgraph_ptr;
+}
+
+Depsgraph *BKE_scene_get_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, bool allocate)
+{
+  Depsgraph **depsgraph_ptr = scene_get_depsgraph_p(bmain, scene, view_layer, allocate, allocate);
+  return (depsgraph_ptr != NULL) ? *depsgraph_ptr : NULL;
+}
+
+GHash *BKE_scene_undo_depsgraphs_extract(Main *bmain)
+{
+  GHash *depsgraph_extract = BLI_ghash_new(
+      BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__);
+
+  for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
+    for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL;
+         view_layer = view_layer->next) {
+      DepsgraphKey key;
+      key.view_layer = view_layer;
+      Depsgraph **depsgraph = (Depsgraph **)BLI_ghash_lookup_p(scene->depsgraph_hash, &key);
+
+      if (depsgraph != NULL && *depsgraph != NULL) {
+        char *key_full = MEM_callocN(MAX_ID_NAME + FILE_MAX + MAX_NAME, __func__);
+        BLI_strncpy(key_full, scene->id.name, MAX_ID_NAME);
+        if (scene->id.lib != NULL) {
+          BLI_strncpy(key_full + MAX_ID_NAME, scene->id.lib->name, FILE_MAX);
+        }
+        BLI_strncpy(key_full + MAX_ID_NAME + FILE_MAX, view_layer->name, MAX_NAME);
+
+        /* We steal the depsgraph from the scene. */
+        BLI_ghash_insert(depsgraph_extract, key_full, *depsgraph);
+        *depsgraph = NULL;
+      }
+    }
+  }
+
+  return depsgraph_extract;
+}
+
+void BKE_scene_undo_depsgraphs_restore(Main *bmain, GHash *depsgraph_extract)
+{
+  for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
+    BLI_assert(scene->depsgraph_hash == NULL);
+
+    for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL;
+         view_layer = view_layer->next) {
+      char key_full[MAX_ID_NAME + FILE_MAX + MAX_NAME] = {0};
+      BLI_strncpy(key_full, scene->id.name, MAX_ID_NAME);
+      if (scene->id.lib != NULL) {
+        BLI_strncpy(key_full + MAX_ID_NAME, scene->id.lib->name, FILE_MAX);
+      }
+      BLI_strncpy(key_full + MAX_ID_NAME + FILE_MAX, view_layer->name, MAX_NAME);
+
+      Depsgraph **depsgraph_extract_ptr = (Depsgraph **)BLI_ghash_lookup_p(depsgraph_extract,
+                                                                           key_full);
+      Depsgraph **depsgraph_scene_ptr = scene_get_depsgraph_p(
+          bmain, scene, view_layer, true, false);
+      BLI_assert(depsgraph_scene_ptr != NULL);
+      BLI_assert(*depsgraph_scene_ptr == NULL);
+
+      /* We steal the depsgraph back from our 'extract' storage to the scene. */
+      Depsgraph *depsgraph = *depsgraph_extract_ptr;
+
+      DEG_graph_update_bmain_pointers(depsgraph, bmain, scene, view_layer);
+
+      *depsgraph_scene_ptr = depsgraph;
+      *depsgraph_extract_ptr = NULL;
+    }
+  }
+
+  BLI_ghash_free(depsgraph_extract, MEM_freeN, depsgraph_key_value_free);
 }
 
 /* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index ecae1650a51..a6fba5c2f56 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -26,7 +26,9 @@
 
 #include "BLI_utildefines.h"
 #include "BLI_sys_types.h"
+#include "BLI_ghash.h"
 #include "BLI_listbase.h"
+#include "BLI_path_util.h"
 #include "BLI_string.h"
 
 #include "BLT_translation.h"
@@ -38,6 +40,7 @@
 #include "BKE_global.h"
 #include "BKE_library_override.h"
 #include "BKE_main.h"
+#include "BKE_scene.h"
 #include "BKE_undo_system.h"
 
 #include "MEM_guardedalloc.h"
@@ -670,6 +673,10 @@ bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack,
   if (us != NULL) {
     CLOG_INFO(&LOG, 1, "addr=%p, name='%s', type='%s'", us, us->name, us->type->name);
 
+    Main *bmain = CTX_data_main(C);
+    GHash *depsgraphs = BKE_scene_undo_depsgraphs_extract(bmain);
+    bmain = NULL;
+
     /* Handle accumulate steps. */
     if (ustack->step_active) {
       UndoStep *us_iter = ustack->step_active;
@@ -708,6 +715,9 @@ bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack,
       } while ((us_active != us_iter) && (us_iter = us_iter->prev));
     }
 
+    bmain = CTX_data_main(C);
+    BKE_scene_undo_depsgraphs_restore(bmain, depsgraphs);
+
     return true;
   }
   return false;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 0919c7ad6da..884cc325e92 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -223,7 +223,7 @@
 #define USE_GHASH_RESTORE_POINTER
 
 /* Define this to have verbose debug prints. */
-//#define USE_DEBUG_PRINT
+#define USE_DEBUG_PRINT
 
 #ifdef USE_DEBUG_PRINT
 #  define DEBUG_PRINTF(...) printf(__VA_ARGS__)
@@ -1257,7 +1257,7 @@ static int fd_read_from_memfile(FileData *filedata,
         *r_is_memchunck_identical = chunk->is_identical;
       }
       if (chunk->is_identical) {
-        DEBUG_PRINTF("%s: found an identical memfile chunk...\n", __func__);
+        //        DEBUG_PRINTF("%s: found an identical memfile chunk...\n", __func__);
       }
     } while (totread < size);
 
@@ -9259,7 +9259,8 @@ static BHead *read_libblock(FileData *fd,
 
       /* read all data into fd->datamap */
       /* TODO: instead of building oldnewmap here we could just quickly check the bheads... could
-       * save some more ticks. */
+       * save some more ticks. Probably not worth it though, bottleneck is full depsgraph rebuild
+       * and eval, not actual file reading. */
       bhead = read_data_into_oldnewmap(fd, id_bhead, allocname);
 
       DEBUG_PRINTF("\tfor data of ID %s: are_memchunks_identical: %d\n",
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index fb68ec28209..9583671d152 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -84,7 +84,7 @@ typedef struct FileData {
   /** Whether all data read from memfile so far was identical
    * (i.e. shared with some previous undo step).
    * Updated by `fd_read_from_memfile()`, user is responsible to reset it to true when needed.
-   * Used to detected unchanged IDs. */
+   * Used to detect unchanged IDs. */
   bool are_memchunks_identical;
 
   /** Variables needed for reading from fil

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list