[Bf-blender-cvs] [e018da98b9d] new-object-types: Volumes: fix memory leak in grids depsgraph backup
Brecht Van Lommel
noreply at git.blender.org
Mon Feb 10 14:37:53 CET 2020
Commit: e018da98b9d8ff85ec798f9c1a2d5e7704f4c731
Author: Brecht Van Lommel
Date: Sun Feb 9 23:03:54 2020 +0100
Branches: new-object-types
https://developer.blender.org/rBe018da98b9d8ff85ec798f9c1a2d5e7704f4c731
Volumes: fix memory leak in grids depsgraph backup
===================================================================
M source/blender/blenkernel/BKE_volume.h
M source/blender/blenkernel/intern/volume.cc
M source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.cc
M source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index ad4db53b31a..a76996afe20 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -37,6 +37,7 @@ struct Main;
struct Object;
struct Scene;
struct Volume;
+struct VolumeGridVector;
/* Module */
@@ -67,6 +68,10 @@ void BKE_volume_data_update(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *object);
+void BKE_volume_grids_backup_restore(struct Volume *volume,
+ struct VolumeGridVector *grids,
+ const char *filepath);
+
/* Draw Cache */
enum {
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index c820a0b7940..8d9efb01f50 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -79,7 +79,7 @@ static CLG_LogRef LOG = {"bke.volume"};
* When the number of users drops to zero, the grid data is immediately deleted.
*
* TODO: also add a cache for OpenVDB files rather than individual grids,
- * so getting the list of grids is also cached?
+ * so getting the list of grids is also cached.
* TODO: Further, we could cache openvdb::io::File so that loading a grid
* does not re-open it every time. But then we have to take care not to run
* out of file descriptors or prevent other applications from writing to it.
@@ -373,6 +373,11 @@ struct VolumeGridVector : public std::vector<VolumeGrid> {
memcpy(filepath, other.filepath, sizeof(filepath));
}
+ bool is_loaded() const
+ {
+ return filepath[0] != '\0';
+ }
+
/* Absolute file path that grids have been loaded from. */
char filepath[FILE_MAX];
/* File loading error message. */
@@ -552,7 +557,7 @@ bool BKE_volume_is_loaded(const Volume *volume)
{
#ifdef WITH_OPENVDB
/* Test if there is a file to load, or if already loaded. */
- return (volume->filepath[0] == '\0' || volume->runtime.grids->filepath[0] != '\0');
+ return (volume->filepath[0] == '\0' || volume->runtime.grids->is_loaded());
#else
UNUSED_VARS(volume);
return true;
@@ -778,15 +783,13 @@ static Volume *volume_evaluate_modifiers(struct Depsgraph *depsgraph,
void BKE_volume_eval_geometry(struct Depsgraph *depsgraph, Volume *volume)
{
+ /* TODO: can we avoid modifier re-evaluation when frame did not change? */
int frame = volume_sequence_frame(depsgraph, volume);
-
if (frame != volume->runtime.frame) {
BKE_volume_unload(volume);
volume->runtime.frame = frame;
}
- /* TODO: can we avoid modifier re-evaluation when frame did not change? */
-
/* Flush back to original. */
if (DEG_is_active(depsgraph)) {
Volume *volume_orig = (Volume *)DEG_get_original_id(&volume->id);
@@ -808,6 +811,33 @@ void BKE_volume_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Ob
BKE_object_eval_assign_data(object, &volume_eval->id, is_owned);
}
+void BKE_volume_grids_backup_restore(Volume *volume, VolumeGridVector *grids, const char *filepath)
+{
+#ifdef WITH_OPENVDB
+ /* Restore grids after datablock was re-copied from original by depsgraph,
+ * we don't want to load them again if possible. */
+ BLI_assert(volume->id.tag & LIB_TAG_COPIED_ON_WRITE);
+ BLI_assert(volume->runtime.grids != NULL && grids != NULL);
+
+ if (!grids->is_loaded()) {
+ /* No grids loaded in CoW datablock, nothing lost by discarding. */
+ OBJECT_GUARDED_DELETE(grids, VolumeGridVector);
+ }
+ else if (!STREQ(volume->filepath, filepath)) {
+ /* Filepath changed, discard grids from CoW datablock. */
+ OBJECT_GUARDED_DELETE(grids, VolumeGridVector);
+ }
+ else {
+ /* Keep grids from CoW datablock. We might still unload them a little
+ * later in BKE_volume_eval_geometry if the frame changes. */
+ OBJECT_GUARDED_DELETE(volume->runtime.grids, VolumeGridVector);
+ volume->runtime.grids = grids;
+ }
+#else
+ UNUSED_VARS(volume, grids);
+#endif
+}
+
/* Draw Cache */
void (*BKE_volume_batch_cache_dirty_tag_cb)(Volume *volume, int mode) = NULL;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.cc
index fe1bf9ee644..09e13ec131d 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.cc
@@ -23,37 +23,38 @@
#include "intern/eval/deg_eval_runtime_backup_volume.h"
+#include "BLI_assert.h"
+#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "DNA_volume_types.h"
+
+#include "BKE_volume.h"
+
#include <stdio.h>
namespace DEG {
-VolumeBackup::VolumeBackup(const Depsgraph * /*depsgraph*/)
-{
- reset();
-}
-
-void VolumeBackup::reset()
+VolumeBackup::VolumeBackup(const Depsgraph * /*depsgraph*/) : grids(nullptr)
{
- grids = nullptr;
}
void VolumeBackup::init_from_volume(Volume *volume)
{
- /* TODO: this is leaking! */
+ STRNCPY(filepath, volume->filepath);
+ BLI_STATIC_ASSERT(sizeof(filepath) == sizeof(volume->filepath),
+ "VolumeBackup filepath length wrong");
+
grids = volume->runtime.grids;
volume->runtime.grids = nullptr;
}
void VolumeBackup::restore_to_volume(Volume *volume)
{
- /* TODO: why does it call restore without init? */
if (grids) {
- volume->runtime.grids = grids;
+ BKE_volume_grids_backup_restore(volume, grids, filepath);
+ grids = nullptr;
}
- reset();
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.h
index c9fd0f33734..cf57c702c8f 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.h
@@ -35,12 +35,11 @@ class VolumeBackup {
public:
VolumeBackup(const Depsgraph *depsgraph);
- void reset();
-
void init_from_volume(Volume *volume);
void restore_to_volume(Volume *volume);
VolumeGridVector *grids;
+ char filepath[1024]; /* FILE_MAX */
};
} // namespace DEG
More information about the Bf-blender-cvs
mailing list