[gegl] buffer: add gegl_buffer_foreach_tile(); use in gegl_buffer_clear()
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: add gegl_buffer_foreach_tile(); use in gegl_buffer_clear()
- Date: Thu, 29 Nov 2018 15:44:29 +0000 (UTC)
commit a9a09b95d126c6c5ae69e7718887854a994df304
Author: Ell <ell_se yahoo com>
Date: Thu Nov 29 10:08:18 2018 -0500
buffer: add gegl_buffer_foreach_tile(); use in gegl_buffer_clear()
Factor the logic for iterating over whole-tiles contained in a
given rect, and over the remaining "edge" rects, out of
gegl_buffer_clear(), and into a new gegl_buffer_foreach_tile()
internal function, which takes a pair of functions: one which
performs the per-tile action, and one which performs the per-rect
action, and calls them for each tile/edge-rect in the given region.
Modify gegl_buffer_clear() to use the new function.
Additionally, when voiding the tiles, call
gegl_tile_handler_cache_remove() directly, to avoid voiding the
tile pyramid at each base tile. Instead, have
gegl_buffer_foreach_tile() void the entire region in a single step.
gegl/buffer/gegl-buffer-access.c | 215 +++++++++++++++++++++-------------
gegl/buffer/gegl-tile-handler-cache.c | 2 +-
gegl/buffer/gegl-tile-handler-cache.h | 4 +
3 files changed, 136 insertions(+), 85 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index 8a8b7865e..2637478b2 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -2579,144 +2579,191 @@ gegl_buffer_copy (GeglBuffer *src,
gegl_buffer_emit_changed_signal (dst, dst_rect);
}
-static void
-gegl_buffer_clear2 (GeglBuffer *dst,
- const GeglRectangle *dst_rect)
-{
- GeglBufferIterator *i;
- gint pxsize;
-
- pxsize = babl_format_get_bytes_per_pixel (dst->soft_format);
-
- if (gegl_buffer_ext_invalidate)
- {
- gegl_buffer_ext_invalidate (dst, dst_rect);
- }
-
- i = gegl_buffer_iterator_new (dst, dst_rect, 0, dst->soft_format,
- GEGL_ACCESS_WRITE | GEGL_ITERATOR_NO_NOTIFY,
- GEGL_ABYSS_NONE, 1);
- while (gegl_buffer_iterator_next (i))
- {
- memset (((guchar*)(i->items[0].data)), 0, i->length * pxsize);
- }
-}
+typedef void (* GeglBufferTileFunc) (GeglBuffer *buffer,
+ gint tile_x,
+ gint tile_y,
+ gpointer data);
+typedef void (* GeglBufferRectFunc) (GeglBuffer *buffer,
+ const GeglRectangle *rect,
+ gpointer data);
-void
-gegl_buffer_clear (GeglBuffer *dst,
- const GeglRectangle *dst_rect)
+static void
+gegl_buffer_foreach_tile (GeglBuffer *buffer,
+ const GeglRectangle *rect,
+ GeglBufferTileFunc tile_func,
+ GeglBufferRectFunc rect_func,
+ gpointer data)
{
- g_return_if_fail (GEGL_IS_BUFFER (dst));
+ if (! rect)
+ rect = gegl_buffer_get_extent (buffer);
- if (!dst_rect)
- {
- dst_rect = gegl_buffer_get_extent (dst);
- }
- if (dst_rect->width <= 0 ||
- dst_rect->height <= 0)
+ if (rect->width <= 0 || rect->height <= 0)
return;
#if 1
/* cow for clearing is currently broken */
- if (dst_rect->width >= dst->tile_width &&
- dst_rect->height >= dst->tile_height &&
- !g_object_get_data (G_OBJECT (dst), "is-linear"))
+ if (rect->width >= buffer->tile_width &&
+ rect->height >= buffer->tile_height &&
+ ! g_object_get_data (G_OBJECT (buffer), "is-linear"))
{
- gint tile_width = dst->tile_width;
- gint tile_height = dst->tile_height;
+ gint tile_width = buffer->tile_width;
+ gint tile_height = buffer->tile_height;
- GeglRectangle cow_rect = *dst_rect;
+ GeglRectangle tile_rect = *rect;
gint rem;
+ /* shift rect to tile coordinate system */
+ tile_rect.x += buffer->shift_x;
+ tile_rect.y += buffer->shift_y;
+
/* adjust origin to match the start of tile alignment */
- rem = (cow_rect.x + dst->shift_x) % tile_width;
+ rem = tile_rect.x % tile_width;
if (rem > 0)
rem -= tile_width;
- cow_rect.x -= rem;
- cow_rect.width += rem;
+ tile_rect.x -= rem;
+ tile_rect.width += rem;
- rem = (cow_rect.y + dst->shift_y) % tile_height;
+ rem = tile_rect.y % tile_height;
if (rem > 0)
rem -= tile_height;
- cow_rect.y -= rem;
- cow_rect.height += rem;
+ tile_rect.y -= rem;
+ tile_rect.height += rem;
/* adjust size of rect to match multiple of tiles */
- cow_rect.width -= cow_rect.width % tile_width;
- cow_rect.height -= cow_rect.height % tile_height;
+ tile_rect.width -= tile_rect.width % tile_width;
+ tile_rect.height -= tile_rect.height % tile_height;
- if (cow_rect.width > 0 && cow_rect.height > 0)
+ if (tile_rect.width > 0 && tile_rect.height > 0)
{
GeglRectangle top, bottom, left, right;
- /* iterate over rectangle that can be cow copied, duplicating
- * one and one tile
- */
+ /* iterate over the tile rectangle */
{
- /* first we do a dumb copy,. but with fetched tiles */
-
- gint dst_x, dst_y;
+ gint x, y;
- g_rec_mutex_lock (&dst->tile_storage->mutex);
+ g_rec_mutex_lock (&buffer->tile_storage->mutex);
- for (dst_y = cow_rect.y + dst->shift_y; dst_y < cow_rect.y + dst->shift_y + cow_rect.height;
dst_y += tile_height)
- for (dst_x = cow_rect.x + dst->shift_x; dst_x < cow_rect.x + dst->shift_x + cow_rect.width;
dst_x += tile_width)
+ for (y = tile_rect.y;
+ y < tile_rect.y + tile_rect.height;
+ y += tile_height)
{
- gint dtx, dty;
+ for (x = tile_rect.x;
+ x < tile_rect.x + tile_rect.width;
+ x += tile_width)
+ {
+ gint tile_x, tile_y;
- dtx = gegl_tile_indice (dst_x, tile_width);
- dty = gegl_tile_indice (dst_y, tile_height);
+ tile_x = gegl_tile_indice (x, tile_width);
+ tile_y = gegl_tile_indice (y, tile_height);
- gegl_tile_source_void ((GeglTileSource*)dst, dtx, dty, 0);
+ tile_func (buffer, tile_x, tile_y, data);
+ }
}
- g_rec_mutex_unlock (&dst->tile_storage->mutex);
+ gegl_tile_handler_damage_rect (
+ GEGL_TILE_HANDLER (buffer->tile_storage),
+ &tile_rect);
+
+ g_rec_mutex_unlock (&buffer->tile_storage->mutex);
}
- top = *dst_rect;
- top.height = (cow_rect.y - dst_rect->y);
+ /* shift rect to buffer coordinate system */
+ tile_rect.x -= buffer->shift_x;
+ tile_rect.y -= buffer->shift_y;
+ top = *rect;
+ top.height = (tile_rect.y - rect->y);
- left = *dst_rect;
- left.y = cow_rect.y;
- left.height = cow_rect.height;
- left.width = (cow_rect.x - dst_rect->x);
- bottom = *dst_rect;
- bottom.y = (cow_rect.y + cow_rect.height);
- bottom.height = (dst_rect->y + dst_rect->height) -
- (cow_rect.y + cow_rect.height);
+ left = *rect;
+ left.y = tile_rect.y;
+ left.height = tile_rect.height;
+ left.width = (tile_rect.x - rect->x);
+
+ bottom = *rect;
+ bottom.y = (tile_rect.y + tile_rect.height);
+ bottom.height = (rect->y + rect->height) -
+ (tile_rect.y + tile_rect.height);
if (bottom.height < 0)
bottom.height = 0;
- right = *dst_rect;
- right.x = (cow_rect.x + cow_rect.width);
- right.width = (dst_rect->x + dst_rect->width) -
- (cow_rect.x + cow_rect.width);
- right.y = cow_rect.y;
- right.height = cow_rect.height;
+ right = *rect;
+ right.x = (tile_rect.x + tile_rect.width);
+ right.width = (rect->x + rect->width) -
+ (tile_rect.x + tile_rect.width);
+ right.y = tile_rect.y;
+ right.height = tile_rect.height;
if (right.width < 0)
right.width = 0;
- if (top.height) gegl_buffer_clear2 (dst, &top);
- if (bottom.height) gegl_buffer_clear2 (dst, &bottom);
- if (left.width && left.height) gegl_buffer_clear2 (dst, &left);
- if (right.width && right.height) gegl_buffer_clear2 (dst, &right);
+ if (top.height) rect_func (buffer, &top, data);
+ if (bottom.height) rect_func (buffer, &bottom, data);
+ if (left.width && left.height) rect_func (buffer, &left, data);
+ if (right.width && right.height) rect_func (buffer, &right, data);
}
else
{
- gegl_buffer_clear2 (dst, dst_rect);
+ rect_func (buffer, rect, data);
}
}
else
#endif
{
- gegl_buffer_clear2 (dst, dst_rect);
+ rect_func (buffer, rect, data);
}
- gegl_buffer_emit_changed_signal (dst, dst_rect);
+ gegl_buffer_emit_changed_signal (buffer, rect);
+}
+
+static void
+gegl_buffer_clear_tile (GeglBuffer *dst,
+ gint tile_x,
+ gint tile_y,
+ gpointer data)
+{
+ gegl_tile_handler_cache_remove (dst->tile_storage->cache,
+ tile_x, tile_y, 0);
+
+ gegl_tile_handler_source_command (dst->tile_storage->cache, GEGL_TILE_VOID,
+ tile_x, tile_y, 0, NULL);
+}
+
+static void
+gegl_buffer_clear_rect (GeglBuffer *dst,
+ const GeglRectangle *dst_rect,
+ gpointer data)
+{
+ GeglBufferIterator *i;
+ gint pxsize;
+
+ pxsize = babl_format_get_bytes_per_pixel (dst->soft_format);
+
+ if (gegl_buffer_ext_invalidate)
+ {
+ gegl_buffer_ext_invalidate (dst, dst_rect);
+ }
+
+ i = gegl_buffer_iterator_new (dst, dst_rect, 0, dst->soft_format,
+ GEGL_ACCESS_WRITE | GEGL_ITERATOR_NO_NOTIFY,
+ GEGL_ABYSS_NONE, 1);
+ while (gegl_buffer_iterator_next (i))
+ {
+ memset (((guchar*)(i->items[0].data)), 0, i->length * pxsize);
+ }
+}
+
+void
+gegl_buffer_clear (GeglBuffer *dst,
+ const GeglRectangle *dst_rect)
+{
+ g_return_if_fail (GEGL_IS_BUFFER (dst));
+
+ gegl_buffer_foreach_tile (dst, dst_rect,
+ gegl_buffer_clear_tile,
+ gegl_buffer_clear_rect,
+ NULL);
}
void
diff --git a/gegl/buffer/gegl-tile-handler-cache.c b/gegl/buffer/gegl-tile-handler-cache.c
index 37e030c87..f25c222d7 100644
--- a/gegl/buffer/gegl-tile-handler-cache.c
+++ b/gegl/buffer/gegl-tile-handler-cache.c
@@ -765,7 +765,7 @@ gegl_tile_handler_cache_remove_item (GeglTileHandlerCache *cache,
g_slice_free (CacheItem, item);
}
-static void
+void
gegl_tile_handler_cache_remove (GeglTileHandlerCache *cache,
gint x,
gint y,
diff --git a/gegl/buffer/gegl-tile-handler-cache.h b/gegl/buffer/gegl-tile-handler-cache.h
index b027974d8..60ef7146a 100644
--- a/gegl/buffer/gegl-tile-handler-cache.h
+++ b/gegl/buffer/gegl-tile-handler-cache.h
@@ -64,6 +64,10 @@ void gegl_tile_handler_cache_insert (GeglTileHandlerCac
gint x,
gint y,
gint z);
+void gegl_tile_handler_cache_remove (GeglTileHandlerCache *cache,
+ gint x,
+ gint y,
+ gint z);
void gegl_tile_handler_cache_tile_uncloned (GeglTileHandlerCache *cache,
GeglTile *tile);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]