[Bf-blender-cvs] [e3052ecb0d2] blender2.8: Studiolight: removed raise condition

Jeroen Bakker noreply at git.blender.org
Wed Jun 20 09:32:59 CEST 2018


Commit: e3052ecb0d246381558c75219962915140bbe4ca
Author: Jeroen Bakker
Date:   Wed Jun 20 09:29:40 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBe3052ecb0d246381558c75219962915140bbe4ca

Studiolight: removed raise condition

Happened when deleting many studiolights at the same time when the
previews were still beging calculated in the background.

Added a free function callback that is filled when the preview is being
generated. This free function will then kill the preview job

This patch also removes icons that are not valid anymore so the user
cannot accidentally render an icon where the studiolight is invalid.

In the end we should use a add/remove function in the studiolight as
currently icons are recalculated too much.

===================================================================

M	source/blender/blenkernel/BKE_studiolight.h
M	source/blender/blenkernel/intern/blender.c
M	source/blender/blenkernel/intern/icons.c
M	source/blender/blenkernel/intern/studiolight.c
M	source/blender/editors/interface/interface_icons.c
M	source/blender/makesrna/intern/rna_space.c
M	source/blender/makesrna/intern/rna_userdef.c
M	source/blender/windowmanager/intern/wm_init_exit.c

===================================================================

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_lis

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list