[gegl] buffer: use gegl_buffer_foreach_tile() in gegl_buffer_set_color_from_pixel()
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: use gegl_buffer_foreach_tile() in gegl_buffer_set_color_from_pixel()
- Date: Thu, 29 Nov 2018 15:44:34 +0000 (UTC)
commit 904445c2a00752ec7751f6a2183499a3a4373115
Author: Ell <ell_se yahoo com>
Date: Thu Nov 29 10:20:23 2018 -0500
buffer: use gegl_buffer_foreach_tile() in gegl_buffer_set_color_from_pixel()
... so that we use a single cloned tile when filling whole tiles.
Additionally, convert the incoming pixel to the native buffer
format early on, to avoid conversion during iteration.
gegl/buffer/gegl-buffer-access.c | 91 ++++++++++++++++++++++++++++++++++------
1 file changed, 79 insertions(+), 12 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index 2637478b2..65d90364e 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -2870,14 +2870,69 @@ gegl_buffer_set_pattern (GeglBuffer *buffer,
gegl_free (pattern_data);
}
+typedef struct
+{
+ gconstpointer pixel;
+ gint bpp;
+
+ GeglTile *tile;
+} SetColorFromPixelData;
+
+static void
+gegl_buffer_set_color_from_pixel_tile (GeglBuffer *dst,
+ gint tile_x,
+ gint tile_y,
+ SetColorFromPixelData *data)
+{
+ GeglTile *tile;
+
+ if (! data->tile)
+ {
+ data->tile = gegl_tile_new (dst->tile_storage->tile_size);
+
+ gegl_tile_lock (data->tile);
+
+ gegl_memset_pattern (gegl_tile_get_data (data->tile),
+ data->pixel,
+ data->bpp,
+ dst->tile_storage->tile_size / data->bpp);
+
+ gegl_tile_unlock (data->tile);
+ }
+
+ tile = gegl_tile_dup (data->tile);
+
+ gegl_tile_handler_cache_insert (dst->tile_storage->cache, tile,
+ tile_x, tile_y, 0);
+
+ gegl_tile_unref (tile);
+}
+
+static void
+gegl_buffer_set_color_from_pixel_rect (GeglBuffer *dst,
+ const GeglRectangle *dst_rect,
+ SetColorFromPixelData *data)
+{
+ GeglBufferIterator *i;
+
+ i = gegl_buffer_iterator_new (dst, dst_rect, 0, dst->soft_format,
+ GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE, 1);
+ while (gegl_buffer_iterator_next (i))
+ {
+ gegl_memset_pattern (i->items[0].data,
+ data->pixel,
+ data->bpp,
+ i->length);
+ }
+}
+
void
gegl_buffer_set_color_from_pixel (GeglBuffer *dst,
const GeglRectangle *dst_rect,
const uint8_t *pixel,
const Babl *pixel_format)
{
- GeglBufferIterator *i;
- gint bpp;
+ SetColorFromPixelData data = {};
g_return_if_fail (GEGL_IS_BUFFER (dst));
g_return_if_fail (pixel);
@@ -2888,21 +2943,33 @@ gegl_buffer_set_color_from_pixel (GeglBuffer *dst,
{
dst_rect = gegl_buffer_get_extent (dst);
}
- if (dst_rect->width == 0 ||
- dst_rect->height == 0)
+ if (dst_rect->width <= 0 ||
+ dst_rect->height <= 0)
return;
- bpp = babl_format_get_bytes_per_pixel (pixel_format);
+ data.bpp = babl_format_get_bytes_per_pixel (dst->soft_format);
- /* FIXME: this can be even further optimized by special casing it so
- * that fully filled tiles are shared.
- */
- i = gegl_buffer_iterator_new (dst, dst_rect, 0, pixel_format,
- GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE, 1);
- while (gegl_buffer_iterator_next (i))
+ /* convert the pixel data to the buffer format */
+ if (pixel_format == dst->soft_format)
{
- gegl_memset_pattern (i->items[0].data, pixel, bpp, i->length);
+ data.pixel = pixel;
}
+ else
+ {
+ data.pixel = g_alloca (data.bpp);
+
+ babl_process (babl_fish (pixel_format, dst->soft_format),
+ pixel, (gpointer) data.pixel, 1);
+ }
+
+ gegl_buffer_foreach_tile (
+ dst, dst_rect,
+ (GeglBufferTileFunc) gegl_buffer_set_color_from_pixel_tile,
+ (GeglBufferRectFunc) gegl_buffer_set_color_from_pixel_rect,
+ &data);
+
+ if (data.tile)
+ gegl_tile_unref (data.tile);
}
GeglBuffer *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]