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
This commit is contained in:
Jeroen Bakker 2023-12-14 16:17:55 +01:00
parent 451aa56d9c
commit 4a34dcbb69
2 changed files with 27 additions and 13 deletions

View File

@ -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];

View File

@ -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<StudioLight *>(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)