diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-06-08 14:51:42 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-06-08 14:52:53 +0300 |
commit | 33437719c177ebd9d5d8718a137d1958e595cd8b (patch) | |
tree | 8be5a9a7c6f6aaec08673a0dd904a203ac78da9b /source/blender/blenkernel/intern/cachefile.c | |
parent | 0c7fc3a9618c2bd410c45953f49f836ee866502c (diff) |
Alembic import: fixed memory management for CoW copies of CacheFile blocks
When a CacheFile datablock is copied to an in-main datablock, it means that
the new copy should be independent of the old copy. In this case certain
properties are reset/duplicated. When it is copied to a no-main datablock,
we assume this is a copy-on-write copy that's used for evaluating things,
in which case the handle and object paths are referenced instead of
reset/ duplicated. This prevents us from re-opening the Alembic file every
time a new CoW copy is made.
The same approach is taken when freeing data (only when an in-main datablock
is freed do we actually free the data).
Diffstat (limited to 'source/blender/blenkernel/intern/cachefile.c')
-rw-r--r-- | source/blender/blenkernel/intern/cachefile.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c index d0cdfd6aeed..58770b37147 100644 --- a/source/blender/blenkernel/intern/cachefile.c +++ b/source/blender/blenkernel/intern/cachefile.c @@ -89,15 +89,22 @@ void BKE_cachefile_free(CacheFile *cache_file) { BKE_animdata_free((ID *)cache_file, false); + if (cache_file->id.tag & LIB_TAG_NO_MAIN) { + /* CoW/no-main copies reuse the existing ArchiveReader and mutex */ + return; + } + + if (cache_file->handle) { #ifdef WITH_ALEMBIC - ABC_free_handle(cache_file->handle); + ABC_free_handle(cache_file->handle); #endif - - /* CoW copies share the mutex, so it should only be freed if the original - * CacheFile datablock is freed. */ - if (cache_file->handle_mutex && (cache_file->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0) { + cache_file->handle = NULL; + } + if (cache_file->handle_mutex) { BLI_mutex_free(cache_file->handle_mutex); + cache_file->handle_mutex = NULL; } + BLI_freelistN(&cache_file->object_paths); } @@ -112,8 +119,14 @@ void BKE_cachefile_free(CacheFile *cache_file) void BKE_cachefile_copy_data( Main *UNUSED(bmain), CacheFile *cache_file_dst, const CacheFile *UNUSED(cache_file_src), const int UNUSED(flag)) { + if (cache_file_dst->id.tag & LIB_TAG_NO_MAIN) { + /* CoW/no-main copies reuse the existing ArchiveReader and mutex */ + return; + } + cache_file_dst->handle = NULL; - BLI_listbase_clear(&cache_file_dst->object_paths); + cache_file_dst->handle_mutex = NULL; + BLI_duplicatelist(&cache_file_dst->object_paths, &cache_file_dst->object_paths); } CacheFile *BKE_cachefile_copy(Main *bmain, const CacheFile *cache_file) |