From 0b07f9b71738c59b3834e2fc8b19779c72b3b020 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 6 Jul 2020 15:07:12 +0200 Subject: Fix T78608: Memory leak in Material properties: "Data from SCE". Caused by recent own refactor of cache presevation handling in readfile, EEVEE's lightcache are weird birds that can also be saved in .blend files, need a special handling for those 'persistent' caches... --- source/blender/blenkernel/BKE_idtype.h | 6 ++++++ source/blender/blenkernel/intern/image.c | 8 ++++---- source/blender/blenkernel/intern/movieclip.c | 4 ++-- source/blender/blenkernel/intern/scene.c | 6 +++++- source/blender/blenkernel/intern/sound.c | 2 +- source/blender/blenkernel/intern/volume.cc | 2 +- source/blender/blenloader/intern/readfile.c | 14 +++++++++++--- 7 files changed, 30 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h index 705ed18df90..6cbb7571f41 100644 --- a/source/blender/blenkernel/BKE_idtype.h +++ b/source/blender/blenkernel/BKE_idtype.h @@ -76,9 +76,15 @@ typedef void (*IDTypeMakeLocalFunction)(struct Main *bmain, struct ID *id, const typedef void (*IDTypeForeachIDFunction)(struct ID *id, struct LibraryForeachIDData *data); +typedef enum eIDTypeInfoCacheCallbackFlags { + /** Indicates to the callback that that cache may be stored in the .blend file, so its pointer + * should not be cleared at readtime.*/ + IDTYPE_CACHE_CB_FLAGS_PERSISTENT = 1 << 0, +} eIDTypeInfoCacheCallbackFlags; typedef void (*IDTypeForeachCacheFunctionCallback)(struct ID *id, const struct IDCacheKey *cache_key, void **cache_p, + uint flags, void *user_data); typedef void (*IDTypeForeachCacheFunction)(struct ID *id, IDTypeForeachCacheFunctionCallback function_callback, diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 41ef5dc00ef..53e7037218e 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -195,24 +195,24 @@ static void image_foreach_cache(ID *id, .offset_in_ID = offsetof(Image, cache), .cache_v = image->cache, }; - function_callback(id, &key, (void **)&image->cache, user_data); + function_callback(id, &key, (void **)&image->cache, 0, user_data); for (int eye = 0; eye < 2; eye++) { for (int a = 0; a < TEXTARGET_COUNT; a++) { key.offset_in_ID = offsetof(Image, gputexture[a][eye]); key.cache_v = image->gputexture[a][eye]; - function_callback(id, &key, (void **)&image->gputexture[a][eye], user_data); + function_callback(id, &key, (void **)&image->gputexture[a][eye], 0, user_data); } } key.offset_in_ID = offsetof(Image, rr); key.cache_v = image->rr; - function_callback(id, &key, (void **)&image->rr, user_data); + function_callback(id, &key, (void **)&image->rr, 0, user_data); LISTBASE_FOREACH (RenderSlot *, slot, &image->renderslots) { key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(slot->name); key.cache_v = slot->render; - function_callback(id, &key, (void **)&slot->render, user_data); + function_callback(id, &key, (void **)&slot->render, 0, user_data); } } diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index d36f5ed0329..4a65c6ff5e7 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -139,11 +139,11 @@ static void movie_clip_foreach_cache(ID *id, .offset_in_ID = offsetof(MovieClip, cache), .cache_v = movie_clip->cache, }; - function_callback(id, &key, (void **)&movie_clip->cache, user_data); + function_callback(id, &key, (void **)&movie_clip->cache, 0, user_data); key.offset_in_ID = offsetof(MovieClip, tracking.camera.intrinsics); key.cache_v = movie_clip->tracking.camera.intrinsics; - function_callback(id, &key, (void **)&movie_clip->tracking.camera.intrinsics, user_data); + function_callback(id, &key, (void **)&movie_clip->tracking.camera.intrinsics, 0, user_data); } IDTypeInfo IDType_ID_MC = { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 7f3d6eb0372..a457d278e1d 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -581,7 +581,11 @@ static void scene_foreach_cache(ID *id, .cache_v = scene->eevee.light_cache_data, }; - function_callback(id, &key, (void **)&scene->eevee.light_cache_data, user_data); + function_callback(id, + &key, + (void **)&scene->eevee.light_cache_data, + IDTYPE_CACHE_CB_FLAGS_PERSISTENT, + user_data); } IDTypeInfo IDType_ID_SCE = { diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 18fd8a10cc1..1fcfc9b060f 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -123,7 +123,7 @@ static void sound_foreach_cache(ID *id, .cache_v = sound->waveform, }; - function_callback(id, &key, &sound->waveform, user_data); + function_callback(id, &key, &sound->waveform, 0, user_data); } IDTypeInfo IDType_ID_SO = { diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 18859869b4e..48b920c8a05 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -494,7 +494,7 @@ static void volume_foreach_cache(ID *id, /* cache_v */ volume->runtime.grids, }; - function_callback(id, &key, (void **)&volume->runtime.grids, user_data); + function_callback(id, &key, (void **)&volume->runtime.grids, 0, user_data); } IDTypeInfo IDType_ID_VO = { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 836260c46e5..441421c8736 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2263,6 +2263,7 @@ typedef struct BLOCacheStorage { static void blo_cache_storage_entry_register(ID *id, const IDCacheKey *key, void **UNUSED(cache_p), + eIDTypeInfoCacheCallbackFlags UNUSED(flags), void *cache_storage_v) { BLI_assert(key->id_session_uuid == id->session_uuid); @@ -2280,12 +2281,18 @@ static void blo_cache_storage_entry_register(ID *id, static void blo_cache_storage_entry_restore_in_new(ID *UNUSED(id), const IDCacheKey *key, void **cache_p, + eIDTypeInfoCacheCallbackFlags flags, void *cache_storage_v) { BLOCacheStorage *cache_storage = cache_storage_v; if (cache_storage == NULL) { - *cache_p = NULL; + /* In non-undo case, only clear the pointer if it is a purely runtime one. + * If it may be stored in a persistent way in the .blend file, direct_link code is responsible + * to properly deal with it. */ + if ((flags & IDTYPE_CACHE_CB_FLAGS_PERSISTENT) == 0) { + *cache_p = NULL; + } return; } @@ -2302,6 +2309,7 @@ static void blo_cache_storage_entry_restore_in_new(ID *UNUSED(id), static void blo_cache_storage_entry_clear_in_old(ID *UNUSED(id), const IDCacheKey *key, void **cache_p, + eIDTypeInfoCacheCallbackFlags UNUSED(flags), void *cache_storage_v) { BLOCacheStorage *cache_storage = cache_storage_v; @@ -9249,8 +9257,8 @@ static BHead *read_data_into_datamap(FileData *fd, BHead *bhead, const char *all void *data; #if 0 /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */ - short* sp = fd->filesdna->structs[bhead->SDNAnr]; - char* tmp = malloc(100); + short *sp = fd->filesdna->structs[bhead->SDNAnr]; + char *tmp = malloc(100); allocname = fd->filesdna->types[sp[0]]; strcpy(tmp, allocname); data = read_struct(fd, bhead, tmp); -- cgit v1.2.3