[Bf-blender-cvs] [6766efce4c7] undo-experiments-idnames: undoexp: add a way to prevent re-using data from old bmain for memfile undo.
Bastien Montagne
noreply at git.blender.org
Thu Jan 9 11:25:55 CET 2020
Commit: 6766efce4c7e201eac5ae29385d41314129df48d
Author: Bastien Montagne
Date: Wed Jan 8 15:35:53 2020 +0100
Branches: undo-experiments-idnames
https://developer.blender.org/rB6766efce4c7e201eac5ae29385d41314129df48d
undoexp: add a way to prevent re-using data from old bmain for memfile undo.
There are cases where we need a full 'clean' re-read of stored memfile
data. This include some (rather uncommon, but possible) ID rename
situations, and also likely some switching between memfileundo and
edit-data undo systems.
===================================================================
M source/blender/blenkernel/BKE_blender_undo.h
M source/blender/blenkernel/BKE_main.h
M source/blender/blenkernel/BKE_undo_system.h
M source/blender/blenkernel/intern/blender_undo.c
M source/blender/blenkernel/intern/undo_system.c
M source/blender/blenloader/BLO_readfile.h
M source/blender/blenloader/intern/readblenentry.c
M source/blender/blenloader/intern/readfile.c
M source/blender/editors/undo/memfile_undo.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_blender_undo.h b/source/blender/blenkernel/BKE_blender_undo.h
index 7392d3947a2..f869790decf 100644
--- a/source/blender/blenkernel/BKE_blender_undo.h
+++ b/source/blender/blenkernel/BKE_blender_undo.h
@@ -32,7 +32,9 @@ struct bContext;
struct MemFileUndoData *BKE_memfile_undo_encode(struct Main *bmain,
struct MemFileUndoData *mfu_prev);
-bool BKE_memfile_undo_decode(struct MemFileUndoData *mfu, struct bContext *C);
+bool BKE_memfile_undo_decode(struct MemFileUndoData *mfu,
+ const bool use_old_bmain_data,
+ struct bContext *C);
void BKE_memfile_undo_free(struct MemFileUndoData *mfu);
#ifdef __cplusplus
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index c48a9cad443..c756a5e12df 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -85,6 +85,11 @@ typedef struct Main {
* use "needs_flush_to_id" in edit data to flag data which needs updating.
*/
char is_memfile_undo_flush_needed;
+ /**
+ * Indicates that next memfile undo step should not allow to re-use old bmain when re-read, but
+ * instead do a complete full re-read/update from stored memfile.
+ */
+ char use_memfile_full_barrier;
BlendThumbnail *blen_thumb;
diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h
index bc10d422a61..74ce4d3f020 100644
--- a/source/blender/blenkernel/BKE_undo_system.h
+++ b/source/blender/blenkernel/BKE_undo_system.h
@@ -79,6 +79,9 @@ typedef struct UndoStep {
bool skip;
/** Some situations require the global state to be stored, edge cases when exiting modes. */
bool use_memfile_step;
+ /** When this is true, undo/memfile read code is allowed to re-use old data-blocks for unchanged
+ * IDs, and existing depsgraphes. This has to be forbidden in some cases (like renamed IDs). */
+ bool use_old_bmain_data;
/** For use by undo systems that accumulate changes (text editor, painting). */
bool is_applied;
/* Over alloc 'type->struct_size'. */
diff --git a/source/blender/blenkernel/intern/blender_undo.c b/source/blender/blenkernel/intern/blender_undo.c
index cd950e05415..3a91eb3c1a3 100644
--- a/source/blender/blenkernel/intern/blender_undo.c
+++ b/source/blender/blenkernel/intern/blender_undo.c
@@ -61,7 +61,7 @@
#define UNDO_DISK 0
-bool BKE_memfile_undo_decode(MemFileUndoData *mfu, bContext *C)
+bool BKE_memfile_undo_decode(MemFileUndoData *mfu, const bool use_old_bmain_data, bContext *C)
{
Main *bmain = CTX_data_main(C);
char mainstr[sizeof(bmain->name)];
@@ -76,8 +76,11 @@ bool BKE_memfile_undo_decode(MemFileUndoData *mfu, bContext *C)
success = BKE_blendfile_read(C, mfu->filename, &(const struct BlendFileReadParams){0}, NULL);
}
else {
- success = BKE_blendfile_read_from_memfile(
- C, &mfu->memfile, &(const struct BlendFileReadParams){0}, NULL);
+ struct BlendFileReadParams params = {0};
+ if (!use_old_bmain_data) {
+ params.skip_flags |= BLO_READ_SKIP_UNDO_OLD_MAIN;
+ }
+ success = BKE_blendfile_read_from_memfile(C, &mfu->memfile, ¶ms, NULL);
}
/* Restore, bmain has been re-allocated. */
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index 5d049e9fa3e..3af7c978553 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -170,6 +170,12 @@ static bool undosys_step_encode(bContext *C, Main *bmain, UndoStack *ustack, Und
* not all members are filled in. */
us->type->step_foreach_ID_ref(us, undosys_id_ref_store, bmain);
}
+
+ /* Store the fact that we should not re-use old data with that undo step, and reset the Main
+ * flag. */
+ us->use_old_bmain_data = !bmain->use_memfile_full_barrier;
+ bmain->use_memfile_full_barrier = false;
+
#ifdef WITH_GLOBAL_UNDO_CORRECT_ORDER
if (us->type == BKE_UNDOSYS_TYPE_MEMFILE) {
ustack->step_active_memfile = us;
@@ -233,27 +239,32 @@ static void undosys_step_decode(
/* Extract depsgraphs from current bmain (which may be freed during undo step reading),
* and store them for re-use. */
- GHash *depsgraphs = BKE_scene_undo_depsgraphs_extract(bmain);
+ GHash *depsgraphs = NULL;
+ if (us->use_old_bmain_data) {
+ depsgraphs = BKE_scene_undo_depsgraphs_extract(bmain);
+ }
UNDO_NESTED_CHECK_BEGIN;
us->type->step_decode(C, bmain, us, dir, is_final);
UNDO_NESTED_CHECK_END;
- /* Restore previous depsgraphs into current bmain. */
- bmain = G_MAIN;
- BKE_scene_undo_depsgraphs_restore(bmain, depsgraphs);
-
- /* We need to inform depsgraph about re-used old IDs that would be using newly read data-blocks,
- * at least COW evaluated copies need to be updated... */
- ID *id = NULL;
- FOREACH_MAIN_ID_BEGIN (bmain, id) {
- if (id->tag & LIB_TAG_UNDO_OLD_ID_REUSED) {
- BKE_library_foreach_ID_link(bmain, id, undosys_step_id_reused_cb, bmain, IDWALK_READONLY);
+ if (us->use_old_bmain_data) {
+ /* Restore previous depsgraphs into current bmain. */
+ bmain = G_MAIN;
+ BKE_scene_undo_depsgraphs_restore(bmain, depsgraphs);
+
+ /* We need to inform depsgraph about re-used old IDs that would be using newly read
+ * data-blocks, at least COW evaluated copies need to be updated... */
+ ID *id = NULL;
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ if (id->tag & LIB_TAG_UNDO_OLD_ID_REUSED) {
+ BKE_library_foreach_ID_link(bmain, id, undosys_step_id_reused_cb, bmain, IDWALK_READONLY);
+ }
}
- }
- FOREACH_MAIN_ID_END;
+ FOREACH_MAIN_ID_END;
- BKE_main_id_tag_all(bmain, LIB_TAG_UNDO_OLD_ID_REUSED, false);
+ BKE_main_id_tag_all(bmain, LIB_TAG_UNDO_OLD_ID_REUSED, false);
+ }
#ifdef WITH_GLOBAL_UNDO_CORRECT_ORDER
if (us->type == BKE_UNDOSYS_TYPE_MEMFILE) {
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index adf3bf00d48..978a38808ad 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -74,7 +74,7 @@ typedef struct WorkspaceConfigFileData {
} WorkspaceConfigFileData;
struct BlendFileReadParams {
- uint skip_flags : 2; /* eBLOReadSkip */
+ uint skip_flags : 3; /* eBLOReadSkip */
uint is_startup : 1;
};
@@ -83,6 +83,8 @@ typedef enum eBLOReadSkip {
BLO_READ_SKIP_NONE = 0,
BLO_READ_SKIP_USERDEF = (1 << 0),
BLO_READ_SKIP_DATA = (1 << 1),
+ /** Do not attempt to re-use IDs from old bmain for unchanged ones in case of undo. */
+ BLO_READ_SKIP_UNDO_OLD_MAIN = (1 << 2),
} eBLOReadSkip;
#define BLO_READ_SKIP_ALL (BLO_READ_SKIP_USERDEF | BLO_READ_SKIP_DATA)
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 0c010a59477..f11d2de57c3 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -384,13 +384,15 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain,
/* add the library pointers in oldmap lookup */
blo_add_library_pointer_map(&old_mainlist, fd);
- /* Build idmap of old main (we only care about local data here, so we can do that after
- * split_main() call. */
- blo_make_idmap_from_main(fd, old_mainlist.first);
-
- /* Create sibling mapping of libmap (i.e. old ID pointer values to new valid IDs), but for the
- * addresses from old main. */
- blo_make_undo_reused_libmap(fd);
+ if ((skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0) {
+ /* Build idmap of old main (we only care about local data here, so we can do that after
+ * split_main() call. */
+ blo_make_idmap_from_main(fd, old_mainlist.first);
+
+ /* Create sibling mapping of libmap (i.e. old ID pointer values to new valid IDs), but for
+ * the addresses from old main. */
+ blo_make_undo_reused_libmap(fd);
+ }
/* makes lookup of existing images in old main */
blo_make_image_pointer_map(fd, oldmain);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 2984e690e1f..1a098d1428e 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -9469,7 +9469,8 @@ static BHead *read_libblock(FileData *fd,
id->name,
fd->are_memchunks_identical);
- if (fd->are_memchunks_identical && !ELEM(idcode, ID_WM, ID_SCR, ID_WS)) {
+ if (fd->memfile != NULL && (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0 &&
+ fd->are_memchunks_identical && !ELEM(idcode, ID_WM, ID_SCR, ID_WS)) {
BLI_assert(fd->memfile != NULL);
BLI_assert(fd->old_idmap != NULL);
/* This code should only ever be reached for local data-blocks. */
@@ -9522,7 +9523,9 @@ static BHead *read_libblock(FileData *fd,
/* Some re-used old IDs might also use newly read ones, so we have to check for old memory
* addresses for those as well. */
- if (fd->old_idmap != NULL && id->lib == NULL) {
+ if (fd->memfile != NULL && (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0 &&
+ id->lib == NULL) {
+ BLI_assert(fd->old_idmap != NULL);
ID *id_old = BKE_main_idmap_lookup(fd->old_idmap, idcode, id->name + 2, NULL);
if (id_old != NULL) {
oldnewmap_insert(fd->libmap_undo_reused, id_old, id, id_bhead->code);
@@ -10245,7 +10248,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
blo_join_main(&mainlist);
- if (fd->memfile != NULL) {
+ if (fd->memfile != NULL && (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0) {
/* In case of undo, we have to handle possible 'pointer collisions' between newly read
* data-blocks and those re-used from the old bmain. */
BLI_assert(fd->libmap_undo_reused != NULL);
diff --git a/source/blender/editors/undo/memfile_undo.c b/source/blender/editors/undo/memfile_undo.c
index a5f30409aa6..30d8a7d5a61 100644
--- a/source/blender/editors/undo/memfile_undo.c
+++ b/sou
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list