[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23545] trunk/blender/source/blender/ editors: Preview icon rendering for menus now runs in a separate thread, to avoid

Brecht Van Lommel brecht at blender.org
Mon Sep 28 20:33:45 CEST 2009


Revision: 23545
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23545
Author:   blendix
Date:     2009-09-28 20:33:45 +0200 (Mon, 28 Sep 2009)

Log Message:
-----------
Preview icon rendering for menus now runs in a separate thread, to avoid
blocking the user when opening a menu. Material and texture buttons now
display these icons in the list. Also fixes #19387, icon and full preview
render at the same time would crash.

I'm not really convinced this is thread-safe, but on the other hand also
not sure regular preview render is really thread-safe yet.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/include/ED_previewrender.h
    trunk/blender/source/blender/editors/interface/interface_icons.c
    trunk/blender/source/blender/editors/interface/interface_intern.h
    trunk/blender/source/blender/editors/interface/interface_layout.c
    trunk/blender/source/blender/editors/interface/interface_templates.c
    trunk/blender/source/blender/editors/preview/previewrender.c

Modified: trunk/blender/source/blender/editors/include/ED_previewrender.h
===================================================================
--- trunk/blender/source/blender/editors/include/ED_previewrender.h	2009-09-28 18:05:44 UTC (rev 23544)
+++ trunk/blender/source/blender/editors/include/ED_previewrender.h	2009-09-28 18:33:45 UTC (rev 23545)
@@ -72,7 +72,7 @@
 void ED_preview_free_dbase(void);
 
 void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, struct ID *parent, struct MTex *slot, int sizex, int sizey);
-void ED_preview_iconrender(struct Scene *scene, struct ID *id, unsigned int *rect, int sizex, int sizey);
+void ED_preview_icon_job(const struct bContext *C, void *owner, struct ID *id, unsigned int *rect, int sizex, int sizey);
 
 void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, void *slot, rcti *rect);
 

Modified: trunk/blender/source/blender/editors/interface/interface_icons.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_icons.c	2009-09-28 18:05:44 UTC (rev 23544)
+++ trunk/blender/source/blender/editors/interface/interface_icons.c	2009-09-28 18:33:45 UTC (rev 23545)
@@ -47,6 +47,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_userdef_types.h"
 
+#include "BKE_context.h"
 #include "BKE_image.h"
 #include "BKE_icons.h"
 #include "BKE_utildefines.h"
@@ -676,56 +677,6 @@
 	init_internal_icons();
 }
 
-static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned int *rect)
-{
-	struct ImBuf *ima;
-	unsigned int *drect, *srect;
-	float scaledx, scaledy;
-	short ex, ey, dx, dy;
-
-	/* paranoia test */
-	if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
-		return;
-	
-	/* waste of cpu cyles... but the imbuf API has no other way to scale fast (ton) */
-	ima = IMB_dupImBuf(ibuf);
-	
-	if (!ima) 
-		return;
-	
-	if (ima->x > ima->y) {
-		scaledx = (float)w;
-		scaledy =  ( (float)ima->y/(float)ima->x )*(float)w;
-	}
-	else {			
-		scaledx =  ( (float)ima->x/(float)ima->y )*(float)h;
-		scaledy = (float)h;
-	}
-	
-	ex = (short)scaledx;
-	ey = (short)scaledy;
-	
-	dx = (w - ex) / 2;
-	dy = (h - ey) / 2;
-	
-	IMB_scalefastImBuf(ima, ex, ey);
-	
-	/* if needed, convert to 32 bits */
-	if(ima->rect==NULL)
-		IMB_rect_from_float(ima);
-
-	srect = ima->rect;
-	drect = rect;
-
-	drect+= dy*w+dx;
-	for (;ey > 0; ey--){		
-		memcpy(drect,srect, ex * sizeof(int));
-		drect += w;
-		srect += ima->x;
-	}
-	IMB_freeImBuf(ima);
-}
-
 /* Render size for preview images at level miplevel */
 static int preview_render_size(int miplevel)
 {
@@ -751,105 +702,20 @@
 	}
 }
 
-/* create single icon from jpg, png etc. */
-static void icon_from_image(Scene *scene, Image *img, int miplevel)
-{
-	ImBuf *ibuf= NULL;
-	ImageUser iuser;
-	PreviewImage *pi;
-	unsigned int pr_size;
-	short image_loaded = 0;
-
-	/* img->ok is zero when Image cannot load */
-	if (img==NULL || img->ok==0)
-		return;
-
-	/* setup dummy image user */
-	memset(&iuser, 0, sizeof(ImageUser));
-	iuser.ok= iuser.framenr= 1;
-	iuser.scene= scene;
-	
-	/* elubie: this needs to be changed: here image is always loaded if not
-	   already there. Very expensive for large images. Need to find a way to 
-	   only get existing ibuf */
-	
-	ibuf = BKE_image_get_ibuf(img, &iuser);
-	if(ibuf==NULL || ibuf->rect==NULL) {
-		return;
-	}
-	
-	pi = BKE_previewimg_get((ID*)img); 	
-	
-	if(!pi) {
-		printf("preview image could'nt be allocated");
-		return;
-	}
-	/* we can only create the preview rect here, since loading possibly deallocated
-	   old preview */
-	icon_create_mipmap(pi, miplevel);
-
-	pr_size = img->preview->w[miplevel]*img->preview->h[miplevel]*sizeof(unsigned int);
-
-	image_loaded = 1;
-	icon_copy_rect(ibuf, img->preview->w[miplevel], img->preview->h[miplevel], img->preview->rect[miplevel]);	
-}
-
-static void set_alpha(char* cp, int sizex, int sizey, char alpha) 
-{
-	int x,y;
-	for(y=0; y<sizey; y++) {
-		for(x=0; x<sizex; x++, cp+=4) {
-			cp[3]= alpha;
-		}
-	}
-}
-
 /* only called when icon has changed */
 /* only call with valid pointer from UI_icon_draw */
-static void icon_set_image(Scene *scene, ID *id, PreviewImage* prv_img, int miplevel)
+static void icon_set_image(bContext *C, ID *id, PreviewImage* prv_img, int miplevel)
 {
-	RenderInfo ri;	
-	unsigned int pr_size = 0;
-	
 	if (!prv_img) {
 		printf("No preview image for this ID: %s\n", id->name);
 		return;
 	}	
 
-	/* no drawing (see last parameter doDraw, just calculate preview image 
-		- hopefully small enough to be fast */
-	if (GS(id->name) == ID_IM)
-		icon_from_image(scene, (struct Image*)id, miplevel);
-	else {	
-		/* create the preview rect */
-		icon_create_mipmap(prv_img, miplevel);
+	/* create the preview rect */
+	icon_create_mipmap(prv_img, miplevel);
 
-		ri.curtile= 0;
-		ri.tottile= 0;
-		ri.pr_rectx = prv_img->w[miplevel];
-		ri.pr_recty = prv_img->h[miplevel];
-		pr_size = ri.pr_rectx*ri.pr_recty*sizeof(unsigned int);
-		ri.rect = MEM_callocN(pr_size, "pr icon rect");
-
-		ED_preview_iconrender(scene, id, ri.rect, ri.pr_rectx, ri.pr_recty);
-
-		/* world is rendered with alpha=0, so it wasn't displayed 
-		   this could be render option for sky to, for later */
-		if (GS(id->name) == ID_WO) { 
-			set_alpha( (char*) ri.rect, ri.pr_rectx, ri.pr_recty, 255);
-		} 
-		else if (GS(id->name) == ID_MA) {
-			Material* mat = (Material*)id;
-			if (mat->material_type == MA_TYPE_HALO) {
-				set_alpha( (char*) ri.rect, ri.pr_rectx, ri.pr_recty, 255);
-			}
-		}
-
-		memcpy(prv_img->rect[miplevel], ri.rect, pr_size);
-
-		/* and clean up */
-		MEM_freeN(ri.rect);
-	}
+	ED_preview_icon_job(C, prv_img, id, prv_img->rect[miplevel],
+		prv_img->w[miplevel], prv_img->h[miplevel]);
 }
 
 static void icon_draw_rect(float x, float y, int w, int h, float aspect, int rw, int rh, unsigned int *rect)
@@ -944,7 +810,7 @@
 	}
 }
 
-void ui_id_icon_render(Scene *scene, ID *id)
+void ui_id_icon_render(bContext *C, ID *id)
 {
 	PreviewImage *pi = BKE_previewimg_get(id); 
 		
@@ -952,13 +818,13 @@
 		if ((pi->changed[0] ||!pi->rect[0])) /* changed only ever set by dynamic icons */
 		{
 			/* create the preview rect if necessary */				
-			icon_set_image(scene, id, pi, 0);
+			icon_set_image(C, id, pi, 0);
 			pi->changed[0] = 0;
 		}
 	}
 }
 
-int ui_id_icon_get(Scene *scene, ID *id)
+int ui_id_icon_get(bContext *C, ID *id)
 {
 	int iconid= 0;
 	
@@ -972,7 +838,7 @@
 		case ID_LA: /* fall through */
 			iconid= BKE_icon_getid(id);
 			/* checks if not exists, or changed */
-			ui_id_icon_render(scene, id);
+			ui_id_icon_render(C, id);
 			break;
 		default:
 			break;

Modified: trunk/blender/source/blender/editors/interface/interface_intern.h
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_intern.h	2009-09-28 18:05:44 UTC (rev 23544)
+++ trunk/blender/source/blender/editors/interface/interface_intern.h	2009-09-28 18:33:45 UTC (rev 23545)
@@ -451,8 +451,8 @@
 void uiStyleInit(void);
 
 /* interface_icons.c */
-void ui_id_icon_render(struct Scene *scene, struct ID *id);
-int ui_id_icon_get(struct Scene *scene, struct ID *id);
+void ui_id_icon_render(struct bContext *C, struct ID *id);
+int ui_id_icon_get(struct bContext *C, struct ID *id);
 
 /* resources.c */
 void init_userdef_do_versions(void);

Modified: trunk/blender/source/blender/editors/interface/interface_layout.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_layout.c	2009-09-28 18:05:44 UTC (rev 23544)
+++ trunk/blender/source/blender/editors/interface/interface_layout.c	2009-09-28 18:33:45 UTC (rev 23545)
@@ -1021,7 +1021,6 @@
 
 static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, uiSearchItems *items)
 {
-	Scene *scene= CTX_data_scene(C);
 	uiBut *but= arg_but;
 	char *name;
 	int i, iconid;
@@ -1030,7 +1029,7 @@
 	RNA_PROP_BEGIN(&but->rnasearchpoin, itemptr, but->rnasearchprop) {
 		iconid= 0;
 		if(RNA_struct_is_ID(itemptr.type))
-			iconid= ui_id_icon_get(scene, itemptr.data);
+			iconid= ui_id_icon_get((bContext*)C, itemptr.data);
 
 		name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
 

Modified: trunk/blender/source/blender/editors/interface/interface_templates.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_templates.c	2009-09-28 18:05:44 UTC (rev 23544)
+++ trunk/blender/source/blender/editors/interface/interface_templates.c	2009-09-28 18:33:45 UTC (rev 23545)
@@ -94,7 +94,6 @@
 static void id_search_cb(const bContext *C, void *arg_template, char *str, uiSearchItems *items)
 {
 	TemplateID *template= (TemplateID*)arg_template;
-	Scene *scene= CTX_data_scene(C);
 	ListBase *lb= template->idlb;
 	ID *id;
 	int iconid;
@@ -102,7 +101,7 @@
 	/* ID listbase */
 	for(id= lb->first; id; id= id->next) {
 		if(BLI_strcasestr(id->name+2, str)) {
-			iconid= ui_id_icon_get(scene, id);
+			iconid= ui_id_icon_get((bContext*)C, id);
 
 			if(!uiSearchItemAdd(items, id->name+2, id, iconid))
 				break;
@@ -1842,6 +1841,36 @@
 }
 #endif
 
+static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon)
+{
+	ID *id= NULL;
+	int icon;
+
+	if(!itemptr->data)
+		return rnaicon;
+
+	/* try ID, material or texture slot */
+	if(RNA_struct_is_ID(itemptr->type)) {
+		id= itemptr->id.data;
+	}
+	else if(RNA_struct_is_a(itemptr->type, &RNA_MaterialSlot)) {
+		id= RNA_pointer_get(itemptr, "material").data;
+	}
+	else if(RNA_struct_is_a(itemptr->type, &RNA_TextureSlot)) {
+		id= RNA_pointer_get(itemptr, "texture").data;
+	}
+
+	/* get icon from ID */
+	if(id) {
+		icon= ui_id_icon_get(C, id);
+
+		if(icon)
+			return icon;
+	}
+
+	return rnaicon;
+}
+
 ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, PointerRNA *activeptr, char *activepropname, int rows, int listtype)
 {
 	//Scene *scene= CTX_data_scene(C);
@@ -1854,7 +1883,7 @@
 	Panel *pa;
 	ListBase lb, *itemlb;
 	char *name, str[32];
-	int icon=0, i= 0, activei= 0, len= 0, items, found, min, max;
+	int rnaicon=0, icon=0, i= 0, activei= 0, len= 0, items, found, min, max;
 
 	lb.first= lb.last= NULL;
 	
@@ -1901,7 +1930,7 @@
 	/* get icon */
 	if(ptr->data && prop) {
 		ptype= RNA_property_pointer_type(ptr, prop);
-		icon= RNA_struct_ui_icon(ptype);
+		rnaicon= RNA_struct_ui_icon(ptype);
 	}
 
 	/* get active data */
@@ -1921,15 +1950,7 @@
 				if(i == 9)
 					row= uiLayoutRow(col, 0);
 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list