[gegl] plasma: don't use a sampler + fix + speedup
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] plasma: don't use a sampler + fix + speedup
- Date: Mon, 14 May 2018 07:12:59 +0000 (UTC)
commit fa702369ad30bafe82a86b171776e3e24a276675
Author: Ell <ell_se yahoo com>
Date: Mon May 14 02:47:14 2018 -0400
plasma: don't use a sampler + fix + speedup
gegl:plasma uses a sampler, created at the start of the operation,
to sample the output buffer, after having written to it. This
should be avoided, since the sampler may return outdated cached
data (at least in theory). Use gegl_buffer_get() instead.
When the subdivided region is small enough, the op switches to use
a linear buffer, instead of directly using the output buffer, to
speed processing up. However, the op only writes to the linear
buffer, while still reading from the output buffer, which both
produces (subtly) wrong results, and is slower than necessary. Fix
this by reading from the linear buffer, when in use.
Update reference hash.
operations/common-gpl3+/plasma.c | 66 +++++++++++++++++++++++++++-----------
1 files changed, 47 insertions(+), 19 deletions(-)
---
diff --git a/operations/common-gpl3+/plasma.c b/operations/common-gpl3+/plasma.c
index c7026af..8b43a50 100644
--- a/operations/common-gpl3+/plasma.c
+++ b/operations/common-gpl3+/plasma.c
@@ -82,7 +82,6 @@ property_seed (seed, _("Random seed"), rand)
typedef struct
{
GeglBuffer *output;
- GeglSampler *sampler;
GRand *gr;
GeglProperties *o;
float *buffer;
@@ -132,6 +131,40 @@ add_random (GRand *gr,
}
static void
+get_pixel (PlasmaContext *context,
+ gfloat *pixel,
+ gint x,
+ gint y)
+{
+ if (G_UNLIKELY (!context->using_buffer))
+ {
+ GeglRectangle rect;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = 1;
+ rect.height = 1;
+
+ gegl_buffer_get (context->output, &rect, 1.0, NULL /* R'G'B' float */,
+ pixel, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+ }
+ else
+ {
+ float *ptr;
+ gint index;
+
+ index = ((y - context->buffer_y) * context->buffer_width +
+ x - context->buffer_x);
+
+ ptr = context->buffer + index * 3;
+
+ *pixel++ = *ptr++;
+ *pixel++ = *ptr++;
+ *pixel++ = *ptr++;
+ }
+}
+
+static void
put_pixel (PlasmaContext *context,
gfloat *pixel,
gint x,
@@ -148,7 +181,6 @@ put_pixel (PlasmaContext *context,
gegl_buffer_set (context->output, &rect, 0, NULL /* R'G'B' float */,
pixel, GEGL_AUTO_ROWSTRIDE);
- return;
}
else
{
@@ -173,8 +205,7 @@ do_plasma (PlasmaContext *context,
gint x2,
gint y2,
gint plasma_depth,
- gint recursion_depth,
- gint level)
+ gint recursion_depth)
{
gfloat tl[3], ml[3], bl[3], mt[3], mm[3], mb[3], tr[3], mr[3], br[3];
gfloat tmp[3];
@@ -201,7 +232,7 @@ do_plasma (PlasmaContext *context,
context->buffer_y = y1;
context->buffer_width = x2 - x1 + 1;
- ret = do_plasma (context, x1, y1, x2, y2, plasma_depth, recursion_depth, level);
+ ret = do_plasma (context, x1, y1, x2, y2, plasma_depth, recursion_depth);
context->using_buffer = FALSE;
@@ -251,10 +282,10 @@ do_plasma (PlasmaContext *context,
if (x1 == x2 && y1 == y2)
return FALSE;
- gegl_sampler_get (context->sampler, x1, y1, NULL, tl, GEGL_ABYSS_NONE);
- gegl_sampler_get (context->sampler, x1, y2, NULL, bl, GEGL_ABYSS_NONE);
- gegl_sampler_get (context->sampler, x2, y1, NULL, tr, GEGL_ABYSS_NONE);
- gegl_sampler_get (context->sampler, x2, y2, NULL, br, GEGL_ABYSS_NONE);
+ get_pixel (context, tl, x1, y1);
+ get_pixel (context, bl, x1, y2);
+ get_pixel (context, tr, x2, y1);
+ get_pixel (context, br, x2, y2);
ran = context->o->turbulence / (2.0 * recursion_depth);
@@ -311,14 +342,14 @@ do_plasma (PlasmaContext *context,
if (x1 < x2 || y1 < y2)
{
/* Top left. */
- do_plasma (context, x1, y1, xm, ym, plasma_depth - 1, recursion_depth + 1, level);
+ do_plasma (context, x1, y1, xm, ym, plasma_depth - 1, recursion_depth + 1);
/* Bottom left. */
- do_plasma (context, x1, ym, xm, y2, plasma_depth - 1, recursion_depth + 1, level);
+ do_plasma (context, x1, ym, xm, y2, plasma_depth - 1, recursion_depth + 1);
/* Top right. */
- do_plasma (context, xm, y1, x2, ym, plasma_depth - 1, recursion_depth + 1, level);
+ do_plasma (context, xm, y1, x2, ym, plasma_depth - 1, recursion_depth + 1);
/* Bottom right. */
return do_plasma (context, xm, ym, x2, y2,
- plasma_depth - 1, recursion_depth + 1, level);
+ plasma_depth - 1, recursion_depth + 1);
}
return TRUE;
@@ -343,8 +374,6 @@ process (GeglOperation *operation,
context = g_new (PlasmaContext, 1);
context->o = GEGL_PROPERTIES (operation);
context->output = output;
- context->sampler = gegl_buffer_sampler_new_at_level (
- context->output, babl_format ("R'G'B' float"), GEGL_SAMPLER_NEAREST, level);
context->buffer = g_malloc (TILE_SIZE * TILE_SIZE * 3 * sizeof (gfloat));
context->using_buffer = FALSE;
@@ -357,18 +386,17 @@ process (GeglOperation *operation,
context->gr = g_rand_new_with_seed (context->o->seed);
- do_plasma (context, result->x, result->y, x-1, y-1, -1, 0, level);
+ do_plasma (context, result->x, result->y, x-1, y-1, -1, 0);
/*
* Now we recurse through the images, going deeper each time
*/
depth = 1;
- while (!do_plasma (context, result->x, result->y, x-1, y-1, depth, 0, level))
+ while (!do_plasma (context, result->x, result->y, x-1, y-1, depth, 0))
depth++;
g_rand_free (context->gr);
g_free (context->buffer);
- g_object_unref (context->sampler);
g_free (context);
return TRUE;
@@ -417,7 +445,7 @@ gegl_op_class_init (GeglOpClass *klass)
"title", _("Plasma"),
"categories", "render",
"position-dependent", "true",
- "reference-hash", "06418af5f015f21fab965ecf439d95f7",
+ "reference-hash", "f5b2ec90eaf0b44d9b06130b3abb73c9",
"license", "GPL3+",
"description", _("Creates an image filled with a plasma effect."),
NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]