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, [EMAIL PROTECTED]         
         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);
 

Reply via email to