[gimp] app: prefetch entire rows of pixels when finding contiguous regions
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: prefetch entire rows of pixels when finding contiguous regions
- Date: Thu, 12 Jun 2014 21:55:09 +0000 (UTC)
commit 64d9e146d81f0d5068df41c046af29a9f4f30608
Author: Michael Natterer <mitch gimp org>
Date: Thu Jun 12 23:26:01 2014 +0200
app: prefetch entire rows of pixels when finding contiguous regions
Makes the thing about twice as fast (used by fuzzy select, bucket fill)
app/core/gimppickable-contiguous-region.c | 100 +++++++++++++++++++++--------
1 files changed, 74 insertions(+), 26 deletions(-)
---
diff --git a/app/core/gimppickable-contiguous-region.c b/app/core/gimppickable-contiguous-region.c
index 05d2c6b..1f16476 100644
--- a/app/core/gimppickable-contiguous-region.c
+++ b/app/core/gimppickable-contiguous-region.c
@@ -30,6 +30,7 @@
#include "gegl/gimp-babl.h"
+#include "gimp-utils.h" /* GIMP_TIMER */
#include "gimppickable.h"
#include "gimppickable-contiguous-region.h"
@@ -62,8 +63,9 @@ static gboolean find_contiguous_segment (const gfloat *col,
gint initial_x,
gint initial_y,
gint *start,
- gint *end);
-static void find_contiguous_region_helper (GeglBuffer *src_buffer,
+ gint *end,
+ gfloat *row);
+static void find_contiguous_region (GeglBuffer *src_buffer,
GeglBuffer *mask_buffer,
const Babl *format,
gint n_components,
@@ -126,11 +128,15 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
mask_buffer = gegl_buffer_new (gegl_buffer_get_extent (src_buffer),
babl_format ("Y float"));
- find_contiguous_region_helper (src_buffer, mask_buffer,
- format, n_components, has_alpha,
- select_transparent, select_criterion,
- antialias, threshold,
- x, y, start_col);
+ GIMP_TIMER_START();
+
+ find_contiguous_region (src_buffer, mask_buffer,
+ format, n_components, has_alpha,
+ select_transparent, select_criterion,
+ antialias, threshold,
+ x, y, start_col);
+
+ GIMP_TIMER_END("foo")
return mask_buffer;
}
@@ -360,6 +366,8 @@ pixel_difference (const gfloat *col1,
}
}
+#define FETCH_ROW 1
+
static gboolean
find_contiguous_segment (const gfloat *col,
GeglBuffer *src_buffer,
@@ -375,14 +383,24 @@ find_contiguous_segment (const gfloat *col,
gint initial_x,
gint initial_y,
gint *start,
- gint *end)
+ gint *end,
+ gfloat *row)
{
- gfloat s[MAX_CHANNELS];
- gfloat mask_row[width];
- gfloat diff;
+ gfloat *s;
+ gfloat mask_row[width];
+ gfloat diff;
+
+#ifdef FETCH_ROW
+ gegl_buffer_get (src_buffer, GEGL_RECTANGLE (0, initial_y, width, 1), 1.0,
+ format,
+ row, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+ s = row + initial_x * n_components;
+#else
+ s = g_alloca (n_components * sizeof (gfloat));
gegl_buffer_sample (src_buffer, initial_x, initial_y, NULL, s, format,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
+#endif
diff = pixel_difference (col, s, antialias, threshold,
n_components, has_alpha, select_transparent,
@@ -395,11 +413,16 @@ find_contiguous_segment (const gfloat *col,
mask_row[initial_x] = diff;
*start = initial_x - 1;
+#ifdef FETCH_ROW
+ s = row + *start * n_components;
+#endif
while (*start >= 0 && diff)
{
+#ifndef FETCH_ROW
gegl_buffer_sample (src_buffer, *start, initial_y, NULL, s, format,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
+#endif
diff = pixel_difference (col, s, antialias, threshold,
n_components, has_alpha, select_transparent,
@@ -408,16 +431,26 @@ find_contiguous_segment (const gfloat *col,
mask_row[*start] = diff;
if (diff)
- (*start)--;
+ {
+ (*start)--;
+#ifdef FETCH_ROW
+ s -= n_components;
+#endif
+ }
}
diff = 1;
*end = initial_x + 1;
+#ifdef FETCH_ROW
+ s = row + *end * n_components;
+#endif
while (*end < width && diff)
{
+#ifndef FETCH_ROW
gegl_buffer_sample (src_buffer, *end, initial_y, NULL, s, format,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
+#endif
diff = pixel_difference (col, s, antialias, threshold,
n_components, has_alpha, select_transparent,
@@ -426,7 +459,12 @@ find_contiguous_segment (const gfloat *col,
mask_row[*end] = diff;
if (diff)
- (*end)++;
+ {
+ (*end)++;
+#ifdef FETCH_ROW
+ s += n_components;
+#endif
+ }
}
gegl_buffer_set (mask_buffer, GEGL_RECTANGLE (*start, initial_y,
@@ -438,22 +476,27 @@ find_contiguous_segment (const gfloat *col,
}
static void
-find_contiguous_region_helper (GeglBuffer *src_buffer,
- GeglBuffer *mask_buffer,
- const Babl *format,
- gint n_components,
- gboolean has_alpha,
- gboolean select_transparent,
- GimpSelectCriterion select_criterion,
- gboolean antialias,
- gfloat threshold,
- gint x,
- gint y,
- const gfloat *col)
+find_contiguous_region (GeglBuffer *src_buffer,
+ GeglBuffer *mask_buffer,
+ const Babl *format,
+ gint n_components,
+ gboolean has_alpha,
+ gboolean select_transparent,
+ GimpSelectCriterion select_criterion,
+ gboolean antialias,
+ gfloat threshold,
+ gint x,
+ gint y,
+ const gfloat *col)
{
gint start, end;
gint new_start, new_end;
GQueue *coord_stack;
+ gfloat *row = NULL;
+
+#ifdef FETCH_ROW
+ row = g_new (gfloat, gegl_buffer_get_width (src_buffer) * n_components);
+#endif
coord_stack = g_queue_new ();
@@ -489,7 +532,8 @@ find_contiguous_region_helper (GeglBuffer *src_buffer,
gegl_buffer_get_width (src_buffer),
select_transparent, select_criterion,
antialias, threshold, x, y,
- &new_start, &new_end))
+ &new_start, &new_end,
+ row))
continue;
if (y + 1 < gegl_buffer_get_height (src_buffer))
@@ -510,4 +554,8 @@ find_contiguous_region_helper (GeglBuffer *src_buffer,
while (! g_queue_is_empty (coord_stack));
g_queue_free (coord_stack);
+
+#ifdef FETCH_ROW
+ g_free (row);
+#endif
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]