[gegl] buffer: in GeglBufferIterator, alias compatible sub-iterators
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: in GeglBufferIterator, alias compatible sub-iterators
- Date: Wed, 2 Jan 2019 22:01:57 +0000 (UTC)
commit aace10e2bb46fef812b450f422c5a17dea0a72e1
Author: Ell <ell_se yahoo com>
Date: Wed Jan 2 16:55:47 2019 -0500
buffer: in GeglBufferIterator, alias compatible sub-iterators
In GeglBufferIterator, when several sub-iterators are compatible --
i.e., they use the same tile storage and format, fully overlap, and
don't read outside the abyss -- combine their access modes into the
first sub-iterator, and make the rest aliases for it, using the
same data buffer, so that we only fetch the tile, or read/write the
data, once per iteration.
gegl/buffer/gegl-buffer-iterator.c | 122 ++++++++++++++++++++++++-------------
1 file changed, 81 insertions(+), 41 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-iterator.c b/gegl/buffer/gegl-buffer-iterator.c
index 55f86855d..7f8ca014b 100644
--- a/gegl/buffer/gegl-buffer-iterator.c
+++ b/gegl/buffer/gegl-buffer-iterator.c
@@ -57,6 +57,7 @@ typedef struct _SubIterState {
GeglAbyssPolicy abyss_policy;
const Babl *format;
gint format_bpp;
+ gint alias;
GeglIteratorTileMode current_tile_mode;
gint row_stride;
GeglRectangle real_roi;
@@ -161,6 +162,7 @@ _gegl_buffer_iterator_add (GeglBufferIterator *iter,
sub->level = level;
sub->can_discard_data = (access_mode & GEGL_ACCESS_READWRITE) ==
GEGL_ACCESS_WRITE;
+ sub->alias = -1;
if (index > 0)
{
@@ -506,13 +508,20 @@ prepare_iteration (GeglBufferIterator *iter)
gint current_offset_y;
gint j;
+ gegl_buffer_lock (sub->buffer);
+
+ if (sub->alias >= 0)
+ continue;
+
current_offset_x = buf->shift_x + sub->full_rect.x;
current_offset_y = buf->shift_y + sub->full_rect.y;
/* Avoid discarding tile data through a write-only sub-iterator, if
- * another sub-iterator reads the same tile during the same iteration
+ * another sub-iterator reads the same tile during the same iteration.
+ * If the two sub-iterators are compatible, make the second sub-iterator
+ * an alias for the first, combining their access mode.
*/
- for (j = i + 1; sub->can_discard_data && j < priv->num_buffers; j++)
+ for (j = i + 1; j < priv->num_buffers; j++)
{
gint index2 = access_order[j];
SubIterState *sub2 = &priv->sub_iter[index2];
@@ -520,16 +529,30 @@ prepare_iteration (GeglBufferIterator *iter)
gint current_offset2_x;
gint current_offset2_y;
+ if (sub2->alias >= 0)
+ continue;
+
current_offset2_x = buf2->shift_x + sub2->full_rect.x;
current_offset2_y = buf2->shift_y + sub2->full_rect.y;
if (sub2->level == sub->level &&
buf2->tile_storage == buf->tile_storage &&
current_offset2_x == current_offset_x &&
- current_offset2_y == current_offset_y &&
- sub2->access_mode & GEGL_ACCESS_READ)
+ current_offset2_y == current_offset_y)
{
- sub->can_discard_data = FALSE;
+ if (sub2->access_mode & GEGL_ACCESS_READ)
+ sub->can_discard_data = FALSE;
+
+ if (sub2->format == sub->format &&
+ gegl_rectangle_contains (&sub->buffer->abyss,
+ &sub->full_rect) &&
+ gegl_rectangle_contains (&sub2->buffer->abyss,
+ &sub2->full_rect))
+ {
+ sub->access_mode |= sub2->access_mode;
+
+ sub2->alias = index;
+ }
}
}
@@ -566,8 +589,6 @@ prepare_iteration (GeglBufferIterator *iter)
else
sub->access_mode |= GEGL_ITERATOR_INCOMPATIBLE;
}
-
- gegl_buffer_lock (sub->buffer);
}
}
@@ -581,16 +602,30 @@ load_rects (GeglBufferIterator *iter)
for (i = 0; i < priv->num_buffers; i++)
{
- gint index = access_order[i];
+ gint index = access_order[i];
+ SubIterState *sub = &priv->sub_iter[index];
- if (needs_indirect_read (iter, index))
- get_indirect (iter, index);
- else
- get_tile (iter, index);
+ if (sub->alias < 0)
+ {
+ if (needs_indirect_read (iter, index))
+ get_indirect (iter, index);
+ else
+ get_tile (iter, index);
- if ((next_state != GeglIteratorState_InRows) && needs_rows (iter, index))
+ if ((next_state != GeglIteratorState_InRows) &&
+ needs_rows (iter, index))
+ {
+ next_state = GeglIteratorState_InRows;
+ }
+ }
+ else
{
- next_state = GeglIteratorState_InRows;
+ SubIterState *sub_alias = &priv->sub_iter[sub->alias];
+
+ sub->row_stride = sub_alias->row_stride;
+ sub->real_roi = sub_alias->real_roi;
+
+ iter->items[index].data = iter->items[sub->alias].data;
}
}
@@ -635,32 +670,35 @@ _gegl_buffer_iterator_stop (GeglBufferIterator *iter)
gint index = access_order[i];
SubIterState *sub = &priv->sub_iter[index];
- if (sub->current_tile_mode != GeglIteratorTileMode_Empty)
- release_tile (iter, index);
-
- if (sub->linear_tile)
- {
- if (sub->access_mode & GEGL_ACCESS_WRITE)
- gegl_tile_unlock_no_void (sub->linear_tile);
- else
- gegl_tile_read_unlock (sub->linear_tile);
- gegl_tile_unref (sub->linear_tile);
- }
-
- if (sub->level == 0 &&
- sub->access_mode & GEGL_ACCESS_WRITE &&
- ! (sub->access_mode & GEGL_ITERATOR_INCOMPATIBLE))
+ if (sub->alias < 0)
{
- GeglRectangle damage_rect;
-
- damage_rect.x = sub->full_rect.x + sub->buffer->shift_x;
- damage_rect.y = sub->full_rect.y + sub->buffer->shift_y;
- damage_rect.width = sub->full_rect.width;
- damage_rect.height = sub->full_rect.height;
-
- gegl_tile_handler_damage_rect (
- GEGL_TILE_HANDLER (sub->buffer->tile_storage),
- &damage_rect);
+ if (sub->current_tile_mode != GeglIteratorTileMode_Empty)
+ release_tile (iter, index);
+
+ if (sub->linear_tile)
+ {
+ if (sub->access_mode & GEGL_ACCESS_WRITE)
+ gegl_tile_unlock_no_void (sub->linear_tile);
+ else
+ gegl_tile_read_unlock (sub->linear_tile);
+ gegl_tile_unref (sub->linear_tile);
+ }
+
+ if (sub->level == 0 &&
+ sub->access_mode & GEGL_ACCESS_WRITE &&
+ ! (sub->access_mode & GEGL_ITERATOR_INCOMPATIBLE))
+ {
+ GeglRectangle damage_rect;
+
+ damage_rect.x = sub->full_rect.x + sub->buffer->shift_x;
+ damage_rect.y = sub->full_rect.y + sub->buffer->shift_y;
+ damage_rect.width = sub->full_rect.width;
+ damage_rect.height = sub->full_rect.height;
+
+ gegl_tile_handler_damage_rect (
+ GEGL_TILE_HANDLER (sub->buffer->tile_storage),
+ &damage_rect);
+ }
}
gegl_buffer_unlock (sub->buffer);
@@ -804,9 +842,11 @@ gegl_buffer_iterator_next (GeglBufferIterator *iter)
for (i = priv->num_buffers - 1; i >= 0; i--)
{
- gint index = access_order[i];
+ gint index = access_order[i];
+ SubIterState *sub = &priv->sub_iter[index];
- release_tile (iter, index);
+ if (sub->alias < 0)
+ release_tile (iter, index);
}
if (increment_rects (iter) == FALSE)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]