[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33665] trunk/blender/source/blender: Bugfix #22040

Ton Roosendaal ton at blender.org
Tue Dec 14 19:02:41 CET 2010


Revision: 33665
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33665
Author:   ton
Date:     2010-12-14 19:02:41 +0100 (Tue, 14 Dec 2010)

Log Message:
-----------
Bugfix #22040

Old bug report:

Image Editor, Painting: crash when texture was visible in 
Material or Texture preview. Was caused by paint code
freeing mipmaps. Now replaced with a mipmap tag (to be done
again), and a new mipmap function that doesn't re-allocate.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/sculpt_paint/paint_image.c
    trunk/blender/source/blender/imbuf/IMB_imbuf.h
    trunk/blender/source/blender/imbuf/IMB_imbuf_types.h
    trunk/blender/source/blender/imbuf/intern/IMB_filter.h
    trunk/blender/source/blender/imbuf/intern/filter.c
    trunk/blender/source/blender/imbuf/intern/scaling.c
    trunk/blender/source/blender/render/intern/source/imagetexture.c

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image.c	2010-12-14 16:33:04 UTC (rev 33664)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image.c	2010-12-14 18:02:41 UTC (rev 33665)
@@ -4013,8 +4013,9 @@
 	if(ibuf->rect_float)
 		/* TODO - should just update a portion from imapaintpartial! */
 		imb_freerectImBuf(ibuf); /* force recreate of char rect */
+	
 	if(ibuf->mipmap[0])
-		imb_freemipmapImBuf(ibuf);
+		ibuf->userflags |= IB_MIPMAP_INVALID;
 
 	/* todo: should set_tpage create ->rect? */
 	if(texpaint || (sima && sima->lock)) {

Modified: trunk/blender/source/blender/imbuf/IMB_imbuf.h
===================================================================
--- trunk/blender/source/blender/imbuf/IMB_imbuf.h	2010-12-14 16:33:04 UTC (rev 33664)
+++ trunk/blender/source/blender/imbuf/IMB_imbuf.h	2010-12-14 18:02:41 UTC (rev 33665)
@@ -244,6 +244,7 @@
 void IMB_filterN(struct ImBuf *out, struct ImBuf *in);
 void IMB_filter_extend(struct ImBuf *ibuf, char *mask);
 void IMB_makemipmap(struct ImBuf *ibuf, int use_filter);
+void IMB_remakemipmap(struct ImBuf *ibuf, int use_filter);
 struct ImBuf *IMB_getmipmap(struct ImBuf *ibuf, int level);
 
 /**

Modified: trunk/blender/source/blender/imbuf/IMB_imbuf_types.h
===================================================================
--- trunk/blender/source/blender/imbuf/IMB_imbuf_types.h	2010-12-14 16:33:04 UTC (rev 33664)
+++ trunk/blender/source/blender/imbuf/IMB_imbuf_types.h	2010-12-14 18:02:41 UTC (rev 33665)
@@ -131,11 +131,12 @@
 
 /* Moved from BKE_bmfont_types.h because it is a userflag bit mask. */
 /**
- * \brief Flags used internally by blender for imagebuffers
+ * \brief userflags: Flags used internally by blender for imagebuffers
  */
 
 #define IB_BITMAPFONT		(1 << 0)	/* this image is a font */
 #define IB_BITMAPDIRTY		(1 << 1)	/* image needs to be saved is not the same as filename */
+#define IB_MIPMAP_INVALID	(1 << 2)	/* image mipmaps are invalid, need recreate */
 
 /* From iff.h. This was once moved away by Frank, now Nzc moves it
  * back. Such is the way it is... It is a long list of defines, and

Modified: trunk/blender/source/blender/imbuf/intern/IMB_filter.h
===================================================================
--- trunk/blender/source/blender/imbuf/intern/IMB_filter.h	2010-12-14 16:33:04 UTC (rev 33664)
+++ trunk/blender/source/blender/imbuf/intern/IMB_filter.h	2010-12-14 18:02:41 UTC (rev 33665)
@@ -44,5 +44,7 @@
 void IMB_premultiply_rect(unsigned int *rect, int depth, int w, int h);
 void IMB_premultiply_rect_float(float *rect_float, int depth, int w, int h);
 
+void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1);
+
 #endif
 

Modified: trunk/blender/source/blender/imbuf/intern/filter.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/filter.c	2010-12-14 16:33:04 UTC (rev 33664)
+++ trunk/blender/source/blender/imbuf/intern/filter.c	2010-12-14 18:02:41 UTC (rev 33665)
@@ -371,11 +371,48 @@
 	}
 }
 
+/* threadsafe version, only recreates existing maps */
+void IMB_remakemipmap(ImBuf *ibuf, int use_filter)
+{
+	ImBuf *hbuf = ibuf;
+	int curmap = 0;
+	
+	ibuf->miptot= 1;
+	
+	while(curmap < IB_MIPMAP_LEVELS) {
+		
+		if(ibuf->mipmap[curmap]) {
+			
+			if(use_filter) {
+				ImBuf *nbuf= IMB_allocImBuf(hbuf->x, hbuf->y, 32, IB_rect);
+				IMB_filterN(nbuf, hbuf);
+				imb_onehalf_no_alloc(ibuf->mipmap[curmap], nbuf);
+				IMB_freeImBuf(nbuf);
+			}
+			else
+				imb_onehalf_no_alloc(ibuf->mipmap[curmap], hbuf);
+		}
+		
+		ibuf->miptot= curmap+2;
+		hbuf= ibuf->mipmap[curmap];
+		if(hbuf)
+			hbuf->miplevel= curmap+1;
+		
+		if(!hbuf || (hbuf->x <= 2 && hbuf->y <= 2))
+			break;
+		
+		curmap++;
+	}
+}
+
+/* frees too (if there) and recreates new data */
 void IMB_makemipmap(ImBuf *ibuf, int use_filter)
 {
 	ImBuf *hbuf = ibuf;
 	int curmap = 0;
 
+	imb_freemipmapImBuf(ibuf);
+	
 	ibuf->miptot= 1;
 
 	while(curmap < IB_MIPMAP_LEVELS) {

Modified: trunk/blender/source/blender/imbuf/intern/scaling.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/scaling.c	2010-12-14 16:33:04 UTC (rev 33664)
+++ trunk/blender/source/blender/imbuf/intern/scaling.c	2010-12-14 18:02:41 UTC (rev 33665)
@@ -286,26 +286,16 @@
 	return (ibuf2);
 }
 
-
-struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1)
+/* result in ibuf2, scaling should be done correctly */
+void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
 {
-	struct ImBuf *ibuf2;
 	uchar *p1, *p2 = NULL, *dest;
 	float *p1f, *destf, *p2f = NULL;
 	int x,y;
 	int do_rect, do_float;
 
-	if (ibuf1==NULL) return (0);
-	if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0);
-
 	do_rect= (ibuf1->rect != NULL);
-
-	if (ibuf1->x <= 1) return(IMB_half_y(ibuf1));
-	if (ibuf1->y <= 1) return(IMB_half_x(ibuf1));
 	
-	ibuf2=IMB_allocImBuf((ibuf1->x)/2, (ibuf1->y)/2, ibuf1->depth, ibuf1->flags);
-	if (ibuf2==NULL) return (0);
-
 	p1f = ibuf1->rect_float;
 	destf=ibuf2->rect_float;
 	p1 = (uchar *) ibuf1->rect;
@@ -343,10 +333,27 @@
 			if (do_float) p1f+=4;
 		}
 	}
+	
+}
+
+struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1)
+{
+	struct ImBuf *ibuf2;
+
+	if (ibuf1==NULL) return (0);
+	if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0);
+	
+	if (ibuf1->x <= 1) return(IMB_half_y(ibuf1));
+	if (ibuf1->y <= 1) return(IMB_half_x(ibuf1));
+	
+	ibuf2=IMB_allocImBuf((ibuf1->x)/2, (ibuf1->y)/2, ibuf1->depth, ibuf1->flags);
+	if (ibuf2==NULL) return (0);
+	
+	imb_onehalf_no_alloc(ibuf2, ibuf1);
+	
 	return (ibuf2);
 }
 
-
 /* q_scale_linear_interpolation helper functions */
 
 static void enlarge_picture_byte(

Modified: trunk/blender/source/blender/render/intern/source/imagetexture.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/imagetexture.c	2010-12-14 16:33:04 UTC (rev 33664)
+++ trunk/blender/source/blender/render/intern/source/imagetexture.c	2010-12-14 18:02:41 UTC (rev 33665)
@@ -960,6 +960,30 @@
 	}
 }
 
+static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
+{
+	if (tex->imaflag & TEX_MIPMAP) {
+		if ((ibuf->flags & IB_fields) == 0) {
+			
+			if (ibuf->mipmap[0] && (ibuf->userflags & IB_MIPMAP_INVALID)) {
+				BLI_lock_thread(LOCK_IMAGE);
+				if (ibuf->userflags & IB_MIPMAP_INVALID) {
+					IMB_remakemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
+					ibuf->userflags &= ~IB_MIPMAP_INVALID;
+				}				
+				BLI_unlock_thread(LOCK_IMAGE);
+			}
+			if (ibuf->mipmap[0] == NULL) {
+				BLI_lock_thread(LOCK_IMAGE);
+				if (ibuf->mipmap[0] == NULL) 
+					IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
+				BLI_unlock_thread(LOCK_IMAGE);
+			}
+		}
+	}
+	
+}
+
 static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *dxt, float *dyt, TexResult *texres)
 {
 	TexResult texr;
@@ -996,15 +1020,9 @@
 
 	if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) return retval;
 
-	// mipmap test
-	if (tex->imaflag & TEX_MIPMAP) {
-		if (((ibuf->flags & IB_fields) == 0) && (ibuf->mipmap[0] == NULL)) {
-			BLI_lock_thread(LOCK_IMAGE);
-			if (ibuf->mipmap[0] == NULL) IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
-			BLI_unlock_thread(LOCK_IMAGE);
-		}
-	}
-
+	/* mipmap test */
+	image_mipmap_test(tex, ibuf);
+	
 	if ((tex->imaflag & TEX_USEALPHA) && ((tex->imaflag & TEX_CALCALPHA) == 0)) texres->talpha = 1;
 	texr.talpha = texres->talpha;
 
@@ -1388,18 +1406,8 @@
 	   return retval;
 	
 	/* mipmap test */
-	if (tex->imaflag & TEX_MIPMAP) {
-		if(ibuf->flags & IB_fields);
-		else if(ibuf->mipmap[0]==NULL) {
-			BLI_lock_thread(LOCK_IMAGE);
-			
-			if(ibuf->mipmap[0]==NULL)
-				IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
+	image_mipmap_test(tex, ibuf);
 
-			BLI_unlock_thread(LOCK_IMAGE);
-		}
-	}
-
 	if(tex->imaflag & TEX_USEALPHA) {
 		if(tex->imaflag & TEX_CALCALPHA);
 		else texres->talpha= 1;





More information about the Bf-blender-cvs mailing list