[gegl] buffer: avoid allocation/chunking when downsampling by a power of 2
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: avoid allocation/chunking when downsampling by a power of 2
- Date: Sun, 14 Oct 2018 12:44:13 +0000 (UTC)
commit cb0acb7c7b4f60bfc4573e7a56b83800e7e2b44a
Author: Ell <ell_se yahoo com>
Date: Sun Oct 14 08:14:50 2018 -0400
buffer: avoid allocation/chunking when downsampling by a power of 2
In _gegl_buffer_get_unlocked(), we already avoid filtering when
downsampling by a power of 2, but let's also avoid allocating a
sample buffer and chunking altogether.
gegl/buffer/gegl-buffer-access.c | 52 +++++++++++++++++++++++-----------------
1 file changed, 30 insertions(+), 22 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index 587dfc949..259a185bb 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -2089,6 +2089,35 @@ _gegl_buffer_get_unlocked (GeglBuffer *buffer,
int allocated = 0;
gint interpolation = (flags & GEGL_BUFFER_FILTER_ALL);
gint factor = 1;
+
+ while (scale <= 0.5)
+ {
+ x1 = 0 < x1 ? x1 / 2 : (x1 - 1) / 2;
+ x2 = 0 < x2 ? (x2 + 1) / 2 : x2 / 2;
+ scale *= 2;
+ factor *= 2;
+ level++;
+ }
+
+ if (GEGL_FLOAT_EQUAL (scale, 1.0))
+ {
+ GeglRectangle rect0;
+
+ rect0.x = floorf (rect->x / scale_orig + GEGL_SCALE_EPSILON);
+ rect0.y = floorf (rect->y / scale_orig + GEGL_SCALE_EPSILON);
+ rect0.width = ceilf ((rect->x + rect->width) / scale_orig -
+ GEGL_SCALE_EPSILON) -
+ rect0.x;
+ rect0.height = ceilf ((rect->y + rect->height) / scale_orig -
+ GEGL_SCALE_EPSILON) -
+ rect0.y;
+
+ gegl_buffer_iterate_read_dispatch (buffer, &rect0,
+ dest_buf, rowstride,
+ format, level, repeat_mode);
+ return;
+ }
+
chunk_height = (1024 * 128) / max_bytes_per_row;
if (chunk_height < 4)
@@ -2102,15 +2131,6 @@ _gegl_buffer_get_unlocked (GeglBuffer *buffer,
chunk_height = rect2.height;
}
- while (scale <= 0.5)
- {
- x1 = 0 < x1 ? x1 / 2 : (x1 - 1) / 2;
- x2 = 0 < x2 ? (x2 + 1) / 2 : x2 / 2;
- scale *= 2;
- factor *= 2;
- level++;
- }
-
allocated = max_bytes_per_row * ((chunk_height+1) * 2);
if (interpolation == GEGL_BUFFER_FILTER_AUTO)
@@ -2149,18 +2169,6 @@ _gegl_buffer_get_unlocked (GeglBuffer *buffer,
if (rowstride == GEGL_AUTO_ROWSTRIDE)
rowstride = rect2.width * bpp;
- if (GEGL_FLOAT_EQUAL (scale, 1.0))
- {
- sample_rect.x = factor * x1;
- sample_rect.y = factor * y1;
- sample_rect.width = factor * (x2 - x1);
- sample_rect.height = factor * (y2 - y1);
- gegl_buffer_iterate_read_dispatch (buffer, &sample_rect,
- (guchar*)dest_buf, rowstride,
- format, level, repeat_mode);
- goto setup_next_chunk;
- }
-
/* this is the level where we split and chew through a small temp-buf worth of data
* possibly managing to keep things in L2 cache
*/
@@ -2289,7 +2297,7 @@ _gegl_buffer_get_unlocked (GeglBuffer *buffer,
}
break;
}
-setup_next_chunk:
+
dest_buf = ((guchar*)dest_buf) + rowstride * rect2.height;
ystart+=rect2.height;
rect2.y = ystart;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]