From cd579c49960510b9979842284b94b35c9175e059 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 30 Jul 2020 11:05:04 +0200 Subject: Add generic session UUID structures to DNA Allows to use pre-defined structure for session UUIDs in all data structures which needs it: pose channels, sequencer strips, modifiers. The goal of all this is to have a reliable way of matching original and copy-on-written versions of data, so that it's possible to preserve runtime caches. --- source/blender/makesdna/DNA_session_uuid_types.h | 46 ++++++++++++++++++++++++ source/blender/makesdna/intern/makesdna.c | 2 ++ 2 files changed, 48 insertions(+) create mode 100644 source/blender/makesdna/DNA_session_uuid_types.h diff --git a/source/blender/makesdna/DNA_session_uuid_types.h b/source/blender/makesdna/DNA_session_uuid_types.h new file mode 100644 index 00000000000..d2ec0eb3de1 --- /dev/null +++ b/source/blender/makesdna/DNA_session_uuid_types.h @@ -0,0 +1,46 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup DNA + */ + +#ifndef __DNA_SESSION_UUID_TYPES_H__ +#define __DNA_SESSION_UUID_TYPES_H__ + +#include "BLI_sys_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Is a structure because of the following considerations: + * + * - It is not possible to use custom types in DNA members: makesdna does not recognize them. + * - It allows to add more bits, more than standard fixed-size types can store. For example, if + * we ever need to go 128 bits, it is as simple as adding extra 64bit field. + */ +typedef struct SessionUUID { + /* Never access directly, as it might cause a headache when more bits are needed: if the field + * is used directly it will not be easy to find all places where partial access is used. */ + uint64_t uuid_; +} SessionUUID; + +#ifdef __cplusplus +} +#endif + +#endif /* __DNA_SESSION_UUID_TYPES_H__ */ diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 182296c0ba2..9d2fecb123b 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -98,6 +98,7 @@ static const char *includefiles[] = { "DNA_sdna_types.h", "DNA_fileglobal_types.h", "DNA_sequence_types.h", + "DNA_session_uuid_types.h", "DNA_effect_types.h", "DNA_outliner_types.h", "DNA_sound_types.h", @@ -1538,6 +1539,7 @@ int main(int argc, char **argv) # pragma GCC poison long #endif +#include "DNA_session_uuid_types.h" #include "DNA_ID.h" #include "DNA_action_types.h" #include "DNA_anim_types.h" -- cgit v1.2.3 From de21ddf821ce073031aa0154874cebcfad7cb481 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 30 Jul 2020 11:12:13 +0200 Subject: BLI: Initial implementation of generic session UUID API Covers basics like generation of new UUID. Also contains code needed to use the SessionUUID as a key in the Map. --- source/blender/blenlib/BLI_session_uuid.h | 71 ++++++++++++++++++++++++ source/blender/blenlib/CMakeLists.txt | 2 + source/blender/blenlib/intern/session_uuid.c | 78 +++++++++++++++++++++++++++ tests/gtests/blenlib/BLI_session_uuid_test.cc | 20 +++++++ tests/gtests/blenlib/CMakeLists.txt | 1 + 5 files changed, 172 insertions(+) create mode 100644 source/blender/blenlib/BLI_session_uuid.h create mode 100644 source/blender/blenlib/intern/session_uuid.c create mode 100644 tests/gtests/blenlib/BLI_session_uuid_test.cc diff --git a/source/blender/blenlib/BLI_session_uuid.h b/source/blender/blenlib/BLI_session_uuid.h new file mode 100644 index 00000000000..35d358b8e7c --- /dev/null +++ b/source/blender/blenlib/BLI_session_uuid.h @@ -0,0 +1,71 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __BLI_SESSION_UUID_H__ +#define __BLI_SESSION_UUID_H__ + +/** \file + * \ingroup bli + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "DNA_session_uuid_types.h" + +/* Generate new UUID which is unique throughout the Blender session. */ +SessionUUID BLI_session_uuid_generate(void); + +/* Check whether the UUID is properly generated. */ +bool BLI_session_uuid_is_generated(const SessionUUID *uuid); + +/* Check whether two UUIDs are identical. */ +bool BLI_session_uuid_is_equal(const SessionUUID *lhs, const SessionUUID *rhs); + +uint64_t BLI_session_uuid_hash_uint64(const SessionUUID *uuid); + +/* Utility functions to make it possible to create GHash/GSet with UUID as a key. */ +uint BLI_session_uuid_ghash_hash(const void *uuid_v); +bool BLI_session_uuid_ghash_compare(const void *lhs_v, const void *rhs_v); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus + +namespace blender { + +inline const bool operator==(const SessionUUID &lhs, const SessionUUID &rhs) +{ + return BLI_session_uuid_is_equal(&lhs, &rhs); +} + +template struct DefaultHash; + +template<> struct DefaultHash { + uint64_t operator()(const SessionUUID &value) const + { + return BLI_session_uuid_hash_uint64(&value); + } +}; + +} // namespace blender + +#endif + +#endif /* __BLI_SESSION_UUID_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index c6e04d4147a..d7b279c9bbf 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -110,6 +110,7 @@ set(SRC intern/rct.c intern/scanfill.c intern/scanfill_utils.c + intern/session_uuid.c intern/smallhash.c intern/sort.c intern/sort_utils.c @@ -239,6 +240,7 @@ set(SRC BLI_rect.h BLI_resource_collector.hh BLI_scanfill.h + BLI_session_uuid.h BLI_set.hh BLI_set_slots.hh BLI_smallhash.h diff --git a/source/blender/blenlib/intern/session_uuid.c b/source/blender/blenlib/intern/session_uuid.c new file mode 100644 index 00000000000..51d1177a332 --- /dev/null +++ b/source/blender/blenlib/intern/session_uuid.c @@ -0,0 +1,78 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup bli + */ + +#include "BLI_session_uuid.h" + +#include "BLI_utildefines.h" + +#include "atomic_ops.h" + +/* Special value which indicates the UUID has not been assigned yet. */ +#define BLI_SESSION_UUID_NONE 0 + +static const SessionUUID global_session_uuid_none = {BLI_SESSION_UUID_NONE}; + +/* Denotes last used UUID. + * It might eventually overflow, and easiest is to add more bits to it. */ +static SessionUUID global_session_uuid = global_session_uuid_none; + +SessionUUID BLI_session_uuid_generate(void) +{ + SessionUUID result; + result.uuid_ = atomic_add_and_fetch_uint64(&global_session_uuid.uuid_, 1); + if (!BLI_session_uuid_is_generated(&result)) { + /* Happens when the UUID overflows. + * + * Just request the UUID once again, hoping that there are no a lot of high-priority threads + * which will overflow the counter once again between the previous call and this one. + * + * NOTE: It is possible to have collissions after such overflow. */ + result.uuid_ = atomic_add_and_fetch_uint64(&global_session_uuid.uuid_, 1); + } + return result; +} + +bool BLI_session_uuid_is_generated(const SessionUUID *uuid) +{ + return !BLI_session_uuid_is_equal(uuid, &global_session_uuid_none); +} + +bool BLI_session_uuid_is_equal(const SessionUUID *lhs, const SessionUUID *rhs) +{ + return lhs->uuid_ == rhs->uuid_; +} + +uint64_t BLI_session_uuid_hash_uint64(const SessionUUID *uuid) +{ + return uuid->uuid_; +} + +uint BLI_session_uuid_ghash_hash(const void *uuid_v) +{ + const SessionUUID *uuid = (const SessionUUID *)uuid_v; + return uuid->uuid_ & 0xffffffff; +} + +bool BLI_session_uuid_ghash_compare(const void *lhs_v, const void *rhs_v) +{ + const SessionUUID *lhs = (const SessionUUID *)lhs_v; + const SessionUUID *rhs = (const SessionUUID *)rhs_v; + return BLI_session_uuid_is_equal(lhs, rhs); +} diff --git a/tests/gtests/blenlib/BLI_session_uuid_test.cc b/tests/gtests/blenlib/BLI_session_uuid_test.cc new file mode 100644 index 00000000000..1a5f17be06c --- /dev/null +++ b/tests/gtests/blenlib/BLI_session_uuid_test.cc @@ -0,0 +1,20 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include "BLI_session_uuid.h" + +TEST(SessionUUID, GenerateBasic) +{ + { + const SessionUUID uuid = BLI_session_uuid_generate(); + EXPECT_TRUE(BLI_session_uuid_is_generated(&uuid)); + } + + { + const SessionUUID uuid1 = BLI_session_uuid_generate(); + const SessionUUID uuid2 = BLI_session_uuid_generate(); + + EXPECT_FALSE(BLI_session_uuid_is_equal(&uuid1, &uuid2)); + } +} diff --git a/tests/gtests/blenlib/CMakeLists.txt b/tests/gtests/blenlib/CMakeLists.txt index d151dacd7a4..937279bceb9 100644 --- a/tests/gtests/blenlib/CMakeLists.txt +++ b/tests/gtests/blenlib/CMakeLists.txt @@ -68,6 +68,7 @@ BLENDER_TEST(BLI_memiter "bf_blenlib") BLENDER_TEST(BLI_memory_utils "bf_blenlib") BLENDER_TEST(BLI_path_util "${BLI_path_util_extra_libs}") BLENDER_TEST(BLI_polyfill_2d "bf_blenlib") +BLENDER_TEST(BLI_session_uuid "bf_blenlib") BLENDER_TEST(BLI_set "bf_blenlib") BLENDER_TEST(BLI_span "bf_blenlib") BLENDER_TEST(BLI_stack "bf_blenlib") -- cgit v1.2.3 From 44b32e0e4ae342f03f94ce1a2a1a607476fb8601 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 30 Jul 2020 11:42:04 +0200 Subject: Sequencer: Add session UUID field to the Sequence DNA --- source/blender/makesdna/DNA_sequence_types.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 9fee839f979..798bc20a71e 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -34,6 +34,7 @@ #include "DNA_color_types.h" #include "DNA_defs.h" #include "DNA_listBase.h" +#include "DNA_session_uuid_types.h" #include "DNA_vec_types.h" #include "DNA_vfont_types.h" @@ -119,6 +120,10 @@ typedef struct Strip { ColorManagedColorspaceSettings colorspace_settings; } Strip; +typedef struct SequenceRuntime { + SessionUUID session_uuid; +} SequenceRuntime; + /** * The sequence structure is the basic struct used by any strip. * each of the strips uses a different sequence structure. @@ -237,6 +242,10 @@ typedef struct Sequence { int cache_flag; int _pad2[3]; + SequenceRuntime runtime; + + /* NOTE: Technically this is a runtime data as well, but it is aimed to be removed once the + * UUID is in place. */ struct Sequence *orig_sequence; void *_pad3; } Sequence; -- cgit v1.2.3 From 3305a94fa1d80259651c776e088ec9c6a6f64e44 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 30 Jul 2020 11:58:18 +0200 Subject: Sequencer: Add session UUID management to Sequence This is the first step for having sequences covered with session UUID with the goal to remove code which uses original sequence pointer to match sequences. Currently this UUID is maintained on file load, allocation and leaf duplication function.There are more cases to cover and ensure UUID is re-generated or re-used when needed. It will be done as follow-up development. --- source/blender/blenkernel/BKE_sequencer.h | 3 +++ source/blender/blenkernel/intern/sequencer.c | 12 ++++++++++++ source/blender/blenloader/intern/readfile.c | 3 +++ 3 files changed, 18 insertions(+) diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index c32abbb41c6..6997ea94786 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -527,6 +527,9 @@ typedef struct Sequence *(*SeqLoadFn)(struct bContext *, ListBase *, struct SeqL struct Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine, int type); +/* Generate new UUID for the given sequence. */ +void BKE_sequence_session_uuid_generate(struct Sequence *sequence); + void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq); void BKE_sequence_init_colorspace(struct Sequence *seq); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 42276b7f5c0..57295805e97 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -46,6 +46,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_path_util.h" +#include "BLI_session_uuid.h" #include "BLI_string.h" #include "BLI_string_utf8.h" #include "BLI_threads.h" @@ -5352,9 +5353,16 @@ Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine, int type) seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Sequence Stereo Format"); seq->cache_flag = SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_PREPROCESSED | SEQ_CACHE_STORE_COMPOSITE; + BKE_sequence_session_uuid_generate(seq); + return seq; } +void BKE_sequence_session_uuid_generate(struct Sequence *sequence) +{ + sequence->runtime.session_uuid = BLI_session_uuid_generate(); +} + void BKE_sequence_alpha_mode_from_extension(Sequence *seq) { if (seq->strip && seq->strip->stripdata) { @@ -5664,6 +5672,10 @@ static Sequence *seq_dupli(const Scene *scene_src, { Sequence *seqn = MEM_dupallocN(seq); + if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) { + BKE_sequence_session_uuid_generate(seq); + } + seq->tmp = seqn; seqn->strip = MEM_dupallocN(seq->strip); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9320187f2a0..3c6bf481abe 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6461,6 +6461,9 @@ static void direct_link_scene(BlendDataReader *reader, Scene *sce) link_recurs_seq(reader, &ed->seqbase); SEQ_BEGIN (ed, seq) { + /* Do as early as possible, so that other parts of reading can rely on valid session UUID. */ + BKE_sequence_session_uuid_generate(seq); + BLO_read_data_address(reader, &seq->seq1); BLO_read_data_address(reader, &seq->seq2); BLO_read_data_address(reader, &seq->seq3); -- cgit v1.2.3 From cc63897c2275dc78af7a82684dde37282b3aa876 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 30 Jul 2020 12:23:37 +0200 Subject: Sequencer: Add session UUID check function Is aimed for use during development and debug, to help verifying that operations do not leave sequences with invalid UUIDs. --- source/blender/blenkernel/BKE_sequencer.h | 4 ++++ source/blender/blenkernel/intern/sequencer.c | 29 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 6997ea94786..60a0bee801d 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -629,6 +629,10 @@ void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int cfra); bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports); bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq); +/* A debug and development function which checks whether sequences have unique UUIDs. + * Errors will be reported to the console. */ +void BKE_sequencer_check_uuids_unique_and_report(const struct Scene *scene); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 57295805e97..1be330ee2ef 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -6081,3 +6081,32 @@ bool BKE_sequencer_render_loop_check(Sequence *seq_main, Sequence *seq) return false; } + +void BKE_sequencer_check_uuids_unique_and_report(const Scene *scene) +{ + if (scene->ed == NULL) { + return; + } + + struct GSet *used_uuids = BLI_gset_new( + BLI_session_uuid_ghash_hash, BLI_session_uuid_ghash_compare, "sequencer used uuids"); + + const Sequence *sequence; + SEQ_BEGIN (scene->ed, sequence) { + const SessionUUID *session_uuid = &sequence->runtime.session_uuid; + if (!BLI_session_uuid_is_generated(session_uuid)) { + printf("Sequence %s does not have UUID generated.\n", sequence->name); + continue; + } + + if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) { + printf("Sequence %s has duplicate UUID generated.\n", sequence->name); + continue; + } + + BLI_gset_insert(used_uuids, (void *)session_uuid); + } + SEQ_END; + + BLI_gset_free(used_uuids, NULL); +} -- cgit v1.2.3 From eb8cbb6d7c73fa349ab335cfc7bac8b8f6a845d5 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 30 Jul 2020 12:29:19 +0200 Subject: Depsgraph: Add command line argument to debug UUIDs Will trigger code paths which makes sure UUIDs are generated and are unique. Enabled with --debug-depsgraph-uuid (which is also implied by --debug-depsgraph). --- source/blender/blenkernel/BKE_global.h | 23 +++++++++++----------- .../intern/eval/deg_eval_copy_on_write.cc | 4 ++++ source/creator/creator_args.c | 6 ++++++ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 61c270202f1..a356ad56994 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -145,18 +145,19 @@ enum { G_DEBUG_DEPSGRAPH_TIME = (1 << 11), /* depsgraph timing statistics and messages */ G_DEBUG_DEPSGRAPH_NO_THREADS = (1 << 12), /* single threaded depsgraph */ G_DEBUG_DEPSGRAPH_PRETTY = (1 << 13), /* use pretty colors in depsgraph messages */ + G_DEBUG_DEPSGRAPH_UUID = (1 << 14), /* use pretty colors in depsgraph messages */ G_DEBUG_DEPSGRAPH = (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_EVAL | G_DEBUG_DEPSGRAPH_TAG | - G_DEBUG_DEPSGRAPH_TIME), - G_DEBUG_SIMDATA = (1 << 14), /* sim debug data display */ - G_DEBUG_GPU_MEM = (1 << 15), /* gpu memory in status bar */ - G_DEBUG_GPU = (1 << 16), /* gpu debug */ - G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...)*/ - G_DEBUG_GPU_SHADERS = (1 << 18), /* GLSL shaders */ - G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 19), /* force gpu workarounds bypassing detections. */ - G_DEBUG_XR = (1 << 20), /* XR/OpenXR messages */ - G_DEBUG_XR_TIME = (1 << 21), /* XR/OpenXR timing messages */ - - G_DEBUG_GHOST = (1 << 20), /* Debug GHOST module. */ + G_DEBUG_DEPSGRAPH_TIME | G_DEBUG_DEPSGRAPH_UUID), + G_DEBUG_SIMDATA = (1 << 15), /* sim debug data display */ + G_DEBUG_GPU_MEM = (1 << 16), /* gpu memory in status bar */ + G_DEBUG_GPU = (1 << 17), /* gpu debug */ + G_DEBUG_IO = (1 << 18), /* IO Debugging (for Collada, ...)*/ + G_DEBUG_GPU_SHADERS = (1 << 19), /* GLSL shaders */ + G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 20), /* force gpu workarounds bypassing detections. */ + G_DEBUG_XR = (1 << 21), /* XR/OpenXR messages */ + G_DEBUG_XR_TIME = (1 << 22), /* XR/OpenXR timing messages */ + + G_DEBUG_GHOST = (1 << 23), /* Debug GHOST module. */ }; #define G_DEBUG_ALL \ diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index 79d6c8d6a77..e72083a7cf5 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -306,6 +306,10 @@ bool scene_copy_inplace_no_main(const Scene *scene, Scene *new_scene) { const ID *id_for_copy = &scene->id; + if (G.debug & G_DEBUG_DEPSGRAPH_UUID) { + BKE_sequencer_check_uuids_unique_and_report(scene); + } + #ifdef NESTED_ID_NASTY_WORKAROUND NestedIDHackTempStorage id_hack_storage; id_for_copy = nested_id_hack_get_discarded_pointers(&id_hack_storage, &scene->id); diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 20a75ebe3b9..b8e99899821 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -2189,6 +2189,12 @@ void main_args_setup(bContext *C, bArgs *ba) "--debug-depsgraph-pretty", CB_EX(arg_handle_debug_mode_generic_set, depsgraph_pretty), (void *)G_DEBUG_DEPSGRAPH_PRETTY); + BLI_argsAdd(ba, + 1, + NULL, + "--debug-depsgraph-uuid", + CB_EX(arg_handle_debug_mode_generic_set, depsgraph_build), + (void *)G_DEBUG_DEPSGRAPH_UUID); BLI_argsAdd(ba, 1, NULL, -- cgit v1.2.3 From 9ea6228b07efe4fcefdfb5de83a66308a73ce923 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 30 Jul 2020 14:53:42 +0200 Subject: Sequencer: Ensure UUIDs are updated when needed Document cases where it seems that they need to be updated, but where the proper behavior is to not update the UUID. --- .../blender/editors/space_sequencer/sequencer_edit.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 3fbc31d5240..fe851aa16c8 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2543,7 +2543,8 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) if (nseqbase.first) { Sequence *seq = nseqbase.first; - /* Rely on the nseqbase list being added at the end. */ + /* Rely on the nseqbase list being added at the end. + * Their UUIDs has been re-generated by the BKE_sequence_base_dupli_recursive(), */ BLI_movelisttolist(ed->seqbasep, &nseqbase); for (; seq; seq = seq->next) { @@ -2956,6 +2957,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) if (seq != seqm && (seq->flag & SELECT)) { BKE_sequence_invalidate_cache_composite(scene, seq); channel_max = max_ii(seq->machine, channel_max); + /* Sequence is moved within the same edit, no need to re-generate the UUID. */ BLI_remlink(ed->seqbasep, seq); BLI_addtail(&seqm->seqbase, seq); } @@ -3032,6 +3034,9 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) BKE_sequence_invalidate_cache_composite(scene, seq); } + /* This moves strips from meta to parent, sating within same edit and no new strips are + * allocated. If the UUID was unique already (as it should) it will stay unique. Nn need to + * re-generate the UUIDs.*/ BLI_movelisttolist(ed->seqbasep, &last_seq->seqbase); BLI_listbase_clear(&last_seq->seqbase); @@ -3371,8 +3376,15 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BKE_sequence_base_dupli_recursive( - scene, scene, &seqbase_clipboard, ed->seqbasep, 0, LIB_ID_CREATE_NO_USER_REFCOUNT); + /* NOTE: The UUID is re-generated on paste, so we can keep UUID in the clipboard since + * nobody can reach them anyway. + * This reduces chance or running out of UUIDs if a cat falls asleep on Ctrl-C. */ + BKE_sequence_base_dupli_recursive(scene, + scene, + &seqbase_clipboard, + ed->seqbasep, + 0, + (LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_FREE_NO_MAIN)); seqbase_clipboard_frame = scene->r.cfra; @@ -3430,6 +3442,8 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op)) iseq_first = nseqbase.first; + /* NOTE: BKE_sequence_base_dupli_recursive() takes care of generating new UUIDs for sequences + * in the new list. */ BLI_movelisttolist(ed->seqbasep, &nseqbase); for (iseq = iseq_first; iseq; iseq = iseq->next) { -- cgit v1.2.3 From 1e7afea2bb236ad9281e0d4a3f0342a04cab65c9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 30 Jul 2020 15:36:11 +0200 Subject: Fix T78835: Ghosting audio after using undo The root of the issue comes to the fact that sub-data pointers were used to match strips before/after copy-on-write. The undo system might re-use sub-data pointers after re-allocating them, making it so that, for example, pointer used by sound strip is later re-used by video strip. This fix takes an advantage of recently introduced per-sequence UUID and uses it to match sequences before/after copy-on-write. --- .../depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc | 10 ++++++++-- .../depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h | 6 +++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc index 2780938fe05..ba7d20c0ba8 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc @@ -26,6 +26,8 @@ #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "BLI_assert.h" + #include "BKE_sequencer.h" #include "BKE_sound.h" @@ -43,7 +45,9 @@ void SequencerBackup::init_from_scene(Scene *scene) SequenceBackup sequence_backup(depsgraph); sequence_backup.init_from_sequence(sequence); if (!sequence_backup.isEmpty()) { - sequences_backup.add(sequence->orig_sequence, sequence_backup); + const SessionUUID &session_uuid = sequence->runtime.session_uuid; + BLI_assert(BLI_session_uuid_is_generated(&session_uuid)); + sequences_backup.add(session_uuid, sequence_backup); } } SEQ_END; @@ -53,7 +57,9 @@ void SequencerBackup::restore_to_scene(Scene *scene) { Sequence *sequence; SEQ_BEGIN (scene->ed, sequence) { - SequenceBackup *sequence_backup = sequences_backup.lookup_ptr(sequence->orig_sequence); + const SessionUUID &session_uuid = sequence->runtime.session_uuid; + BLI_assert(BLI_session_uuid_is_generated(&session_uuid)); + SequenceBackup *sequence_backup = sequences_backup.lookup_ptr(session_uuid); if (sequence_backup != nullptr) { sequence_backup->restore_to_sequence(sequence); } diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h index 9fe38ec270c..4419238da32 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h @@ -23,6 +23,10 @@ #pragma once +#include "DNA_session_uuid_types.h" + +#include "BLI_session_uuid.h" + #include "intern/depsgraph_type.h" #include "intern/eval/deg_eval_runtime_backup_sequence.h" @@ -43,7 +47,7 @@ class SequencerBackup { const Depsgraph *depsgraph; - Map sequences_backup; + Map sequences_backup; }; } // namespace deg -- cgit v1.2.3 From de68880e792085aaef1372b023c70c363ed025d0 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 30 Jul 2020 15:39:44 +0200 Subject: Cleanup: Remove unused original pointer in Sequence --- .../depsgraph/intern/eval/deg_eval_copy_on_write.cc | 20 -------------------- source/blender/makesdna/DNA_sequence_types.h | 5 ----- 2 files changed, 25 deletions(-) diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index e72083a7cf5..a4e88f4f8d2 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -480,25 +480,6 @@ void scene_setup_view_layers_after_remap(const Depsgraph *depsgraph, * Still not an excuse to have those. */ } -void update_sequence_orig_pointers(const ListBase *sequences_orig, ListBase *sequences_cow) -{ - Sequence *sequence_orig = reinterpret_cast(sequences_orig->first); - Sequence *sequence_cow = reinterpret_cast(sequences_cow->first); - while (sequence_orig != nullptr) { - update_sequence_orig_pointers(&sequence_orig->seqbase, &sequence_cow->seqbase); - sequence_cow->orig_sequence = sequence_orig; - sequence_cow = sequence_cow->next; - sequence_orig = sequence_orig->next; - } -} - -void update_scene_orig_pointers(const Scene *scene_orig, Scene *scene_cow) -{ - if (scene_orig->ed != nullptr) { - update_sequence_orig_pointers(&scene_orig->ed->seqbase, &scene_cow->ed->seqbase); - } -} - /* Check whether given ID is expanded or still a shallow copy. */ inline bool check_datablock_expanded(const ID *id_cow) { @@ -811,7 +792,6 @@ void update_id_after_copy(const Depsgraph *depsgraph, scene_cow->toolsettings = scene_orig->toolsettings; scene_cow->eevee.light_cache_data = scene_orig->eevee.light_cache_data; scene_setup_view_layers_after_remap(depsgraph, id_node, reinterpret_cast(id_cow)); - update_scene_orig_pointers(scene_orig, scene_cow); break; } default: diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 798bc20a71e..0ede03e80e2 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -243,11 +243,6 @@ typedef struct Sequence { int _pad2[3]; SequenceRuntime runtime; - - /* NOTE: Technically this is a runtime data as well, but it is aimed to be removed once the - * UUID is in place. */ - struct Sequence *orig_sequence; - void *_pad3; } Sequence; typedef struct MetaStack { -- cgit v1.2.3