Commit 3807aef3 authored by Øyvind Kolås's avatar Øyvind Kolås

avoid unneeded sub buffer. refactored away the scan iterator sitting in

* gegl/buffer/gegl-buffer-access.c: (gegl_buffer_set): avoid unneeded
sub buffer.
* gegl/buffer/gegl-buffer-iterator.c:
(gegl_buffer_tile_iterator_init), (gegl_buffer_tile_iterator_next),
(gegl_buffer_iterator_add), (gegl_buffer_iterator_next): refactored
away the scan iterator sitting in front of the tile iterator, operate
directly on the tiles.

svn path=/trunk/; revision=2700
parent 01a24a55
2008-11-07 Øyvind Kolås <pippin@gimp.org>
* gegl/buffer/gegl-buffer-access.c: (gegl_buffer_set): avoid unneeded
sub buffer.
* gegl/buffer/gegl-buffer-iterator.c:
(gegl_buffer_tile_iterator_init), (gegl_buffer_tile_iterator_next),
(gegl_buffer_iterator_add), (gegl_buffer_iterator_next): refactored
away the scan iterator sitting in front of the tile iterator, operate
directly on the tiles.
2008-11-07 Øyvind Kolås <pippin@gimp.org>
* examples/hello-world.c: (main): add prefix to op-name.
2008-11-06 Øyvind Kolås <pippin@gimp.org>
* gegl/buffer/gegl-buffer-access.c: (gegl_buffer_set): avoid creating
a temporary sub_buffer since object creation is expensive.
2008-11-06 Øyvind Kolås <pippin@gimp.org>
* gegl/buffer/gegl-buffer-iterator.c: Modified code to only pass
......
......@@ -591,8 +591,6 @@ gegl_buffer_set (GeglBuffer *buffer,
void *src,
gint rowstride)
{
GeglBuffer *sub_buf;
g_return_if_fail (GEGL_IS_BUFFER (buffer));
#if ENABLE_MP
......@@ -607,19 +605,9 @@ gegl_buffer_set (GeglBuffer *buffer,
{
pset (buffer, rect->x, rect->y, format, src);
}
/* FIXME: if rect->width == TILE_WIDTH and rect->height == TILE_HEIGHT and
* aligned with tile grid, do a fast path, also provide helper functions
* for figuring out how to align accesses with the tile grid.
*/
else if (rect == NULL)
{
gegl_buffer_iterate (buffer, NULL, src, rowstride, TRUE, format, 0);
}
else
{
sub_buf = gegl_buffer_create_sub_buffer (buffer, rect);
gegl_buffer_iterate (sub_buf, NULL, src, rowstride, TRUE, format, 0);
g_object_unref (sub_buf);
gegl_buffer_iterate (buffer, rect, src, rowstride, TRUE, format, 0);
}
if (gegl_buffer_is_shared(buffer))
......
......@@ -47,21 +47,12 @@ typedef struct GeglBufferTileIterator
gint next_col; /* used internally */
gint next_row; /* used internally */
} GeglBufferTileIterator;
typedef struct GeglBufferScanIterator {
GeglBufferTileIterator tile_iterator; /* must be first member since we do
casting */
gint max_size; /* maximum data buffer needed, in bytes */
gint length; /* how long the current scan is in pixels */
gpointer data; /* the current scans data */
GeglRectangle roi; /* the rectangular subregion of data
* in the buffer represented by this scan.
*/
gint max_size; /* maximum data buffer needed, in bytes */
GeglRectangle roi2; /* the rectangular subregion of data
* in the buffer represented by this scan.
*/
gint row; /* used internally */
gint next_row; /* used internally */
} GeglBufferScanIterator;
} GeglBufferTileIterator;
#define GEGL_BUFFER_SCAN_COMPATIBLE 128 /* should be integrated into enum */
#define GEGL_BUFFER_FORMAT_COMPATIBLE 256 /* should be integrated into enum */
......@@ -78,12 +69,10 @@ typedef struct GeglBufferIterators
gint iteration_no;
GeglRectangle rect [GEGL_BUFFER_MAX_ITERATORS];
const Babl *format [GEGL_BUFFER_MAX_ITERATORS];
Babl *fish_from [GEGL_BUFFER_MAX_ITERATORS];
Babl *fish_to [GEGL_BUFFER_MAX_ITERATORS];
GeglBuffer *buffer [GEGL_BUFFER_MAX_ITERATORS];
guint flags [GEGL_BUFFER_MAX_ITERATORS];
gpointer buf [GEGL_BUFFER_MAX_ITERATORS];
GeglBufferScanIterator i[GEGL_BUFFER_MAX_ITERATORS];
GeglBufferTileIterator i[GEGL_BUFFER_MAX_ITERATORS];
} GeglBufferIterators;
......@@ -92,11 +81,6 @@ static void gegl_buffer_tile_iterator_init (GeglBufferTileIterator *i,
GeglRectangle roi,
gboolean write);
static gboolean gegl_buffer_tile_iterator_next (GeglBufferTileIterator *i);
static void gegl_buffer_scan_iterator_init (GeglBufferScanIterator *i,
GeglBuffer *buffer,
GeglRectangle roi,
gboolean write);
static gboolean gegl_buffer_scan_iterator_next (GeglBufferScanIterator *i);
/*
* check whether iterations on two buffers starting from the given coordinates with
......@@ -142,6 +126,8 @@ static void gegl_buffer_tile_iterator_init (GeglBufferTileIterator *i,
i->col = 0;
i->row = 0;
i->write = write;
i->max_size = i->buffer->tile_storage->tile_width *
i->buffer->tile_storage->tile_height;
}
static gboolean
......@@ -211,6 +197,12 @@ gulp:
i->row = i->next_row;
i->next_col += tile_width - offsetx;
i->roi2.x = i->roi.x + i->col;
i->roi2.y = i->roi.y + i->row;
i->roi2.width = i->subrect.width;
i->roi2.height = i->subrect.height;
return TRUE;
}
}
......@@ -237,80 +229,6 @@ gulp:
return FALSE;
}
static void gegl_buffer_scan_iterator_init (GeglBufferScanIterator *i,
GeglBuffer *buffer,
GeglRectangle roi,
gboolean write)
{
GeglBufferTileIterator *tile_i = (GeglBufferTileIterator*)i;
g_assert (i);
memset (i, 0, sizeof (GeglBufferScanIterator));
gegl_buffer_tile_iterator_init (tile_i, buffer, roi, write);
i->max_size = tile_i->buffer->tile_storage->tile_width *
tile_i->buffer->tile_storage->tile_height *
tile_i->buffer->format->format.bytes_per_pixel;
i->row = 0;
if (write)
gegl_buffer_lock (buffer);
}
static gboolean
gegl_buffer_scan_iterator_next (GeglBufferScanIterator *i)
{
GeglBufferTileIterator *tile_i = (GeglBufferTileIterator*)i;
if (tile_i->tile==NULL)
{
gulp:
if (!gegl_buffer_tile_iterator_next (tile_i))
return FALSE; /* this is where the scan iterator terminates */
i->length = tile_i->subrect.width;
i->next_row = 0;
i->row = 0;
i->roi.x = tile_i->roi.x + tile_i->col;
i->roi.y = tile_i->roi.y + tile_i->row + i->row;
i->roi.width = tile_i->subrect.width;
i->roi.height = tile_i->subrect.height;
}
/* we should now have a valid tile */
if (i->next_row < tile_i->subrect.height)
{
if (tile_i->subrect.width == tile_i->buffer->tile_storage->tile_width || 1)
/* the entire contents of the tile can be expressed as one long scan */
{
i->length = tile_i->subrect.width * tile_i->subrect.height;
i->data = tile_i->sub_data;
i->row = 0;
i->next_row = tile_i->subrect.height;
return TRUE;
}
else
/* iterate thorugh the scanlines in the subrect */
{
guchar *data = tile_i->sub_data;
i->roi.height = 1;
if (i->next_row!=0)
i->roi.y++;
i->data = data + i->next_row * tile_i->rowstride;
i->row = i->next_row;
i->next_row ++;
return TRUE;
}
}
else
{ /* we're done with that tile go get another one if possible */
goto gulp;
}
return FALSE;
}
gint
gegl_buffer_iterator_add (GeglBufferIterator *iterator,
GeglBuffer *buffer,
......@@ -332,7 +250,8 @@ gegl_buffer_iterator_add (GeglBufferIterator *iterator,
self = i->iterators++;
/* FIXME: handle roi == NULL, by copying from where it makes sense */
if (!roi)
roi = self==0?&(buffer->extent):&(i->rect[0]);
i->rect[self]=*roi;
i->buffer[self]=gegl_buffer_create_sub_buffer (buffer, roi);
......@@ -345,7 +264,7 @@ gegl_buffer_iterator_add (GeglBufferIterator *iterator,
if (self==0) /* The first buffer which is always scan aligned */
{
i->flags[self] |= GEGL_BUFFER_SCAN_COMPATIBLE;
gegl_buffer_scan_iterator_init (&i->i[self], i->buffer[self], i->rect[self], ((i->flags[self] & GEGL_BUFFER_WRITE) != 0) );
gegl_buffer_tile_iterator_init (&i->i[self], i->buffer[self], i->rect[self], ((i->flags[self] & GEGL_BUFFER_WRITE) != 0) );
}
else
{
......@@ -357,29 +276,17 @@ gegl_buffer_iterator_add (GeglBufferIterator *iterator,
i->buffer[self], i->rect[self].x, i->rect[self].y))
{
i->flags[self] |= GEGL_BUFFER_SCAN_COMPATIBLE;
gegl_buffer_scan_iterator_init (&i->i[self], i->buffer[self], i->rect[self], ((i->flags[self] & GEGL_BUFFER_WRITE) != 0));
gegl_buffer_tile_iterator_init (&i->i[self], i->buffer[self], i->rect[self], ((i->flags[self] & GEGL_BUFFER_WRITE) != 0));
}
}
/* always allocating */
i->buf[self] = gegl_malloc (i->format[self]->format.bytes_per_pixel *
i->i[0].max_size);
/* the iterator needs to allocate a buffer if the desired pixel format and
* the buffers pixel format differ or the scan iterators are not compatible.
*/
if (i->format[self] == i->buffer[self]->format)
{
g_assert (i->flags[self]);
i->flags[self] |= GEGL_BUFFER_FORMAT_COMPATIBLE;
}
/* create babl fishes needed for desired operations */
if (i->flags[self] & GEGL_BUFFER_READ)
i->fish_from[self] = babl_fish (i->buffer[self]->format, i->format[self]);
if (i->flags[self] & GEGL_BUFFER_WRITE)
i->fish_to[self] = babl_fish (i->format[self], i->buffer[self]->format);
return self;
}
......@@ -401,7 +308,7 @@ gboolean gegl_buffer_iterator_next (GeglBufferIterator *iterator)
if (i->flags[no] & GEGL_BUFFER_SCAN_COMPATIBLE &&
i->flags[no] & GEGL_BUFFER_FORMAT_COMPATIBLE &&
i->roi[no].width == i->i[no].tile_iterator.buffer->tile_storage->tile_width && (i->flags[no] & GEGL_BUFFER_FORMAT_COMPATIBLE))
i->roi[no].width == i->i[no].buffer->tile_storage->tile_width && (i->flags[no] & GEGL_BUFFER_FORMAT_COMPATIBLE))
{
/* direct access */
}
......@@ -421,17 +328,12 @@ gboolean gegl_buffer_iterator_next (GeglBufferIterator *iterator)
if (i->flags[no] & GEGL_BUFFER_SCAN_COMPATIBLE)
{
gboolean res;
res = gegl_buffer_scan_iterator_next (&i->i[no]);
res = gegl_buffer_tile_iterator_next (&i->i[no]);
if (no == 0)
{
result = res;
i->length = i->i[0].length;
}
else
{
g_assert (i->length == i->i[0].length);
}
i->roi[no] = i->i[no].roi;
i->roi[no] = i->i[no].roi2;
/* since they were scan compatible this should be true */
if (res != result)
......@@ -440,10 +342,12 @@ gboolean gegl_buffer_iterator_next (GeglBufferIterator *iterator)
}
g_assert (res == result);
if (i->roi[no].width == i->i[no].tile_iterator.buffer->tile_storage->tile_width && (i->flags[no] & GEGL_BUFFER_FORMAT_COMPATIBLE))
if ((i->flags[no] & GEGL_BUFFER_FORMAT_COMPATIBLE) &&
i->roi[no].width == i->i[no].buffer->tile_storage->tile_width
)
{
/* direct access */
i->data[no]=i->i[no].data;
i->data[no]=i->i[no].sub_data;
}
else
{
......@@ -458,13 +362,12 @@ gboolean gegl_buffer_iterator_next (GeglBufferIterator *iterator)
i->roi[no].x += (i->rect[no].x-i->rect[0].x);
i->roi[no].y += (i->rect[no].y-i->rect[0].y);
g_assert (i->length == i->roi[no].width * i->roi[no].height);
g_assert (i->buf[no]);
gegl_buffer_get (i->buffer[no], 1.0, &(i->roi[no]), i->format[no], i->buf[no], GEGL_AUTO_ROWSTRIDE);
i->data[no]=i->buf[no];
}
i->length = i->roi[no].width * i->roi[no].height;
}
i->iteration_no++;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment