diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_studiolight.h | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/icons.c | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/studiolight.c | 49 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_icons.c | 31 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_space.c | 6 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_userdef.c | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 1 |
8 files changed, 98 insertions, 19 deletions
diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h index a1f43352d8b..f9d679b1b1a 100644 --- a/source/blender/blenkernel/BKE_studiolight.h +++ b/source/blender/blenkernel/BKE_studiolight.h @@ -62,6 +62,7 @@ #define STUDIOLIGHT_ICON_SIZE 96 struct GPUTexture; +struct StudioLight; /* StudioLight.flag */ enum StudioLightFlag { @@ -79,7 +80,6 @@ enum StudioLightFlag { STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE = (1 << 10), STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 11), STUDIOLIGHT_UI_EXPANDED = (1 << 13), - STUDIOLIGHT_DISABLED = (1 << 14), } StudioLightFlag; #define STUDIOLIGHT_FLAG_ALL (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_EXTERNAL_FILE) @@ -87,6 +87,8 @@ enum StudioLightFlag { #define STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_ORIENTATION_WORLD) #define STUDIOLIGHT_ORIENTATIONS_SOLID (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD) +typedef void StudioLightFreeFunction(struct StudioLight *, void *data); + typedef struct StudioLight { struct StudioLight *next, *prev; @@ -109,6 +111,13 @@ typedef struct StudioLight { struct GPUTexture *equirectangular_irradiance_gputexture; float *gpu_matcap_3components; /* 3 channel buffer for GPU_R11F_G11F_B10F */ + /* + Free function to clean up the running icons previews (wmJob) the usage is in + interface_icons. Please be aware that this was build to handle only one free function + that cleans up all icons. just to keep the code simple. + */ + StudioLightFreeFunction *free_function; + void* free_function_data; } StudioLight; void BKE_studiolight_init(void); @@ -120,5 +129,7 @@ void BKE_studiolight_preview(uint* icon_buffer, StudioLight *sl, int icon_id_typ struct ListBase *BKE_studiolight_listbase(void); void BKE_studiolight_ensure_flag(StudioLight *sl, int flag); void BKE_studiolight_refresh(void); +void BKE_studiolight_set_free_function(StudioLight *sl, StudioLightFreeFunction *free_function, void *data); +void BKE_studiolight_unset_icon_id(StudioLight *sl, int icon_id); #endif /* __BKE_STUDIOLIGHT_H__ */ diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 006cf8275a7..c366d822648 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -62,6 +62,7 @@ #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_sequencer.h" +#include "BKE_studiolight.h" #include "DEG_depsgraph.h" @@ -82,6 +83,8 @@ char versionstr[48] = ""; void BKE_blender_free(void) { /* samples are in a global list..., also sets G_MAIN->sound->sample NULL */ + + BKE_studiolight_free(); /* needs to run before main free as wm is still referenced for icons preview jobs */ BKE_main_free(G_MAIN); G_MAIN = NULL; diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index e6afe08e19a..37f53e81236 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -119,7 +119,7 @@ static void icon_free(void *val) } } -static void icon_free_data(Icon *icon) +static void icon_free_data(int icon_id, Icon *icon) { if (icon->obj_type == ICON_DATA_ID) { ((ID *)(icon->obj))->icon_id = 0; @@ -130,6 +130,12 @@ static void icon_free_data(Icon *icon) else if (icon->obj_type == ICON_DATA_GEOM) { ((struct Icon_Geom *)(icon->obj))->icon_id = 0; } + else if (icon->obj_type == ICON_DATA_STUDIOLIGHT) { + StudioLight *sl = icon->obj; + if (sl != NULL) { + BKE_studiolight_unset_icon_id(sl, icon_id); + } + } else { BLI_assert(0); } @@ -699,7 +705,7 @@ bool BKE_icon_delete(const int icon_id) Icon *icon = BLI_ghash_popkey(gIcons, SET_INT_IN_POINTER(icon_id), NULL); if (icon) { - icon_free_data(icon); + icon_free_data(icon_id, icon); icon_free(icon); return true; } @@ -722,7 +728,7 @@ bool BKE_icon_delete_unmanaged(const int icon_id) return false; } else { - icon_free_data(icon); + icon_free_data(icon_id, icon); icon_free(icon); return true; } diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 42a6b96653f..da370971715 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -81,6 +81,21 @@ if (p) { \ static void studiolight_free(struct StudioLight *sl) { +#define STUDIOLIGHT_DELETE_ICON(s) { \ + if (s != 0) { \ + BKE_icon_delete(s); \ + s = 0; \ + } \ +} + if (sl->free_function) { + sl->free_function(sl, sl->free_function_data); + } + STUDIOLIGHT_DELETE_ICON(sl->icon_id_radiance); + STUDIOLIGHT_DELETE_ICON(sl->icon_id_irradiance); + STUDIOLIGHT_DELETE_ICON(sl->icon_id_matcap); + 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]); } @@ -101,6 +116,7 @@ static struct StudioLight *studiolight_create(int flag) sl->name[0] = 0x00; sl->path_irr_cache = NULL; sl->path_sh2_cache = NULL; + sl->free_function = NULL; sl->flag = flag; sl->index = BLI_listbase_count(&studiolights); if (flag & STUDIOLIGHT_ORIENTATION_VIEWNORMAL) { @@ -892,7 +908,7 @@ void BKE_studiolight_free(void) struct StudioLight *BKE_studiolight_find_first(int flag) { LISTBASE_FOREACH(StudioLight *, sl, &studiolights) { - if ((sl->flag & flag) && (sl->flag & STUDIOLIGHT_DISABLED) == 0) { + if ((sl->flag & flag)) { return sl; } } @@ -903,7 +919,7 @@ struct StudioLight *BKE_studiolight_find(const char *name, int flag) { LISTBASE_FOREACH(StudioLight *, sl, &studiolights) { if (STREQLEN(sl->name, name, FILE_MAXFILE)) { - if ((sl->flag & flag) && (sl->flag & STUDIOLIGHT_DISABLED) == 0) { + if ((sl->flag & flag)) { return sl; } else { @@ -919,7 +935,7 @@ struct StudioLight *BKE_studiolight_find(const char *name, int flag) struct StudioLight *BKE_studiolight_findindex(int index, int flag) { LISTBASE_FOREACH(StudioLight *, sl, &studiolights) { - if (sl->index == index && (sl->flag & STUDIOLIGHT_DISABLED) == 0) { + if (sl->index == index) { return sl; } } @@ -995,8 +1011,29 @@ void BKE_studiolight_ensure_flag(StudioLight *sl, int flag) void BKE_studiolight_refresh(void) { - LISTBASE_FOREACH(StudioLight *, sl, &studiolights) { - sl->flag |= STUDIOLIGHT_DISABLED; - } + BKE_studiolight_free(); BKE_studiolight_init(); } + +void BKE_studiolight_set_free_function(StudioLight *sl, StudioLightFreeFunction *free_function, void *data) +{ + sl->free_function = free_function; + sl->free_function_data = data; +} + +void BKE_studiolight_unset_icon_id(StudioLight *sl, int icon_id) +{ + BLI_assert(sl != NULL); + if (sl->icon_id_radiance == icon_id) { + sl->icon_id_radiance = 0; + } + if (sl->icon_id_irradiance == icon_id) { + sl->icon_id_irradiance = 0; + } + if (sl->icon_id_matcap == icon_id) { + sl->icon_id_matcap = 0; + } + if (sl->icon_id_matcap_flipped == icon_id) { + sl->icon_id_matcap_flipped = 0; + } +}
\ No newline at end of file diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 3272e9f14a2..539dd05b242 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -851,6 +851,32 @@ static void ui_studiolight_icon_job_exec(void *customdata, short *UNUSED(stop), BKE_studiolight_preview(di->data.buffer.image->rect, sl, icon->id_type); } +static void ui_studiolight_kill_icon_preview_job(wmWindowManager *wm, int icon_id) +{ + Icon *icon = BKE_icon_get(icon_id); + WM_jobs_kill_type(wm, icon, WM_JOB_TYPE_STUDIOLIGHT); + icon->obj = NULL; +} + +static void ui_studiolight_free_function(StudioLight * sl, void* data) +{ + wmWindowManager *wm = data; + + // get icons_id, get icons and kill wm jobs + if (sl->icon_id_radiance) { + ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_radiance); + } + if (sl->icon_id_irradiance) { + ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_irradiance); + } + if (sl->icon_id_matcap) { + ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_matcap); + } + if (sl->icon_id_matcap_flipped) { + ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_matcap_flipped); + } +} + void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool big) { Icon *icon = BKE_icon_get(icon_id); @@ -881,6 +907,9 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi { if (icon->obj_type == ICON_DATA_STUDIOLIGHT) { if (di->data.buffer.image == NULL) { + wmWindowManager *wm = CTX_wm_manager(C); + StudioLight *sl = icon->obj; + BKE_studiolight_set_free_function(sl, &ui_studiolight_free_function, wm); IconImage *img = MEM_mallocN(sizeof(IconImage), __func__); img->w = STUDIOLIGHT_ICON_SIZE; @@ -890,7 +919,7 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi memset(img->rect, 0, size); di->data.buffer.image = img; - wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), icon, "StudioLight Icon", 0, WM_JOB_TYPE_STUDIOLIGHT); + wmJob *wm_job = WM_jobs_get(wm, CTX_wm_window(C), icon, "StudioLight Icon", 0, WM_JOB_TYPE_STUDIOLIGHT); Icon** tmp = MEM_callocN(sizeof(Icon*), __func__); *tmp = icon; WM_jobs_customdata_set(wm_job, tmp, MEM_freeN); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index c886f19d134..34d393c7b62 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -766,9 +766,6 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf( const int flags = (STUDIOLIGHT_EXTERNAL_FILE | STUDIOLIGHT_ORIENTATION_VIEWNORMAL); LISTBASE_FOREACH(StudioLight *, sl, BKE_studiolight_listbase()) { - if ((sl->flag & STUDIOLIGHT_DISABLED)){ - continue; - } int icon_id = (v3d->shading.flag & V3D_SHADING_MATCAP_FLIP_X) ? sl->icon_id_matcap_flipped: sl->icon_id_matcap; if ((sl->flag & flags) == flags) { EnumPropertyItem tmp = {sl->index, sl->name, icon_id, sl->name, ""}; @@ -778,9 +775,6 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf( } else { LISTBASE_FOREACH(StudioLight *, sl, BKE_studiolight_listbase()) { - if ((sl->flag & STUDIOLIGHT_DISABLED)){ - continue; - } int icon_id = sl->icon_id_irradiance; bool show_studiolight = false; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 6e0f95a33b7..2dbdb1bbb1c 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -703,7 +703,7 @@ static int rna_UserDef_studiolight_index_get(PointerRNA *ptr) static int rna_UserDef_studiolight_is_user_defined_get(PointerRNA *ptr) { StudioLight *sl = (StudioLight *)ptr->data; - return (sl->flag & STUDIOLIGHT_USER_DEFINED) > 0 && (sl->flag & STUDIOLIGHT_DISABLED) == 0; + return (sl->flag & STUDIOLIGHT_USER_DEFINED) > 0; } /* StudioLight.orientation */ diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index ebaa51e7906..a14cbed6381 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -517,7 +517,6 @@ void WM_exit_ext(bContext *C, const bool do_python) GPU_pass_cache_free(); DRW_opengl_context_destroy(); } - BKE_studiolight_free(); #ifdef WITH_INTERNATIONAL BLF_free_unifont(); |