From 4a34dcbb6970c381f5cd9469e9697ab1d45fec0d Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 14 Dec 2023 16:17:55 +0100 Subject: [PATCH] Studiolight: Free Resources for Unused Lights. Studio lights based on image resources are kept in memory, even when only displayed as an icon. When having many studio lights configured leads to allocating a lot of memory that are not used. This patch free image resources when only icons are requested. For studio lights that are used in a viewport the image resources are kept. Pull Request: https://projects.blender.org/blender/blender/pulls/116191 --- source/blender/blenkernel/BKE_studiolight.h | 2 - .../blender/blenkernel/intern/studiolight.cc | 38 +++++++++++++------ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h index 83c6f372bdd..275d1a01520 100644 --- a/source/blender/blenkernel/BKE_studiolight.h +++ b/source/blender/blenkernel/BKE_studiolight.h @@ -79,9 +79,7 @@ typedef struct StudioLight { StudioLightImage matcap_diffuse; StudioLightImage matcap_specular; struct ImBuf *equirect_radiance_buffer; - struct ImBuf *radiance_cubemap_buffers[6]; struct GPUTexture *equirect_radiance_gputexture; - struct GPUTexture *equirect_irradiance_gputexture; SolidLight light[STUDIOLIGHT_MAX_LIGHT]; float light_ambient[3]; diff --git a/source/blender/blenkernel/intern/studiolight.cc b/source/blender/blenkernel/intern/studiolight.cc index f406df2a783..68f4b698dc7 100644 --- a/source/blender/blenkernel/intern/studiolight.cc +++ b/source/blender/blenkernel/intern/studiolight.cc @@ -97,6 +97,14 @@ static const char *STUDIOLIGHT_MATCAP_DEFAULT = "basic_1.exr"; } \ } while (0) +static void studiolight_free_image_buffers(StudioLight *sl) +{ + sl->flag &= ~STUDIOLIGHT_EXTERNAL_IMAGE_LOADED; + IMB_SAFE_FREE(sl->matcap_diffuse.ibuf); + IMB_SAFE_FREE(sl->matcap_specular.ibuf); + IMB_SAFE_FREE(sl->equirect_radiance_buffer); +} + static void studiolight_free(StudioLight *sl) { #define STUDIOLIGHT_DELETE_ICON(s) \ @@ -116,19 +124,30 @@ static void studiolight_free(StudioLight *sl) STUDIOLIGHT_DELETE_ICON(sl->icon_id_matcap_flipped); #undef STUDIOLIGHT_DELETE_ICON - for (int index = 0; index < 6; index++) { - IMB_SAFE_FREE(sl->radiance_cubemap_buffers[index]); - } + studiolight_free_image_buffers(sl); + GPU_TEXTURE_SAFE_FREE(sl->equirect_radiance_gputexture); - GPU_TEXTURE_SAFE_FREE(sl->equirect_irradiance_gputexture); - IMB_SAFE_FREE(sl->equirect_radiance_buffer); GPU_TEXTURE_SAFE_FREE(sl->matcap_diffuse.gputexture); GPU_TEXTURE_SAFE_FREE(sl->matcap_specular.gputexture); - IMB_SAFE_FREE(sl->matcap_diffuse.ibuf); - IMB_SAFE_FREE(sl->matcap_specular.ibuf); MEM_SAFE_FREE(sl); } +/** + * Free temp resources when the studio light is only requested for icons. + * + * Only keeps around resources for studio lights that have been used in any viewport. + */ +static void studiolight_free_temp_resources(StudioLight *sl) +{ + const bool is_used_in_viewport = bool(sl->flag & (STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE | + STUDIOLIGHT_MATCAP_SPECULAR_GPUTEXTURE | + STUDIOLIGHT_MATCAP_DIFFUSE_GPUTEXTURE)); + if (is_used_in_viewport) { + return; + } + studiolight_free_image_buffers(sl); +} + static StudioLight *studiolight_create(int flag) { StudioLight *sl = static_cast(MEM_callocN(sizeof(*sl), __func__)); @@ -149,10 +168,6 @@ static StudioLight *studiolight_create(int flag) sl->icon_id_radiance = BKE_icon_ensure_studio_light(sl, STUDIOLIGHT_ICON_ID_TYPE_RADIANCE); } - for (int index = 0; index < 6; index++) { - sl->radiance_cubemap_buffers[index] = nullptr; - } - return sl; } @@ -941,6 +956,7 @@ void BKE_studiolight_preview(uint *icon_buffer, StudioLight *sl, int icon_id_typ break; } } + studiolight_free_temp_resources(sl); } void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)