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;


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to