[Gimp-developer] [patch] unbelievable speedup for bumpmap...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,
I just looked into bumpmap.c and tried to figure out if it can profit from
blocking and played a bit with the code. It seems that there is some major
(performance) problem with the gimp_pixel_rgn_get/set_row-calls in Gimp
1.2.1.

The original bumpmap took for my 1400*1400 image about 30s, when I commented
out one of the gimp_pixel_rgn_get/set_row() that access the source or the
destination image, the whole stuff took only about 2.4s, while the
calculations were still done! 

I experimented a bit, and found out, that apparently the "switch" between
get and set seems to be the problem. I changed the code to get 32 rows,
calculate them and the write the 32 back. It took only 3s overall, the
resulting image is the same as with the 30s boiling time. 

			That's a speedup of 10!

Can someone please try the patch and confirm that I'm not dreaming?
-- 
         Georg Acher, acher@xxxxxxxxx         
         http://www.in.tum.de/~acher/
          "Oh no, not again !" The bowl of petunias          
--- bumpmap.c.org	Thu Apr  5 21:01:03 2001
+++ bumpmap.c	Thu Apr  5 23:26:39 2001
@@ -500,6 +500,7 @@
   gimp_drawable_detach (drawable);
 }
 
+#define BLOCKS 32
 static void
 bumpmap (void)
 {
@@ -509,8 +510,8 @@
   gint              bm_width, bm_height, bm_bpp, bm_has_alpha;
   gint              yofs1, yofs2, yofs3;
   guchar           *bm_row1, *bm_row2, *bm_row3, *bm_tmprow;
-  guchar           *src_row, *dest_row;
-  gint              y;
+  guchar           *src_row[BLOCKS], *dest_row[BLOCKS];
+  gint              y,n;
   gint              progress;
   gint              tmp;
 
@@ -551,8 +552,11 @@
   bm_row2 = g_new (guchar, bm_width * bm_bpp);
   bm_row3 = g_new (guchar, bm_width * bm_bpp);
 
-  src_row  = g_new (guchar, sel_width * img_bpp);
-  dest_row = g_new (guchar, sel_width * img_bpp);
+  for(n=0;n<BLOCKS;n++)
+  {
+	  src_row[n]  = g_new (guchar, sel_width * img_bpp);
+	  dest_row[n] = g_new (guchar, sel_width * img_bpp);
+  }
 
   /* Initialize pixel regions */
   gimp_pixel_rgn_init (&src_rgn, drawable,
@@ -576,32 +580,40 @@
 
   progress = 0;
 
-  for (y = sel_y1; y < sel_y2; y++)
+  for (y = sel_y1; y < sel_y2; y+=BLOCKS)
     {
-      gimp_pixel_rgn_get_row (&src_rgn, src_row, sel_x1, y, sel_width);
-
-      bumpmap_row (src_row, dest_row, sel_width, img_bpp, img_has_alpha,
-		   bm_row1, bm_row2, bm_row3, bm_width, bmvals.xofs,
-		   bmvals.tiled, 
-		   y == CLAMP (y, - bmvals.yofs, - bmvals.yofs + bm_height),
-		   &params);
-
-      gimp_pixel_rgn_set_row (&dest_rgn, dest_row, sel_x1, y, sel_width);
-
-      /* Next line */
-
-      bm_tmprow = bm_row1;
-      bm_row1   = bm_row2;
-      bm_row2   = bm_row3;
-      bm_row3   = bm_tmprow;
-		
-      if (++yofs3 == bm_height)
-	yofs3 = 0;
-
-      gimp_pixel_rgn_get_row (&bm_rgn, bm_row3, 0, yofs3, bm_width);
-      bumpmap_convert_row (bm_row3, bm_width, bm_bpp, bm_has_alpha, params.lut);
-
-      gimp_progress_update ((double) ++progress / sel_height);
+	    
+	    for(n=0;n<BLOCKS && (y+n) != sel_y2;n++)
+	    {     
+		    gimp_pixel_rgn_get_row (&src_rgn, src_row[n], sel_x1, y+n, sel_width);
+		    
+		    bumpmap_row (src_row[n], dest_row[n], sel_width, img_bpp, img_has_alpha,
+				 bm_row1, bm_row2, bm_row3, bm_width, bmvals.xofs,
+				 bmvals.tiled, 
+				 (y+n) == CLAMP (y+n, - bmvals.yofs, - bmvals.yofs + bm_height),
+				 &params);
+		    
+		    /* Next line */
+		       
+		    bm_tmprow = bm_row1;
+		    bm_row1   = bm_row2;	
+		    bm_row2   = bm_row3;	
+		    bm_row3   = bm_tmprow;	
+		    
+		    if (++yofs3 == bm_height)
+			    yofs3 = 0;
+		    
+		    gimp_pixel_rgn_get_row (&bm_rgn, bm_row3, 0, yofs3, bm_width);
+		    bumpmap_convert_row (bm_row3, bm_width, bm_bpp, bm_has_alpha, params.lut);
+		    
+	    }
+
+	    for(n=0;n<BLOCKS && (y+n) != sel_y2;n++)
+	    {
+		    gimp_pixel_rgn_set_row (&dest_rgn, dest_row[n], sel_x1, y+n, sel_width);
+	    }
+	    gimp_progress_update ((double) progress / sel_height);
+	    progress+=BLOCKS;
     }
 
   /* Done */
@@ -609,9 +621,11 @@
   g_free (bm_row1);
   g_free (bm_row2);
   g_free (bm_row3);
-  g_free (src_row);
-  g_free (dest_row);
-
+  for(n=0;n<BLOCKS;n++)
+  {
+	  g_free (src_row[n]);
+	  g_free (dest_row[n]);
+  }
   if (bm_drawable != drawable)
     gimp_drawable_detach (bm_drawable);
 

[Index of Archives]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [GIMP for Windows]     [KDE]     [GEGL]     [Gimp's Home]     [Gimp on GUI]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux