Depsgraph: Refactor, split runtime backup into smaller files
It started to be a long code of all various cases in a single file, which started to be really confusing.
This commit is contained in:
@@ -58,6 +58,15 @@ set(SRC
|
||||
intern/eval/deg_eval.cc
|
||||
intern/eval/deg_eval_copy_on_write.cc
|
||||
intern/eval/deg_eval_flush.cc
|
||||
intern/eval/deg_eval_runtime_backup.cc
|
||||
intern/eval/deg_eval_runtime_backup_modifier.cc
|
||||
intern/eval/deg_eval_runtime_backup_movieclip.cc
|
||||
intern/eval/deg_eval_runtime_backup_object.cc
|
||||
intern/eval/deg_eval_runtime_backup_pose.cc
|
||||
intern/eval/deg_eval_runtime_backup_scene.cc
|
||||
intern/eval/deg_eval_runtime_backup_sequence.cc
|
||||
intern/eval/deg_eval_runtime_backup_sequencer.cc
|
||||
intern/eval/deg_eval_runtime_backup_sound.cc
|
||||
intern/eval/deg_eval_stats.cc
|
||||
intern/node/deg_node.cc
|
||||
intern/node/deg_node_component.cc
|
||||
@@ -98,6 +107,15 @@ set(SRC
|
||||
intern/eval/deg_eval.h
|
||||
intern/eval/deg_eval_copy_on_write.h
|
||||
intern/eval/deg_eval_flush.h
|
||||
intern/eval/deg_eval_runtime_backup.h
|
||||
intern/eval/deg_eval_runtime_backup_modifier.h
|
||||
intern/eval/deg_eval_runtime_backup_movieclip.h
|
||||
intern/eval/deg_eval_runtime_backup_object.h
|
||||
intern/eval/deg_eval_runtime_backup_pose.h
|
||||
intern/eval/deg_eval_runtime_backup_scene.h
|
||||
intern/eval/deg_eval_runtime_backup_sequence.h
|
||||
intern/eval/deg_eval_runtime_backup_sequencer.h
|
||||
intern/eval/deg_eval_runtime_backup_sound.h
|
||||
intern/eval/deg_eval_stats.h
|
||||
intern/node/deg_node.h
|
||||
intern/node/deg_node_component.h
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
/* Enable special; trickery to treat nested owned IDs (such as nodetree of
|
||||
/* Enable special trickery to treat nested owned IDs (such as nodetree of
|
||||
* material) to be handled in same way as "real" data-blocks, even tho some
|
||||
* internal BKE routines doesn't treat them like that.
|
||||
*
|
||||
@@ -95,6 +95,7 @@ extern "C" {
|
||||
#include "intern/depsgraph.h"
|
||||
#include "intern/builder/deg_builder.h"
|
||||
#include "intern/builder/deg_builder_nodes.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup.h"
|
||||
#include "intern/node/deg_node.h"
|
||||
#include "intern/node/deg_node_id.h"
|
||||
|
||||
@@ -945,545 +946,6 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
|
||||
return deg_expand_copy_on_write_datablock(depsgraph, id_node, node_builder, create_placeholders);
|
||||
}
|
||||
|
||||
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 restored: we just copy them over to a new scene. */
|
||||
void *sound_scene;
|
||||
void *playback_handle;
|
||||
void *sound_scrub_handle;
|
||||
void *speaker_handles;
|
||||
float rigidbody_last_time;
|
||||
|
||||
SequencerBackup sequencer_backup;
|
||||
};
|
||||
|
||||
SceneBackup::SceneBackup()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void SceneBackup::reset()
|
||||
{
|
||||
sound_scene = NULL;
|
||||
playback_handle = NULL;
|
||||
sound_scrub_handle = NULL;
|
||||
speaker_handles = NULL;
|
||||
rigidbody_last_time = -1;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (scene->rigidbody_world != NULL) {
|
||||
rigidbody_last_time = scene->rigidbody_world->ltime;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
if (scene->rigidbody_world != NULL) {
|
||||
scene->rigidbody_world->ltime = rigidbody_last_time;
|
||||
}
|
||||
|
||||
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.
|
||||
* It is not enough to only pointer, since it's possible to have a situation
|
||||
* when modifier is removed and a new one added, and due to memory allocation
|
||||
* policy they might have same pointer.
|
||||
* By adding type into matching we are at least ensuring that modifier will not
|
||||
* try to interpret runtime data created by another modifier type. */
|
||||
class ModifierDataBackupID {
|
||||
public:
|
||||
ModifierDataBackupID() : ModifierDataBackupID(NULL, eModifierType_None)
|
||||
{
|
||||
}
|
||||
|
||||
ModifierDataBackupID(ModifierData *modifier_data, ModifierType type)
|
||||
: modifier_data(modifier_data), type(type)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator<(const ModifierDataBackupID &other) const
|
||||
{
|
||||
if (modifier_data < other.modifier_data) {
|
||||
return true;
|
||||
}
|
||||
if (modifier_data == other.modifier_data) {
|
||||
return static_cast<int>(type) < static_cast<int>(other.type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ModifierData *modifier_data;
|
||||
ModifierType type;
|
||||
};
|
||||
|
||||
/* Storage for backed up runtime modifier data. */
|
||||
typedef map<ModifierDataBackupID, void *> ModifierRuntimeDataBackup;
|
||||
|
||||
/* Storage for backed up pose channel runtime data. */
|
||||
typedef map<bPoseChannel *, bPoseChannel_Runtime> PoseChannelRuntimeDataBackup;
|
||||
|
||||
class ObjectRuntimeBackup {
|
||||
public:
|
||||
ObjectRuntimeBackup() : base_flag(0), base_local_view_bits(0)
|
||||
{
|
||||
/* TODO(sergey): Use something like BKE_object_runtime_reset(). */
|
||||
memset(&runtime, 0, sizeof(runtime));
|
||||
}
|
||||
|
||||
/* Make a backup of object's evaluation runtime data, additionally
|
||||
* make object to be safe for free without invalidating backed up
|
||||
* pointers. */
|
||||
void init_from_object(Object *object);
|
||||
void backup_modifier_runtime_data(Object *object);
|
||||
void backup_pose_channel_runtime_data(Object *object);
|
||||
|
||||
/* Restore all fields to the given object. */
|
||||
void restore_to_object(Object *object);
|
||||
/* NOTE: Will free all runtime data which has not been restored. */
|
||||
void restore_modifier_runtime_data(Object *object);
|
||||
void restore_pose_channel_runtime_data(Object *object);
|
||||
|
||||
Object_Runtime runtime;
|
||||
short base_flag;
|
||||
unsigned short base_local_view_bits;
|
||||
ModifierRuntimeDataBackup modifier_runtime_data;
|
||||
PoseChannelRuntimeDataBackup pose_channel_runtime_data;
|
||||
};
|
||||
|
||||
void ObjectRuntimeBackup::init_from_object(Object *object)
|
||||
{
|
||||
/* Store evaluated mesh and curve_cache, and make sure we don't free it. */
|
||||
Mesh *mesh_eval = object->runtime.mesh_eval;
|
||||
runtime = object->runtime;
|
||||
BKE_object_runtime_reset(object);
|
||||
/* Keep bbox (for now at least). */
|
||||
object->runtime.bb = runtime.bb;
|
||||
/* Object update will override actual object->data to an evaluated version.
|
||||
* Need to make sure we don't have data set to evaluated one before free
|
||||
* anything. */
|
||||
if (mesh_eval != NULL && object->data == mesh_eval) {
|
||||
object->data = runtime.mesh_orig;
|
||||
}
|
||||
/* Make a backup of base flags. */
|
||||
base_flag = object->base_flag;
|
||||
base_local_view_bits = object->base_local_view_bits;
|
||||
/* Backup tuntime data of all modifiers. */
|
||||
backup_modifier_runtime_data(object);
|
||||
/* Backup runtime data of all pose channels. */
|
||||
backup_pose_channel_runtime_data(object);
|
||||
}
|
||||
|
||||
inline ModifierDataBackupID create_modifier_data_id(const ModifierData *modifier_data)
|
||||
{
|
||||
return ModifierDataBackupID(modifier_data->orig_modifier_data,
|
||||
static_cast<ModifierType>(modifier_data->type));
|
||||
}
|
||||
|
||||
void ObjectRuntimeBackup::backup_modifier_runtime_data(Object *object)
|
||||
{
|
||||
LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
|
||||
if (modifier_data->runtime == NULL) {
|
||||
continue;
|
||||
}
|
||||
BLI_assert(modifier_data->orig_modifier_data != NULL);
|
||||
ModifierDataBackupID modifier_data_id = create_modifier_data_id(modifier_data);
|
||||
modifier_runtime_data.insert(make_pair(modifier_data_id, modifier_data->runtime));
|
||||
modifier_data->runtime = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectRuntimeBackup::backup_pose_channel_runtime_data(Object *object)
|
||||
{
|
||||
if (object->pose != NULL) {
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
|
||||
/* This is NULL in Edit mode. */
|
||||
if (pchan->orig_pchan != NULL) {
|
||||
pose_channel_runtime_data[pchan->orig_pchan] = pchan->runtime;
|
||||
BKE_pose_channel_runtime_reset(&pchan->runtime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectRuntimeBackup::restore_to_object(Object *object)
|
||||
{
|
||||
Mesh *mesh_orig = object->runtime.mesh_orig;
|
||||
BoundBox *bb = object->runtime.bb;
|
||||
object->runtime = runtime;
|
||||
object->runtime.mesh_orig = mesh_orig;
|
||||
object->runtime.bb = bb;
|
||||
if (object->type == OB_MESH && object->runtime.mesh_eval != NULL) {
|
||||
if (object->id.recalc & ID_RECALC_GEOMETRY) {
|
||||
/* If geometry is tagged for update it means, that part of
|
||||
* evaluated mesh are not valid anymore. In this case we can not
|
||||
* have any "persistent" pointers to point to an invalid data.
|
||||
*
|
||||
* We restore object's data datablock to an original copy of
|
||||
* that datablock. */
|
||||
object->data = mesh_orig;
|
||||
|
||||
/* After that, immediately free the invalidated caches. */
|
||||
BKE_object_free_derived_caches(object);
|
||||
}
|
||||
else {
|
||||
Mesh *mesh_eval = object->runtime.mesh_eval;
|
||||
/* Do same thing as object update: override actual object data
|
||||
* pointer with evaluated datablock. */
|
||||
object->data = mesh_eval;
|
||||
/* Evaluated mesh simply copied edit_mesh pointer from
|
||||
* original mesh during update, need to make sure no dead
|
||||
* pointers are left behind. */
|
||||
mesh_eval->edit_mesh = mesh_orig->edit_mesh;
|
||||
}
|
||||
}
|
||||
object->base_flag = base_flag;
|
||||
object->base_local_view_bits = base_local_view_bits;
|
||||
/* Restore modifier's runtime data.
|
||||
* NOTE: Data of unused modifiers will be freed there. */
|
||||
restore_modifier_runtime_data(object);
|
||||
restore_pose_channel_runtime_data(object);
|
||||
}
|
||||
|
||||
void ObjectRuntimeBackup::restore_modifier_runtime_data(Object *object)
|
||||
{
|
||||
LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
|
||||
BLI_assert(modifier_data->orig_modifier_data != NULL);
|
||||
ModifierDataBackupID modifier_data_id = create_modifier_data_id(modifier_data);
|
||||
ModifierRuntimeDataBackup::iterator runtime_data_iterator = modifier_runtime_data.find(
|
||||
modifier_data_id);
|
||||
if (runtime_data_iterator != modifier_runtime_data.end()) {
|
||||
modifier_data->runtime = runtime_data_iterator->second;
|
||||
runtime_data_iterator->second = NULL;
|
||||
}
|
||||
}
|
||||
for (ModifierRuntimeDataBackup::value_type value : modifier_runtime_data) {
|
||||
const ModifierDataBackupID modifier_data_id = value.first;
|
||||
void *runtime = value.second;
|
||||
if (value.second == NULL) {
|
||||
continue;
|
||||
}
|
||||
const ModifierTypeInfo *modifier_type_info = modifierType_getInfo(modifier_data_id.type);
|
||||
BLI_assert(modifier_type_info != NULL);
|
||||
modifier_type_info->freeRuntimeData(runtime);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectRuntimeBackup::restore_pose_channel_runtime_data(Object *object)
|
||||
{
|
||||
if (object->pose != NULL) {
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
|
||||
/* This is NULL in Edit mode. */
|
||||
if (pchan->orig_pchan != NULL) {
|
||||
PoseChannelRuntimeDataBackup::iterator runtime_data_iterator =
|
||||
pose_channel_runtime_data.find(pchan->orig_pchan);
|
||||
if (runtime_data_iterator != pose_channel_runtime_data.end()) {
|
||||
pchan->runtime = runtime_data_iterator->second;
|
||||
pose_channel_runtime_data.erase(runtime_data_iterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PoseChannelRuntimeDataBackup::value_type &value : pose_channel_runtime_data) {
|
||||
BKE_pose_channel_runtime_free(&value.second);
|
||||
}
|
||||
}
|
||||
|
||||
/* Backup of movie clip runtime data. */
|
||||
|
||||
class MovieClipBackup {
|
||||
public:
|
||||
MovieClipBackup();
|
||||
|
||||
void reset();
|
||||
|
||||
void init_from_movieclip(MovieClip *movieclip);
|
||||
void restore_to_movieclip(MovieClip *movieclip);
|
||||
|
||||
struct anim *anim;
|
||||
struct MovieClipCache *cache;
|
||||
};
|
||||
|
||||
MovieClipBackup::MovieClipBackup()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void MovieClipBackup::reset()
|
||||
{
|
||||
anim = NULL;
|
||||
cache = NULL;
|
||||
}
|
||||
|
||||
void MovieClipBackup::init_from_movieclip(MovieClip *movieclip)
|
||||
{
|
||||
anim = movieclip->anim;
|
||||
cache = movieclip->cache;
|
||||
/* Clear pointers stored in the movie clip, so they are not freed when copied-on-written
|
||||
* datablock is freed for re-allocation. */
|
||||
movieclip->anim = NULL;
|
||||
movieclip->cache = NULL;
|
||||
}
|
||||
|
||||
void MovieClipBackup::restore_to_movieclip(MovieClip *movieclip)
|
||||
{
|
||||
movieclip->anim = anim;
|
||||
movieclip->cache = cache;
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
class RuntimeBackup {
|
||||
public:
|
||||
RuntimeBackup() : drawdata_ptr(NULL)
|
||||
{
|
||||
drawdata_backup.first = drawdata_backup.last = NULL;
|
||||
}
|
||||
|
||||
/* NOTE: Will reset all runbtime fields which has been backed up to NULL. */
|
||||
void init_from_id(ID *id);
|
||||
|
||||
/* 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;
|
||||
MovieClipBackup movieclip_backup;
|
||||
};
|
||||
|
||||
void RuntimeBackup::init_from_id(ID *id)
|
||||
{
|
||||
if (!check_datablock_expanded(id)) {
|
||||
return;
|
||||
}
|
||||
const ID_Type id_type = GS(id->name);
|
||||
switch (id_type) {
|
||||
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;
|
||||
case ID_MC:
|
||||
movieclip_backup.init_from_movieclip(reinterpret_cast<MovieClip *>(id));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Note that we never free GPU draw data from here since that's not
|
||||
* safe for threading and draw data is likely to be re-used. */
|
||||
drawdata_ptr = DRW_drawdatalist_from_id(id);
|
||||
if (drawdata_ptr != NULL) {
|
||||
drawdata_backup = *drawdata_ptr;
|
||||
drawdata_ptr->first = drawdata_ptr->last = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeBackup::restore_to_id(ID *id)
|
||||
{
|
||||
const ID_Type id_type = GS(id->name);
|
||||
switch (id_type) {
|
||||
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;
|
||||
case ID_MC:
|
||||
movieclip_backup.restore_to_movieclip(reinterpret_cast<MovieClip *>(id));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (drawdata_ptr != NULL) {
|
||||
*drawdata_ptr = drawdata_backup;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, const IDNode *id_node)
|
||||
{
|
||||
const ID *id_orig = id_node->id_orig;
|
||||
@@ -1492,7 +954,7 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, const IDNode
|
||||
if (!deg_copy_on_write_is_needed(id_orig)) {
|
||||
return id_cow;
|
||||
}
|
||||
RuntimeBackup backup;
|
||||
RuntimeBackup backup(depsgraph);
|
||||
backup.init_from_id(id_cow);
|
||||
deg_free_copy_on_write_datablock(id_cow);
|
||||
deg_expand_copy_on_write_datablock(depsgraph, id_node);
|
||||
|
||||
101
source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
Normal file
101
source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2017 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup.h"
|
||||
|
||||
#include "intern/eval/deg_eval_copy_on_write.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
RuntimeBackup::RuntimeBackup(const Depsgraph *depsgraph)
|
||||
: scene_backup(depsgraph),
|
||||
sound_backup(depsgraph),
|
||||
object_backup(depsgraph),
|
||||
drawdata_ptr(NULL),
|
||||
movieclip_backup(depsgraph)
|
||||
{
|
||||
drawdata_backup.first = drawdata_backup.last = NULL;
|
||||
}
|
||||
|
||||
void RuntimeBackup::init_from_id(ID *id)
|
||||
{
|
||||
if (!deg_copy_on_write_is_expanded(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ID_Type id_type = GS(id->name);
|
||||
switch (id_type) {
|
||||
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;
|
||||
case ID_MC:
|
||||
movieclip_backup.init_from_movieclip(reinterpret_cast<MovieClip *>(id));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Note that we never free GPU draw data from here since that's not
|
||||
* safe for threading and draw data is likely to be re-used. */
|
||||
drawdata_ptr = DRW_drawdatalist_from_id(id);
|
||||
if (drawdata_ptr != NULL) {
|
||||
drawdata_backup = *drawdata_ptr;
|
||||
drawdata_ptr->first = drawdata_ptr->last = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeBackup::restore_to_id(ID *id)
|
||||
{
|
||||
const ID_Type id_type = GS(id->name);
|
||||
switch (id_type) {
|
||||
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;
|
||||
case ID_MC:
|
||||
movieclip_backup.restore_to_movieclip(reinterpret_cast<MovieClip *>(id));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (drawdata_ptr != NULL) {
|
||||
*drawdata_ptr = drawdata_backup;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DNA_ID.h"
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_movieclip.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup_object.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup_scene.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup_sound.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
struct Depsgraph;
|
||||
|
||||
class RuntimeBackup {
|
||||
public:
|
||||
explicit RuntimeBackup(const Depsgraph *depsgraph);
|
||||
|
||||
/* NOTE: Will reset all runtime fields which has been backed up to NULL. */
|
||||
void init_from_id(ID *id);
|
||||
|
||||
/* 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;
|
||||
MovieClipBackup movieclip_backup;
|
||||
};
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_modifier.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
ModifierDataBackupID::ModifierDataBackupID(const Depsgraph * /*depsgraph*/)
|
||||
: ModifierDataBackupID(NULL, eModifierType_None)
|
||||
{
|
||||
}
|
||||
|
||||
ModifierDataBackupID::ModifierDataBackupID(ModifierData *modifier_data, ModifierType type)
|
||||
: modifier_data(modifier_data), type(type)
|
||||
{
|
||||
}
|
||||
|
||||
bool ModifierDataBackupID::operator<(const ModifierDataBackupID &other) const
|
||||
{
|
||||
if (modifier_data < other.modifier_data) {
|
||||
return true;
|
||||
}
|
||||
if (modifier_data == other.modifier_data) {
|
||||
return static_cast<int>(type) < static_cast<int>(other.type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BKE_modifier.h"
|
||||
|
||||
#include "intern/depsgraph_type.h"
|
||||
|
||||
struct ModifierData;
|
||||
|
||||
namespace DEG {
|
||||
|
||||
struct Depsgraph;
|
||||
|
||||
/* Identifier used to match modifiers to backup/restore their runtime data.
|
||||
* Identification is happening using original modifier data pointer and the
|
||||
* modifier type.
|
||||
* It is not enough to only pointer, since it's possible to have a situation
|
||||
* when modifier is removed and a new one added, and due to memory allocation
|
||||
* policy they might have same pointer.
|
||||
* By adding type into matching we are at least ensuring that modifier will not
|
||||
* try to interpret runtime data created by another modifier type. */
|
||||
class ModifierDataBackupID {
|
||||
public:
|
||||
ModifierDataBackupID(const Depsgraph *depsgraph);
|
||||
ModifierDataBackupID(ModifierData *modifier_data, ModifierType type);
|
||||
|
||||
bool operator<(const ModifierDataBackupID &other) const;
|
||||
|
||||
ModifierData *modifier_data;
|
||||
ModifierType type;
|
||||
};
|
||||
|
||||
/* Storage for backed up runtime modifier data. */
|
||||
typedef map<ModifierDataBackupID, void *> ModifierRuntimeDataBackup;
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_movieclip.h"
|
||||
|
||||
#include "DNA_movieclip_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
MovieClipBackup::MovieClipBackup(const Depsgraph * /*depsgraph*/)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void MovieClipBackup::reset()
|
||||
{
|
||||
anim = NULL;
|
||||
cache = NULL;
|
||||
}
|
||||
|
||||
void MovieClipBackup::init_from_movieclip(MovieClip *movieclip)
|
||||
{
|
||||
anim = movieclip->anim;
|
||||
cache = movieclip->cache;
|
||||
/* Clear pointers stored in the movie clip, so they are not freed when copied-on-written
|
||||
* datablock is freed for re-allocation. */
|
||||
movieclip->anim = NULL;
|
||||
movieclip->cache = NULL;
|
||||
}
|
||||
|
||||
void MovieClipBackup::restore_to_movieclip(MovieClip *movieclip)
|
||||
{
|
||||
movieclip->anim = anim;
|
||||
movieclip->cache = cache;
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct anim;
|
||||
struct MovieClip;
|
||||
struct MovieClipCache;
|
||||
|
||||
namespace DEG {
|
||||
|
||||
struct Depsgraph;
|
||||
|
||||
/* Backup of movie clip runtime data. */
|
||||
class MovieClipBackup {
|
||||
public:
|
||||
MovieClipBackup(const Depsgraph *depsgraph);
|
||||
|
||||
void reset();
|
||||
|
||||
void init_from_movieclip(MovieClip *movieclip);
|
||||
void restore_to_movieclip(MovieClip *movieclip);
|
||||
|
||||
struct anim *anim;
|
||||
struct MovieClipCache *cache;
|
||||
};
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_object.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
ObjectRuntimeBackup::ObjectRuntimeBackup(const Depsgraph * /*depsgraph*/)
|
||||
: base_flag(0), base_local_view_bits(0)
|
||||
{
|
||||
/* TODO(sergey): Use something like BKE_object_runtime_reset(). */
|
||||
memset(&runtime, 0, sizeof(runtime));
|
||||
}
|
||||
|
||||
void ObjectRuntimeBackup::init_from_object(Object *object)
|
||||
{
|
||||
/* Store evaluated mesh and curve_cache, and make sure we don't free it. */
|
||||
Mesh *mesh_eval = object->runtime.mesh_eval;
|
||||
runtime = object->runtime;
|
||||
BKE_object_runtime_reset(object);
|
||||
/* Keep bbox (for now at least). */
|
||||
object->runtime.bb = runtime.bb;
|
||||
/* Object update will override actual object->data to an evaluated version.
|
||||
* Need to make sure we don't have data set to evaluated one before free
|
||||
* anything. */
|
||||
if (mesh_eval != NULL && object->data == mesh_eval) {
|
||||
object->data = runtime.mesh_orig;
|
||||
}
|
||||
/* Make a backup of base flags. */
|
||||
base_flag = object->base_flag;
|
||||
base_local_view_bits = object->base_local_view_bits;
|
||||
/* Backup tuntime data of all modifiers. */
|
||||
backup_modifier_runtime_data(object);
|
||||
/* Backup runtime data of all pose channels. */
|
||||
backup_pose_channel_runtime_data(object);
|
||||
}
|
||||
|
||||
inline ModifierDataBackupID create_modifier_data_id(const ModifierData *modifier_data)
|
||||
{
|
||||
return ModifierDataBackupID(modifier_data->orig_modifier_data,
|
||||
static_cast<ModifierType>(modifier_data->type));
|
||||
}
|
||||
|
||||
void ObjectRuntimeBackup::backup_modifier_runtime_data(Object *object)
|
||||
{
|
||||
LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
|
||||
if (modifier_data->runtime == NULL) {
|
||||
continue;
|
||||
}
|
||||
BLI_assert(modifier_data->orig_modifier_data != NULL);
|
||||
ModifierDataBackupID modifier_data_id = create_modifier_data_id(modifier_data);
|
||||
modifier_runtime_data.insert(make_pair(modifier_data_id, modifier_data->runtime));
|
||||
modifier_data->runtime = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectRuntimeBackup::backup_pose_channel_runtime_data(Object *object)
|
||||
{
|
||||
if (object->pose != NULL) {
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
|
||||
/* This is NULL in Edit mode. */
|
||||
if (pchan->orig_pchan != NULL) {
|
||||
pose_channel_runtime_data[pchan->orig_pchan] = pchan->runtime;
|
||||
BKE_pose_channel_runtime_reset(&pchan->runtime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectRuntimeBackup::restore_to_object(Object *object)
|
||||
{
|
||||
Mesh *mesh_orig = object->runtime.mesh_orig;
|
||||
BoundBox *bb = object->runtime.bb;
|
||||
object->runtime = runtime;
|
||||
object->runtime.mesh_orig = mesh_orig;
|
||||
object->runtime.bb = bb;
|
||||
if (object->type == OB_MESH && object->runtime.mesh_eval != NULL) {
|
||||
if (object->id.recalc & ID_RECALC_GEOMETRY) {
|
||||
/* If geometry is tagged for update it means, that part of
|
||||
* evaluated mesh are not valid anymore. In this case we can not
|
||||
* have any "persistent" pointers to point to an invalid data.
|
||||
*
|
||||
* We restore object's data datablock to an original copy of
|
||||
* that datablock. */
|
||||
object->data = mesh_orig;
|
||||
|
||||
/* After that, immediately free the invalidated caches. */
|
||||
BKE_object_free_derived_caches(object);
|
||||
}
|
||||
else {
|
||||
Mesh *mesh_eval = object->runtime.mesh_eval;
|
||||
/* Do same thing as object update: override actual object data
|
||||
* pointer with evaluated datablock. */
|
||||
object->data = mesh_eval;
|
||||
/* Evaluated mesh simply copied edit_mesh pointer from
|
||||
* original mesh during update, need to make sure no dead
|
||||
* pointers are left behind. */
|
||||
mesh_eval->edit_mesh = mesh_orig->edit_mesh;
|
||||
}
|
||||
}
|
||||
object->base_flag = base_flag;
|
||||
object->base_local_view_bits = base_local_view_bits;
|
||||
/* Restore modifier's runtime data.
|
||||
* NOTE: Data of unused modifiers will be freed there. */
|
||||
restore_modifier_runtime_data(object);
|
||||
restore_pose_channel_runtime_data(object);
|
||||
}
|
||||
|
||||
void ObjectRuntimeBackup::restore_modifier_runtime_data(Object *object)
|
||||
{
|
||||
LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
|
||||
BLI_assert(modifier_data->orig_modifier_data != NULL);
|
||||
ModifierDataBackupID modifier_data_id = create_modifier_data_id(modifier_data);
|
||||
ModifierRuntimeDataBackup::iterator runtime_data_iterator = modifier_runtime_data.find(
|
||||
modifier_data_id);
|
||||
if (runtime_data_iterator != modifier_runtime_data.end()) {
|
||||
modifier_data->runtime = runtime_data_iterator->second;
|
||||
runtime_data_iterator->second = NULL;
|
||||
}
|
||||
}
|
||||
for (ModifierRuntimeDataBackup::value_type value : modifier_runtime_data) {
|
||||
const ModifierDataBackupID modifier_data_id = value.first;
|
||||
void *runtime = value.second;
|
||||
if (value.second == NULL) {
|
||||
continue;
|
||||
}
|
||||
const ModifierTypeInfo *modifier_type_info = modifierType_getInfo(modifier_data_id.type);
|
||||
BLI_assert(modifier_type_info != NULL);
|
||||
modifier_type_info->freeRuntimeData(runtime);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectRuntimeBackup::restore_pose_channel_runtime_data(Object *object)
|
||||
{
|
||||
if (object->pose != NULL) {
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
|
||||
/* This is NULL in Edit mode. */
|
||||
if (pchan->orig_pchan != NULL) {
|
||||
PoseChannelRuntimeDataBackup::iterator runtime_data_iterator =
|
||||
pose_channel_runtime_data.find(pchan->orig_pchan);
|
||||
if (runtime_data_iterator != pose_channel_runtime_data.end()) {
|
||||
pchan->runtime = runtime_data_iterator->second;
|
||||
pose_channel_runtime_data.erase(runtime_data_iterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PoseChannelRuntimeDataBackup::value_type &value : pose_channel_runtime_data) {
|
||||
BKE_pose_channel_runtime_free(&value.second);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_modifier.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup_pose.h"
|
||||
|
||||
struct Object;
|
||||
|
||||
namespace DEG {
|
||||
|
||||
class ObjectRuntimeBackup {
|
||||
public:
|
||||
ObjectRuntimeBackup(const Depsgraph *depsgraph);
|
||||
|
||||
/* Make a backup of object's evaluation runtime data, additionally
|
||||
* make object to be safe for free without invalidating backed up
|
||||
* pointers. */
|
||||
void init_from_object(Object *object);
|
||||
void backup_modifier_runtime_data(Object *object);
|
||||
void backup_pose_channel_runtime_data(Object *object);
|
||||
|
||||
/* Restore all fields to the given object. */
|
||||
void restore_to_object(Object *object);
|
||||
/* NOTE: Will free all runtime data which has not been restored. */
|
||||
void restore_modifier_runtime_data(Object *object);
|
||||
void restore_pose_channel_runtime_data(Object *object);
|
||||
|
||||
Object_Runtime runtime;
|
||||
short base_flag;
|
||||
unsigned short base_local_view_bits;
|
||||
ModifierRuntimeDataBackup modifier_runtime_data;
|
||||
PoseChannelRuntimeDataBackup pose_channel_runtime_data;
|
||||
};
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_pose.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intern/depsgraph_type.h"
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
|
||||
struct bPoseChannel;
|
||||
|
||||
namespace DEG {
|
||||
|
||||
/* Storage for backed up pose channel runtime data. */
|
||||
typedef map<bPoseChannel *, bPoseChannel_Runtime> PoseChannelRuntimeDataBackup;
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_scene.h"
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_rigidbody_types.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
SceneBackup::SceneBackup(const Depsgraph *depsgraph) : sequencer_backup(depsgraph)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void SceneBackup::reset()
|
||||
{
|
||||
sound_scene = NULL;
|
||||
playback_handle = NULL;
|
||||
sound_scrub_handle = NULL;
|
||||
speaker_handles = NULL;
|
||||
rigidbody_last_time = -1;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (scene->rigidbody_world != NULL) {
|
||||
rigidbody_last_time = scene->rigidbody_world->ltime;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
if (scene->rigidbody_world != NULL) {
|
||||
scene->rigidbody_world->ltime = rigidbody_last_time;
|
||||
}
|
||||
|
||||
sequencer_backup.restore_to_scene(scene);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_sequencer.h"
|
||||
|
||||
struct Scene;
|
||||
|
||||
namespace DEG {
|
||||
|
||||
struct Depsgraph;
|
||||
|
||||
/* Backup of scene runtime data. */
|
||||
class SceneBackup {
|
||||
public:
|
||||
SceneBackup(const Depsgraph *depsgraph);
|
||||
|
||||
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 restored: we just copy them over to a new scene. */
|
||||
void *sound_scene;
|
||||
void *playback_handle;
|
||||
void *sound_scrub_handle;
|
||||
void *speaker_handles;
|
||||
float rigidbody_last_time;
|
||||
|
||||
SequencerBackup sequencer_backup;
|
||||
};
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_sequence.h"
|
||||
|
||||
#include "DNA_sequence_types.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
SequenceBackup::SequenceBackup(const Depsgraph * /*depsgraph*/)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void SequenceBackup::reset()
|
||||
{
|
||||
scene_sound = NULL;
|
||||
}
|
||||
|
||||
void SequenceBackup::init_from_sequence(Sequence *sequence)
|
||||
{
|
||||
scene_sound = sequence->scene_sound;
|
||||
|
||||
sequence->scene_sound = NULL;
|
||||
}
|
||||
|
||||
void SequenceBackup::restore_to_sequence(Sequence *sequence)
|
||||
{
|
||||
sequence->scene_sound = scene_sound;
|
||||
reset();
|
||||
}
|
||||
|
||||
bool SequenceBackup::isEmpty() const
|
||||
{
|
||||
return (scene_sound == NULL);
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct Sequence;
|
||||
|
||||
namespace DEG {
|
||||
|
||||
struct Depsgraph;
|
||||
|
||||
/* Backup of a single strip. */
|
||||
class SequenceBackup {
|
||||
public:
|
||||
SequenceBackup(const Depsgraph *depsgraph);
|
||||
|
||||
void reset();
|
||||
|
||||
void init_from_sequence(Sequence *sequence);
|
||||
void restore_to_sequence(Sequence *sequence);
|
||||
|
||||
bool isEmpty() const;
|
||||
|
||||
void *scene_sound;
|
||||
};
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_sequencer.h"
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
|
||||
#include "BKE_sequencer.h"
|
||||
#include "BKE_sound.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
SequencerBackup::SequencerBackup(const Depsgraph *depsgraph) : depsgraph(depsgraph)
|
||||
{
|
||||
}
|
||||
|
||||
void SequencerBackup::init_from_scene(Scene *scene)
|
||||
{
|
||||
Sequence *sequence;
|
||||
SEQ_BEGIN (scene->ed, sequence) {
|
||||
SequenceBackup sequence_backup(depsgraph);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_sequence.h"
|
||||
#include "intern/depsgraph_type.h"
|
||||
|
||||
struct Scene;
|
||||
|
||||
namespace DEG {
|
||||
|
||||
struct Depsgraph;
|
||||
|
||||
/* Backup of sequencer strips runtime data. */
|
||||
class SequencerBackup {
|
||||
public:
|
||||
SequencerBackup(const Depsgraph *depsgraph);
|
||||
|
||||
void init_from_scene(Scene *scene);
|
||||
void restore_to_scene(Scene *scene);
|
||||
|
||||
const Depsgraph *depsgraph;
|
||||
|
||||
typedef map<Sequence *, SequenceBackup> SequencesBackupMap;
|
||||
SequencesBackupMap sequences_backup;
|
||||
};
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_sound.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_sound_types.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
SoundBackup::SoundBackup(const Depsgraph * /*depsgraph*/)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct bSound;
|
||||
|
||||
namespace DEG {
|
||||
|
||||
struct Depsgraph;
|
||||
|
||||
/* Backup of sound datablocks runtime data. */
|
||||
class SoundBackup {
|
||||
public:
|
||||
SoundBackup(const Depsgraph *depsgraph);
|
||||
|
||||
void reset();
|
||||
|
||||
void init_from_sound(bSound *sound);
|
||||
void restore_to_sound(bSound *sound);
|
||||
|
||||
void *cache;
|
||||
void *waveform;
|
||||
void *playback_handle;
|
||||
};
|
||||
|
||||
} // namespace DEG
|
||||
Reference in New Issue
Block a user