gegl r2374 - in trunk: . gegl/buffer gegl/operation



Author: ok
Date: Tue Jun  3 21:00:16 2008
New Revision: 2374
URL: http://svn.gnome.org/viewvc/gegl?rev=2374&view=rev

Log:
Enable scan iteration for compositing.
* gegl/buffer/gegl-buffer-access.c:
(gegl_buffer_scan_iterator_next), (gegl_buffer_scan_compatible),
(gegl_buffer_tile_iterator_next), (gegl_buffer_iterate),
(gegl_buffer_copy): commit earlier missed changes.
* gegl/buffer/gegl-buffer-private.h: fix prototype for scan
compatible.
* gegl/operation/gegl-operation-point-composer.c:
(gegl_operation_point_composer_process): process using scan iterator
when possible.
* gegl/operation/gegl-operation-point-filter.c: commit missed file
from earlier commit.


Modified:
   trunk/ChangeLog
   trunk/gegl/buffer/gegl-buffer-access.c
   trunk/gegl/buffer/gegl-buffer-private.h
   trunk/gegl/operation/gegl-operation-point-composer.c
   trunk/gegl/operation/gegl-operation-point-filter.c

Modified: trunk/gegl/buffer/gegl-buffer-access.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-access.c	(original)
+++ trunk/gegl/buffer/gegl-buffer-access.c	Tue Jun  3 21:00:16 2008
@@ -124,10 +124,10 @@
       i->data = data + px_size * (tile_i->subrect.width * tile_i->subrect.y);
       i->row = tile_i->subrect.height;
       i->real_row = 0;
-      if (i->rowstride < 0)
+/*      if (i->rowstride < 0)
         {
           return FALSE;
-        }
+        }*/
       return TRUE;
     }
   else if (i->row < tile_i->subrect.height)
@@ -149,7 +149,11 @@
 
 
 gboolean gegl_buffer_scan_compatible (GeglBuffer *input,
-                                      GeglBuffer *output)
+                                      gint        x0,
+                                      gint        y0,
+                                      GeglBuffer *output,
+                                      gint        x1,
+                                      gint        y1)
 {
   if (input->tile_storage->tile_width !=
       output->tile_storage->tile_width)
@@ -163,6 +167,12 @@
   if (input->shift_y !=
       output->shift_y)
     return FALSE;
+  if (x0!=x1 || y0!=y1)
+    return FALSE;
+  if ( (abs(x0 - x1) % input->tile_storage->tile_width) != 0)
+    return FALSE;
+  if ( (abs(y0 - y1) % input->tile_storage->tile_height) != 0)
+    return FALSE;
   return TRUE;
 }
 
@@ -178,7 +188,6 @@
   gint  buffer_y       = buffer->extent.y + buffer_shift_y;
   gint  buffer_abyss_x = buffer->abyss.x + buffer_shift_x;
   gint  abyss_x_total  = buffer_abyss_x + buffer->abyss.width;
-  gint  buffer_abyss_y = buffer->abyss.y + buffer_shift_y;
 
   if (i->roi.width == 0 || i->roi.height == 0)
     return FALSE;
@@ -209,28 +218,32 @@
       else
         pixels = tile_width - offsetx;
 
-     if (!(buffer_x + i->col + tile_width >= buffer_abyss_x &&
+     /*if (!(buffer_x + i->col + tile_width >= buffer_abyss_x &&
                       buffer_x + i->col < abyss_x_total))
        { 
           g_warning ("entire tile in abyss?");
 
           i->col += tile_width - offsetx;
+          goto gulp;
        }
-     else
+     else*/
        {
          i->subrect.x = offsetx;
          i->subrect.y = offsety;
 
-         i->subrect.width = pixels;
-        /* (i->roi.width - i->col + tile_width < tile_width) ?
+         i->subrect.width = 
+           //pixels;
+        (i->roi.width - i->col + tile_width < tile_width) ?
                              (i->roi.width - i->col + tile_width) - i->subrect.x:
-                             tile_width - i->subrect.x;*/
+                             tile_width - i->subrect.x;
+
+
 
          i->subrect.height = (i->roi.height - i->row + tile_height < tile_height) ?
                              (i->roi.height - i->row + tile_height) - i->subrect.y:
                              tile_height - i->subrect.y;
 
-         if(1){
+         if(0){
          gint lskip = (buffer_abyss_x) - (buffer_x + i->col);
          /* gap between left side of tile, and abyss */
          gint rskip = (buffer_x + i->col + i->subrect.width) - abyss_x_total;
@@ -595,6 +608,7 @@
   gint  i;
   gint  factor = 1;
 
+
   for (i = 0; i < level; i++)
     {
       factor *= 2;
@@ -674,6 +688,7 @@
             else
               pixels = tile_width - offsetx;
 
+
             if (!(buffer_x + bufx + tile_width >= buffer_abyss_x &&
                   buffer_x + bufx < abyss_x_total))
               { /* entire tile is in abyss */
@@ -1411,7 +1426,7 @@
 
   GeglRectangle src_line;
   GeglRectangle dst_line;
-  const Babl   *format;
+  Babl         *fish;
   guchar       *temp;
   guint         i;
   gint          pxsize;
@@ -1430,7 +1445,7 @@
     }
 
   pxsize = src->tile_storage->px_size;
-  format = src->format;
+  fish = babl_fish (src->format, dst->format);
 
   src_line = *src_rect;
   src_line.height = 1;
@@ -1439,12 +1454,49 @@
   dst_line.width = src_line.width;
   dst_line.height = src_line.height;
 
+  if (gegl_buffer_scan_compatible (src, src_rect->x, src_rect->y,
+                                   dst, dst_rect->x, dst_rect->y)) /*  is this check good enough
+                                               *  with the shifts we might
+                                               *  do?
+                                               */
+    {
+      GeglBufferScanIterator read;
+      GeglBufferScanIterator write;
+      gboolean a=FALSE,b=FALSE;
+
+      gegl_buffer_scan_iterator_init (&read,  src, *dst_rect, FALSE);
+      gegl_buffer_scan_iterator_init (&write, dst, *dst_rect, TRUE);
+
+      gegl_buffer_lock (dst);
+
+      while (  (a = gegl_buffer_scan_iterator_next (&read)) &&
+               (b = gegl_buffer_scan_iterator_next (&write)))
+        {
+          GeglRectangle roi;
+          gegl_buffer_scan_iterator_get_rectangle (&write, &roi);
+          /* XXX: check if we have a full tile, if we do we can clone
+           * it
+           */
+          g_assert (read.length == write.length);
+          babl_process (fish, read.data, write.data, write.length);
+        }
+
+      if (a)
+        while (gegl_buffer_scan_iterator_next (&read));
+      if (b)
+        while (gegl_buffer_scan_iterator_next (&write));
+
+      gegl_buffer_unlock (dst);
+
+      return;
+    }
+
   temp = g_malloc (src_line.width * pxsize);
 
   for (i=0; i<src_rect->height; i++)
     {
-      gegl_buffer_get (src, 1.0, &src_line, format, temp, GEGL_AUTO_ROWSTRIDE);
-      gegl_buffer_set (dst, &dst_line, format, temp, GEGL_AUTO_ROWSTRIDE);
+      gegl_buffer_get (src, 1.0, &src_line, dst->format, temp, GEGL_AUTO_ROWSTRIDE);
+      gegl_buffer_set (dst, &dst_line, dst->format, temp, GEGL_AUTO_ROWSTRIDE);
       src_line.y++;
       dst_line.y++;
     }

Modified: trunk/gegl/buffer/gegl-buffer-private.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-private.h	(original)
+++ trunk/gegl/buffer/gegl-buffer-private.h	Tue Jun  3 21:00:16 2008
@@ -109,8 +109,8 @@
   gint           row;
   gint           real_col;
   gint           real_row;
-  gboolean       write;   /* perhaps in a subclass struct? */
-  GeglRectangle  subrect; /* has x==-1 when entire tile is valid */
+  gboolean       write;
+  GeglRectangle  subrect;
   gpointer       data;
   gpointer       sub_data;
   gint           rowstride;
@@ -161,8 +161,12 @@
 GeglBufferScanIterator *gegl_buffer_scan_iterator_new (GeglBuffer    *buffer,
                                                        GeglRectangle  roi,
                                                        gboolean       write);
-gboolean                gegl_buffer_scan_compatible   (GeglBuffer    *input,
-                                                       GeglBuffer    *output);
+gboolean gegl_buffer_scan_compatible (GeglBuffer *input,
+                                      gint        x0,
+                                      gint        y0,
+                                      GeglBuffer *output,
+                                      gint        x1,
+                                      gint        y1);
 
 
 #endif

Modified: trunk/gegl/operation/gegl-operation-point-composer.c
==============================================================================
--- trunk/gegl/operation/gegl-operation-point-composer.c	(original)
+++ trunk/gegl/operation/gegl-operation-point-composer.c	Tue Jun  3 21:00:16 2008
@@ -121,7 +121,6 @@
           if (input && aux==NULL)
             {
               gegl_buffer_copy (input, result, output, result);
-              g_print ("copied\n");
               done = TRUE;
             }
 
@@ -141,19 +140,18 @@
 
                   if (!gegl_rectangle_intersect (NULL, aux_abyss, result))
                     {
-                      g_print ("skipped\n");
                       done = TRUE;
                     }
                   else
                     {
                       gegl_buffer_copy (aux, result, output, result);
-                      g_print ("copied aux\n");
                       done = TRUE;
                     }
                 }
             }
 /* SKIP_EMPTY_AUX */
-            {
+            if(!done)
+              {
               const GeglRectangle *aux_abyss = NULL;
 
               if (aux)
@@ -163,7 +161,6 @@
                   (aux && !gegl_rectangle_intersect (NULL, aux_abyss, result)))
                 {
                   gegl_buffer_copy (input, result, output, result);
-                  g_print ("copied input\n");
                   done = TRUE;
                 }
             }
@@ -196,7 +193,7 @@
                                        GeglBuffer          *output,
                                        const GeglRectangle *result)
 {
-  const Babl *in_format = gegl_operation_get_format (operation, "input");
+  const Babl *in_format  = gegl_operation_get_format (operation, "input");
   const Babl *aux_format = gegl_operation_get_format (operation, "aux");
   const Babl *out_format = gegl_operation_get_format (operation, "output");
 
@@ -204,6 +201,69 @@
     {
       gfloat *in_buf = NULL, *out_buf = NULL, *aux_buf = NULL;
 
+      if (gegl_buffer_scan_compatible (input, result->x, result->y,
+                                       output, result->x, result->y))
+        {
+          gint input_bpp  = in_format->format.bytes_per_pixel;
+          gint output_bpp = output->format->format.bytes_per_pixel;
+          gint aux_bpp    = aux?aux->format->format.bytes_per_pixel:1;
+
+          Babl *infish;
+          Babl *outfish;
+          GeglBufferScanIterator read;
+          GeglBufferScanIterator write;
+          gboolean a = FALSE, b = FALSE;
+
+          gegl_buffer_scan_iterator_init (&read,  input,  *result, FALSE);
+          gegl_buffer_scan_iterator_init (&write, output, *result, TRUE);
+          
+          infish = babl_fish (input->format, in_format);
+          outfish = babl_fish (out_format, output->format);
+
+          gegl_buffer_lock (output);
+          
+		 /* FIXME use direct access when possible */
+           {
+              GeglRectangle roi;
+              in_buf  = gegl_malloc (input_bpp * read.max_size);
+              out_buf = gegl_malloc (output_bpp * write.max_size);
+              if (aux)
+                aux_buf = gegl_malloc (aux_bpp * write.max_size);
+              while (  (a = gegl_buffer_scan_iterator_next (&read)) &&
+                       (b = gegl_buffer_scan_iterator_next (&write)))
+                {
+                  gegl_buffer_scan_iterator_get_rectangle (&write, &roi);
+                  if (read.length != write.length)
+                    {
+                      g_print ("%i != %i\n", read.length, write.length);
+                    }
+                  g_assert (read.length == write.length);
+                  babl_process (infish, read.data, in_buf, read.length);
+
+                  if (aux)
+                    {
+                      gegl_buffer_get (aux, 1.0, &roi, aux_format, aux_buf, GEGL_AUTO_ROWSTRIDE);
+
+                    }
+                  GEGL_OPERATION_POINT_COMPOSER_GET_CLASS (operation)->process (
+                        operation,
+                        in_buf,
+                        aux_buf, /* can be NULL */
+                        out_buf,
+                        write.length);
+                  babl_process (outfish, out_buf, write.data, write.length);
+                }
+            }
+
+          gegl_buffer_unlock (output);
+
+          gegl_free (in_buf);
+          gegl_free (out_buf);
+          if (aux)
+            gegl_free (aux_buf);
+          return TRUE;
+        }
+
       in_buf = gegl_malloc (in_format->format.bytes_per_pixel *
                          output->extent.width * output->extent.height);
       if (in_format == out_format)

Modified: trunk/gegl/operation/gegl-operation-point-filter.c
==============================================================================
--- trunk/gegl/operation/gegl-operation-point-filter.c	(original)
+++ trunk/gegl/operation/gegl-operation-point-filter.c	Tue Jun  3 21:00:16 2008
@@ -75,7 +75,8 @@
 
   if ((result->width > 0) && (result->height > 0))
     {
-      if (gegl_buffer_scan_compatible (input, output))
+      if (gegl_buffer_scan_compatible (input, result->x, result->y,
+                                       output, result->x, result->y))
         /* We can use the fastest possible path with the least possible
          * copies using paralell scan iteratator with possibly direct
          * read write access to buffers.



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