From 33437719c177ebd9d5d8718a137d1958e595cd8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 8 Jun 2018 13:51:42 +0200 Subject: 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). --- source/blender/blenkernel/intern/cachefile.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'source/blender/blenkernel/intern/cachefile.c') 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) -- cgit v1.2.3