Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/depsgraph')
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_query.h10
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc37
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc5
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc35
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h7
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc11
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc13
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc22
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc244
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.cc3
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.h6
16 files changed, 398 insertions, 13 deletions
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index 48a62a69f30..cc6c5e7282a 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -85,6 +85,16 @@ void DEG_get_customdata_mask_for_object(const struct Depsgraph *graph,
* one. Assert will happen if it's not. */
struct Scene *DEG_get_evaluated_scene(const struct Depsgraph *graph);
+/* Similar to DEG_get_evaluated_scene(), but allows to access non-fully evaluated pointer without
+ * causing asserts or crashes. Works the following way:
+ * - If the scene was never evaluated NULL returned.
+ * - Otherwise the last known state of the scene is returned.
+ *
+ * Use in exceptional case if it's absolutely must to.
+ *
+ * Allows to pass depsgraph == NULL, wil lreturn NULL in that case. */
+struct Scene *DEG_get_evaluated_scene_if_exists(const struct Depsgraph *graph);
+
/* Get view layer at its evaluated state.
* This is a shortcut for accessing active view layer from evaluated scene. */
struct ViewLayer *DEG_get_evaluated_view_layer(const struct Depsgraph *graph);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 93e5dd14ae0..9bdc815518d 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -58,6 +58,7 @@ extern "C" {
#include "DNA_lightprobe_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "DNA_speaker_types.h"
#include "DNA_texture_types.h"
@@ -89,6 +90,8 @@ extern "C" {
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
+#include "BKE_scene.h"
+#include "BKE_sequencer.h"
#include "BKE_shader_fx.h"
#include "BKE_sound.h"
#include "BKE_tracking.h"
@@ -1564,12 +1567,42 @@ void DepsgraphNodeBuilder::build_sound(bSound *sound)
if (built_map_.checkIsBuiltAndTag(sound)) {
return;
}
- /* Placeholder so we can add relations and tag ID node for update. */
- add_operation_node(&sound->id, NodeType::AUDIO, OperationCode::SOUND_EVAL);
+ add_id_node(&sound->id);
+ bSound *sound_cow = get_cow_datablock(sound);
+ add_operation_node(&sound->id,
+ NodeType::AUDIO,
+ OperationCode::SOUND_EVAL,
+ function_bind(BKE_sound_evaluate, _1, bmain_, sound_cow));
build_animdata(&sound->id);
build_parameters(&sound->id);
}
+void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene)
+{
+ if (scene->ed == NULL) {
+ return;
+ }
+ Scene *scene_cow = get_cow_datablock(scene_);
+ add_operation_node(&scene->id,
+ NodeType::SEQUENCER,
+ OperationCode::SEQUENCES_EVAL,
+ function_bind(BKE_scene_eval_sequencer_sequences, _1, scene_cow));
+ /* Make sure data for sequences is in the graph. */
+ Sequence *seq;
+ SEQ_BEGIN (scene->ed, seq) {
+ if (seq->sound != NULL) {
+ build_sound(seq->sound);
+ }
+ /* TODO(sergey): Movie clip, scene, camera, mask. */
+ }
+ SEQ_END;
+}
+
+void DepsgraphNodeBuilder::build_scene_audio(Scene *scene)
+{
+ add_operation_node(&scene->id, NodeType::AUDIO, OperationCode::SOUND_EVAL);
+}
+
/* **** ID traversal callbacks functions **** */
void DepsgraphNodeBuilder::modifier_walk(void *user_data,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index c3a04a9ad88..896854870de 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -212,6 +212,8 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
void build_lightprobe(LightProbe *probe);
void build_speaker(Speaker *speaker);
void build_sound(bSound *sound);
+ void build_scene_sequencer(Scene *scene);
+ void build_scene_audio(Scene *scene);
/* Per-ID information about what was already in the dependency graph.
* Allows to re-use certain values, to speed up following evaluation. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
index 64f841d56fc..ef73de517e8 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
@@ -31,13 +31,19 @@ void DepsgraphNodeBuilder::build_scene_render(Scene *scene)
{
scene_ = scene;
const bool build_compositor = (scene->r.scemode & R_DOCOMP);
+ const bool build_sequencer = (scene->r.scemode & R_DOSEQ);
IDNode *id_node = add_id_node(&scene->id);
id_node->linked_state = DEG_ID_LINKED_DIRECTLY;
add_time_source();
+ build_animdata(&scene->id);
build_scene_parameters(scene);
+ build_scene_audio(scene);
if (build_compositor) {
build_scene_compositor(scene);
}
+ if (build_sequencer) {
+ build_scene_sequencer(scene);
+ }
}
void DepsgraphNodeBuilder::build_scene_parameters(Scene *scene)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index 4e3fdfc6c19..2f6b8c0ba6b 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -146,6 +146,11 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
build_collection(NULL, fls->group);
}
}
+ /* Sequencer. */
+ if (linked_state == DEG_ID_LINKED_DIRECTLY) {
+ build_scene_audio(scene);
+ build_scene_sequencer(scene);
+ }
/* Collections. */
add_operation_node(
&scene->id,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 54d5223497e..a1f8c59f936 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -58,6 +58,7 @@ extern "C" {
#include "DNA_object_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "DNA_speaker_types.h"
#include "DNA_texture_types.h"
@@ -84,6 +85,7 @@ extern "C" {
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
+#include "BKE_sequencer.h"
#include "BKE_shader_fx.h"
#include "BKE_shrinkwrap.h"
#include "BKE_sound.h"
@@ -2324,6 +2326,35 @@ void DepsgraphRelationBuilder::build_sound(bSound *sound)
build_parameters(&sound->id);
}
+void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)
+{
+ if (scene->ed == NULL) {
+ return;
+ }
+ /* Make sure dependencies from sequences data goes to the sequencer evaluation. */
+ ComponentKey sequencer_key(&scene->id, NodeType::SEQUENCER);
+ Sequence *seq;
+ bool has_audio_strips = false;
+ SEQ_BEGIN (scene->ed, seq) {
+ if (seq->sound != NULL) {
+ build_sound(seq->sound);
+ ComponentKey sound_key(&seq->sound->id, NodeType::AUDIO);
+ add_relation(sound_key, sequencer_key, "Sound -> Sequencer");
+ has_audio_strips = true;
+ }
+ /* TODO(sergey): Movie clip, scene, camera, mask. */
+ }
+ SEQ_END;
+ if (has_audio_strips) {
+ ComponentKey scene_audio_key(&scene->id, NodeType::AUDIO);
+ add_relation(sequencer_key, scene_audio_key, "Sequencer -> Audio");
+ }
+}
+
+void DepsgraphRelationBuilder::build_scene_audio(Scene * /*scene*/)
+{
+}
+
void DepsgraphRelationBuilder::build_copy_on_write_relations()
{
for (IDNode *id_node : graph_->id_nodes) {
@@ -2387,6 +2418,10 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
(id_type == ID_CF && comp_node->type == NodeType::CACHE)) {
rel_flag &= ~RELATION_FLAG_NO_FLUSH;
}
+ /* TODO(sergey): Needs better solution for this. */
+ if (id_type == ID_SO) {
+ rel_flag &= ~RELATION_FLAG_NO_FLUSH;
+ }
/* Notes on exceptions:
* - Parameters component is where drivers are living. Changing any
* of the (custom) properties in the original datablock (even the
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 7d302092119..55295c8b075 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -41,6 +41,7 @@
#include "intern/builder/deg_builder_rna.h"
#include "intern/depsgraph.h"
#include "intern/node/deg_node.h"
+#include "intern/node/deg_node_id.h"
#include "intern/node/deg_node_component.h"
#include "intern/node/deg_node_operation.h"
@@ -200,7 +201,9 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
void build_scene_compositor(Scene *scene);
void build_layer_collections(ListBase *lb);
- void build_view_layer(Scene *scene, ViewLayer *view_layer);
+ void build_view_layer(Scene *scene,
+ ViewLayer *view_layer,
+ eDepsNode_LinkedState_Type linked_state);
void build_collection(LayerCollection *from_layer_collection,
Object *object,
Collection *collection);
@@ -270,6 +273,8 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
void build_lightprobe(LightProbe *probe);
void build_speaker(Speaker *speaker);
void build_sound(bSound *sound);
+ void build_scene_sequencer(Scene *scene);
+ void build_scene_audio(Scene *scene);
void build_nested_datablock(ID *owner, ID *id);
void build_nested_nodetree(ID *owner, bNodeTree *ntree);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
index 26bb1bd3d2a..46e8b8e7acc 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
@@ -31,10 +31,16 @@ void DepsgraphRelationBuilder::build_scene_render(Scene *scene)
{
scene_ = scene;
const bool build_compositor = (scene->r.scemode & R_DOCOMP);
+ const bool build_sequencer = (scene->r.scemode & R_DOSEQ);
build_scene_parameters(scene);
+ build_animdata(&scene->id);
+ build_scene_audio(scene);
if (build_compositor) {
build_scene_compositor(scene);
}
+ if (build_sequencer) {
+ build_scene_sequencer(scene);
+ }
}
void DepsgraphRelationBuilder::build_scene_parameters(Scene *scene)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index b832473bde9..4c55e4a137a 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -75,7 +75,9 @@ void DepsgraphRelationBuilder::build_layer_collections(ListBase *lb)
}
}
-void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_layer)
+void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
+ ViewLayer *view_layer,
+ eDepsNode_LinkedState_Type linked_state)
{
/* Setup currently building context. */
scene_ = scene;
@@ -132,10 +134,15 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la
&scene->id, NodeType::LAYER_COLLECTIONS, OperationCode::VIEW_LAYER_EVAL);
OperationKey scene_eval_key(&scene->id, NodeType::PARAMETERS, OperationCode::SCENE_EVAL);
add_relation(scene_view_layer_key, scene_eval_key, "View Layer -> Scene Eval");
+ /* Sequencer. */
+ if (linked_state == DEG_ID_LINKED_DIRECTLY) {
+ build_scene_audio(scene);
+ build_scene_sequencer(scene);
+ }
/* Build all set scenes. */
if (scene->set != NULL) {
ViewLayer *set_view_layer = BKE_view_layer_default_render(scene->set);
- build_view_layer(scene->set, set_view_layer);
+ build_view_layer(scene->set, set_view_layer, DEG_ID_LINKED_VIA_SET);
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index 403c9cfc778..b7efdc0fa3f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -329,10 +329,8 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
return node_identifier;
}
else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
- const Sequence *seq = static_cast<Sequence *>(ptr->data);
/* Sequencer strip */
node_identifier.type = NodeType::SEQUENCER;
- node_identifier.component_name = seq->name;
return node_identifier;
}
else if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index cf1ebccc6c6..bfb0a2aade4 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -272,7 +272,7 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph,
/* Hook up relationships between operations - to determine evaluation order. */
DEG::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache);
relation_builder.begin_build();
- relation_builder.build_view_layer(scene, view_layer);
+ relation_builder.build_view_layer(scene, view_layer, DEG::DEG_ID_LINKED_DIRECTLY);
relation_builder.build_copy_on_write_relations();
/* Finalize building. */
graph_build_finalize_common(deg_graph, bmain);
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index 0345f294860..865da20e6fd 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -160,6 +160,19 @@ Scene *DEG_get_evaluated_scene(const Depsgraph *graph)
return scene_cow;
}
+Scene *DEG_get_evaluated_scene_if_exists(const Depsgraph *graph)
+{
+ if (graph == NULL) {
+ return NULL;
+ }
+ const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
+ Scene *scene_cow = deg_graph->scene_cow;
+ if (scene_cow == NULL || !DEG::deg_copy_on_write_is_expanded(&scene_cow->id)) {
+ return NULL;
+ }
+ return scene_cow;
+}
+
ViewLayer *DEG_get_evaluated_view_layer(const Depsgraph *graph)
{
const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index c2cc15460d1..9f48dd2b47e 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -215,6 +215,16 @@ void depsgraph_tag_to_component_opcode(const ID *id,
/* There is no such node in depsgraph, this tag is to be handled
* separately. */
break;
+ case ID_RECALC_SEQUENCER_STRIPS:
+ *component_type = NodeType::SEQUENCER;
+ break;
+ case ID_RECALC_AUDIO_SEEK:
+ case ID_RECALC_AUDIO_FPS:
+ case ID_RECALC_AUDIO_VOLUME:
+ case ID_RECALC_AUDIO_MUTE:
+ case ID_RECALC_AUDIO_LISTENER:
+ *component_type = NodeType::AUDIO;
+ break;
case ID_RECALC_ALL:
case ID_RECALC_PSYS_ALL:
BLI_assert(!"Should not happen");
@@ -633,6 +643,18 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag)
return "POINT_CACHE";
case ID_RECALC_EDITORS:
return "EDITORS";
+ case ID_RECALC_SEQUENCER_STRIPS:
+ return "SEQUENCER_STRIPS";
+ case ID_RECALC_AUDIO_SEEK:
+ return "AUDIO_SEEK";
+ case ID_RECALC_AUDIO_FPS:
+ return "AUDIO_FPS";
+ case ID_RECALC_AUDIO_VOLUME:
+ return "AUDIO_VOLUME";
+ case ID_RECALC_AUDIO_MUTE:
+ return "AUDIO_MUTE";
+ case ID_RECALC_AUDIO_LISTENER:
+ return "AUDIO_LISTENER";
case ID_RECALC_ALL:
return "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 4bc05bc9185..ef2862ab387 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
@@ -59,6 +59,8 @@ extern "C" {
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
+#include "DNA_sound_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
@@ -84,6 +86,8 @@ extern "C" {
#include "BKE_library_query.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_sequencer.h"
+#include "BKE_sound.h"
}
#include "intern/depsgraph.h"
@@ -467,6 +471,25 @@ 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 != NULL) {
+ 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 != NULL) {
+ update_sequence_orig_pointers(&scene_orig->ed->seqbase, &scene_cow->ed->seqbase);
+ }
+}
+
/* Check whether given ID is expanded or still a shallow copy. */
BLI_INLINE bool check_datablock_expanded(const ID *id_cow)
{
@@ -751,6 +774,7 @@ void update_id_after_copy(const Depsgraph *depsgraph,
scene_cow->toolsettings = scene_orig->toolsettings;
scene_cow->eevee.light_cache = scene_orig->eevee.light_cache;
scene_setup_view_layers_after_remap(depsgraph, id_node, reinterpret_cast<Scene *>(id_cow));
+ update_scene_orig_pointers(scene_orig, scene_cow);
break;
}
default:
@@ -881,6 +905,205 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
namespace {
+/* Backup of sequencer strips runtime data. */
+
+/* Backup of a single strip. */
+class SequenceBackup {
+ public:
+ SequenceBackup()
+ {
+ reset();
+ }
+
+ inline void reset()
+ {
+ scene_sound = NULL;
+ }
+
+ void init_from_sequence(Sequence *sequence)
+ {
+ scene_sound = sequence->scene_sound;
+
+ sequence->scene_sound = NULL;
+ }
+
+ void restore_to_sequence(Sequence *sequence)
+ {
+ sequence->scene_sound = scene_sound;
+ reset();
+ }
+
+ inline bool isEmpty() const
+ {
+ return (scene_sound == NULL);
+ }
+
+ void *scene_sound;
+};
+
+class SequencerBackup {
+ public:
+ SequencerBackup();
+
+ void init_from_scene(Scene *scene);
+ void restore_to_scene(Scene *scene);
+
+ typedef map<Sequence *, SequenceBackup> SequencesBackupMap;
+ SequencesBackupMap sequences_backup;
+};
+
+SequencerBackup::SequencerBackup()
+{
+}
+
+void SequencerBackup::init_from_scene(Scene *scene)
+{
+ Sequence *sequence;
+ SEQ_BEGIN (scene->ed, sequence) {
+ SequenceBackup sequence_backup;
+ sequence_backup.init_from_sequence(sequence);
+ if (!sequence_backup.isEmpty()) {
+ sequences_backup.insert(make_pair(sequence->orig_sequence, sequence_backup));
+ }
+ }
+ SEQ_END;
+}
+
+void SequencerBackup::restore_to_scene(Scene *scene)
+{
+ Sequence *sequence;
+ SEQ_BEGIN (scene->ed, sequence) {
+ SequencesBackupMap::iterator it = sequences_backup.find(sequence->orig_sequence);
+ if (it == sequences_backup.end()) {
+ continue;
+ }
+ SequenceBackup &sequence_backup = it->second;
+ sequence_backup.restore_to_sequence(sequence);
+ }
+ SEQ_END;
+ /* Cleanup audio while the scene is still known. */
+ for (SequencesBackupMap::value_type &it : sequences_backup) {
+ SequenceBackup &sequence_backup = it.second;
+ if (sequence_backup.scene_sound != NULL) {
+ BKE_sound_remove_scene_sound(scene, sequence_backup.scene_sound);
+ }
+ }
+}
+
+/* Backup of scene runtime data. */
+
+class SceneBackup {
+ public:
+ SceneBackup();
+
+ void reset();
+
+ void init_from_scene(Scene *scene);
+ void restore_to_scene(Scene *scene);
+
+ /* Sound/audio related pointers of the scene itself.
+ *
+ * NOTE: Scene can not disappear after relations update, because otherwise the entire dependency
+ * graph will be gone. This means we don't need to compare original scene pointer, or worry about
+ * freeing those if they cant' be restorted: we just copy them over to a new scene. */
+ void *sound_scene;
+ void *playback_handle;
+ void *sound_scrub_handle;
+ void *speaker_handles;
+
+ SequencerBackup sequencer_backup;
+};
+
+SceneBackup::SceneBackup()
+{
+ reset();
+}
+
+void SceneBackup::reset()
+{
+ sound_scene = NULL;
+ playback_handle = NULL;
+ sound_scrub_handle = NULL;
+ speaker_handles = NULL;
+}
+
+void SceneBackup::init_from_scene(Scene *scene)
+{
+ sound_scene = scene->sound_scene;
+ playback_handle = scene->playback_handle;
+ sound_scrub_handle = scene->sound_scrub_handle;
+ speaker_handles = scene->speaker_handles;
+
+ /* Clear pointers stored in the scene, so they are not freed when copied-on-written datablock
+ * is freed for re-allocation. */
+ scene->sound_scene = NULL;
+ scene->playback_handle = NULL;
+ scene->sound_scrub_handle = NULL;
+ scene->speaker_handles = NULL;
+
+ sequencer_backup.init_from_scene(scene);
+}
+
+void SceneBackup::restore_to_scene(Scene *scene)
+{
+ scene->sound_scene = sound_scene;
+ scene->playback_handle = playback_handle;
+ scene->sound_scrub_handle = sound_scrub_handle;
+ scene->speaker_handles = speaker_handles;
+
+ sequencer_backup.restore_to_scene(scene);
+
+ reset();
+}
+
+/* Backup of sound datablocks runtime data. */
+
+class SoundBackup {
+ public:
+ SoundBackup();
+
+ void reset();
+
+ void init_from_sound(bSound *sound);
+ void restore_to_sound(bSound *sound);
+
+ void *cache;
+ void *waveform;
+ void *playback_handle;
+};
+
+SoundBackup::SoundBackup()
+{
+ reset();
+}
+
+void SoundBackup::reset()
+{
+ cache = NULL;
+ waveform = NULL;
+ playback_handle = NULL;
+}
+
+void SoundBackup::init_from_sound(bSound *sound)
+{
+ cache = sound->cache;
+ waveform = sound->waveform;
+ playback_handle = sound->playback_handle;
+
+ sound->cache = NULL;
+ sound->waveform = NULL;
+ sound->playback_handle = NULL;
+}
+
+void SoundBackup::restore_to_sound(bSound *sound)
+{
+ sound->cache = cache;
+ sound->waveform = waveform;
+ sound->playback_handle = playback_handle;
+
+ reset();
+}
+
/* Identifier used to match modifiers to backup/restore their runtime data.
* Identification is happening using original modifier data pointer and the
* modifier type.
@@ -921,7 +1144,8 @@ typedef map<ModifierDataBackupID, void *> ModifierRuntimeDataBackup;
/* Storage for backed up pose channel runtime data. */
typedef map<bPoseChannel *, bPoseChannel_Runtime> PoseChannelRuntimeDataBackup;
-struct ObjectRuntimeBackup {
+class ObjectRuntimeBackup {
+ public:
ObjectRuntimeBackup() : base_flag(0), base_local_view_bits(0)
{
/* TODO(sergey): Use something like BKE_object_runtime_reset(). */
@@ -1099,6 +1323,8 @@ class RuntimeBackup {
/* Restore fields to the given ID. */
void restore_to_id(ID *id);
+ SceneBackup scene_backup;
+ SoundBackup sound_backup;
ObjectRuntimeBackup object_backup;
DrawDataList drawdata_backup;
DrawDataList *drawdata_ptr;
@@ -1114,6 +1340,12 @@ void RuntimeBackup::init_from_id(ID *id)
case ID_OB:
object_backup.init_from_object(reinterpret_cast<Object *>(id));
break;
+ case ID_SCE:
+ scene_backup.init_from_scene(reinterpret_cast<Scene *>(id));
+ break;
+ case ID_SO:
+ sound_backup.init_from_sound(reinterpret_cast<bSound *>(id));
+ break;
default:
break;
}
@@ -1133,6 +1365,12 @@ void RuntimeBackup::restore_to_id(ID *id)
case ID_OB:
object_backup.restore_to_object(reinterpret_cast<Object *>(id));
break;
+ case ID_SCE:
+ scene_backup.restore_to_scene(reinterpret_cast<Scene *>(id));
+ break;
+ case ID_SO:
+ sound_backup.restore_to_sound(reinterpret_cast<bSound *>(id));
+ break;
default:
break;
}
@@ -1321,9 +1559,7 @@ bool deg_copy_on_write_is_expanded(const ID *id_cow)
bool deg_copy_on_write_is_needed(const ID *id_orig)
{
const ID_Type id_type = GS(id_orig->name);
- /* TODO(sergey): Make Sound copyable. It is here only because the code for dependency graph is
- * being work in progress. */
- return !ELEM(id_type, ID_IM, ID_SO);
+ return !ELEM(id_type, ID_IM);
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc
index 62a61675bcc..09a761d282f 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc
@@ -185,6 +185,9 @@ const char *operationCodeAsString(OperationCode opcode)
/* Generic datablock. */
case OperationCode::GENERIC_DATABLOCK_UPDATE:
return "GENERIC_DATABLOCK_UPDATE";
+ /* Sequencer. */
+ case OperationCode::SEQUENCES_EVAL:
+ return "SEQUENCES_EVAL";
/* instancing/duplication. */
case OperationCode::DUPLI:
return "DUPLI";
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h
index ab6242a6196..8fc565cfa77 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.h
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.h
@@ -185,12 +185,16 @@ enum class OperationCode {
/* Images. -------------------------------------------------------------- */
IMAGE_ANIMATION,
- /* Synchronization clips. ----------------------------------------------- */
+ /* Synchronization. ----------------------------------------------------- */
SYNCHRONIZE_TO_ORIGINAL,
/* Generic datablock ---------------------------------------------------- */
GENERIC_DATABLOCK_UPDATE,
+ /* Sequencer. ----------------------------------------------------------- */
+
+ SEQUENCES_EVAL,
+
/* Duplication/instancing system. --------------------------------------- */
DUPLI,
};