Merge branch 'blender-v2.90-release'

This commit is contained in:
Sergey Sharybin 2020-07-31 11:53:22 +02:00
commit db24e289b2
17 changed files with 328 additions and 38 deletions

@ -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_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 << 20), /* Debug GHOST module. */
G_DEBUG_GHOST = (1 << 23), /* Debug GHOST module. */
};
#define G_DEBUG_ALL \

@ -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);
@ -630,6 +633,10 @@ void BKE_sequencer_flag_for_removal(struct Scene *scene,
struct Sequence *seq);
void BKE_sequencer_remove_flagged_sequences(struct Scene *scene, struct ListBase *seqbase);
/* 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

@ -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);
@ -6127,3 +6139,32 @@ void BKE_sequencer_remove_flagged_sequences(Scene *scene, ListBase *seqbase)
}
}
}
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);
}

@ -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<typename T> struct DefaultHash;
template<> struct DefaultHash<SessionUUID> {
uint64_t operator()(const SessionUUID &value) const
{
return BLI_session_uuid_hash_uint64(&value);
}
};
} // namespace blender
#endif
#endif /* __BLI_SESSION_UUID_H__ */

@ -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

@ -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);
}

@ -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);

@ -311,6 +311,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);
@ -481,25 +485,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<Sequence *>(sequences_orig->first);
Sequence *sequence_cow = reinterpret_cast<Sequence *>(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)
{
@ -812,7 +797,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<Scene *>(id_cow));
update_scene_orig_pointers(scene_orig, scene_cow);
break;
}
default:

@ -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);
}

@ -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<Sequence *, SequenceBackup> sequences_backup;
Map<SessionUUID, SequenceBackup> sequences_backup;
};
} // namespace deg

@ -2475,7 +2475,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) {
@ -2845,6 +2846,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);
}
@ -2921,6 +2923,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);
@ -3260,8 +3265,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;
@ -3319,6 +3331,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) {

@ -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,8 +242,7 @@ typedef struct Sequence {
int cache_flag;
int _pad2[3];
struct Sequence *orig_sequence;
void *_pad3;
SequenceRuntime runtime;
} Sequence;
typedef struct MetaStack {

@ -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__ */

@ -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",
@ -1547,6 +1548,7 @@ int main(int argc, char **argv)
# pragma GCC poison int8_t
#endif
#include "DNA_session_uuid_types.h"
#include "DNA_ID.h"
#include "DNA_action_types.h"
#include "DNA_anim_types.h"

@ -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,

@ -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));
}
}

@ -59,6 +59,7 @@ BLENDER_TEST(BLI_math_vector "bf_blenlib")
BLENDER_TEST(BLI_memiter "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_stack "bf_blenlib")
BLENDER_TEST(BLI_string "bf_blenlib")
BLENDER_TEST(BLI_string_utf8 "bf_blenlib")