[gegl] plasma: Write a rect of pixels at a time, speeding up the op
- From: Mukund Sivaraman <muks src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] plasma: Write a rect of pixels at a time, speeding up the op
- Date: Thu, 30 Jun 2011 11:44:20 +0000 (UTC)
commit ff1d01f3f245b8b1e3ebcec6778fae36e11ef923
Author: Mukund Sivaraman <muks banu com>
Date: Thu Jun 30 17:08:46 2011 +0530
plasma: Write a rect of pixels at a time, speeding up the op
Also remove tabs from all over the code.
operations/workshop/plasma.c | 187 +++++++++++++++++++++++++++---------------
1 files changed, 122 insertions(+), 65 deletions(-)
---
diff --git a/operations/workshop/plasma.c b/operations/workshop/plasma.c
index 0bb7b8a..5b6e092 100644
--- a/operations/workshop/plasma.c
+++ b/operations/workshop/plasma.c
@@ -31,9 +31,9 @@
#ifdef GEGL_CHANT_PROPERTIES
gegl_chant_int (seed, _("Seed"), -1, G_MAXINT, -1,
- _("Random seed. Passing -1 implies that the seed is randomly chosen."))
+ _("Random seed. Passing -1 implies that the seed is randomly chosen."))
gegl_chant_double (turbulence, _("Turbulence"), 0.1, 7.0, 1.0,
- _("The value of the turbulence"))
+ _("The value of the turbulence"))
#else
@@ -42,13 +42,19 @@ gegl_chant_double (turbulence, _("Turbulence"), 0.1, 7.0, 1.0,
#include "gegl-chant.h"
#include <math.h>
-#include <stdio.h>
+
+#define TILE_SIZE 128
typedef struct
{
GeglBuffer *output;
GRand *gr;
GeglChantO *o;
+ float *buffer;
+ gboolean using_buffer;
+ gint buffer_x;
+ gint buffer_y;
+ gint buffer_width;
} PlasmaContext;
static void prepare (GeglOperation *operation)
@@ -91,23 +97,41 @@ add_random (GRand *gr,
if (amount > 0)
for (i = 0; i < 4; i++)
{
- tmp = dest[i] + (gfloat) g_rand_double_range(gr, -amount, amount);
- dest[i] = CLAMP (tmp, 0, 1);
+ tmp = dest[i] + (gfloat) g_rand_double_range(gr, -amount, amount);
+ dest[i] = CLAMP (tmp, 0, 1);
}
}
static void
-put_pixel_to_buffer (GeglBuffer *output,
- gfloat *pixel,
- gint x,
- gint y)
+put_pixel (PlasmaContext *context,
+ gfloat *pixel,
+ gint x,
+ gint y)
{
- GeglRectangle rect = {1, 1, 1, 1};
+ if (G_UNLIKELY (!context->using_buffer))
+ {
+ GeglRectangle rect;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = 1;
+ rect.height = 1;
+
+ gegl_buffer_set (context->output, &rect, babl_format ("RGBA float"), pixel,
+ GEGL_AUTO_ROWSTRIDE);
+ return;
+ }
+ else
+ {
+ float *ptr;
+
+ ptr = context->buffer + ((y - context->buffer_y) * 4 * context->buffer_width) + ((x - context->buffer_x) * 4);
- rect.x = x;
- rect.y = y;
- gegl_buffer_set (output, &rect, babl_format ("RGBA float"), pixel,
- GEGL_AUTO_ROWSTRIDE);
+ *ptr++ = *pixel++;
+ *ptr++ = *pixel++;
+ *ptr++ = *pixel++;
+ *ptr++ = *pixel++;
+ }
}
static gboolean
@@ -124,37 +148,67 @@ do_plasma_big (PlasmaContext *context,
gint xm, ym;
gfloat ran;
+ if (G_UNLIKELY ((!context->using_buffer) &&
+ ((x2 - x1 + 1) <= TILE_SIZE) &&
+ ((y2 - y1 + 1) <= TILE_SIZE)))
+ {
+ gboolean ret;
+ GeglRectangle rect;
+
+ rect.x = x1;
+ rect.y = y1;
+ rect.width = x2 - x1 + 1;
+ rect.height = y2 - y1 + 1;
+
+ gegl_buffer_get (context->output, 1.0, &rect, babl_format ("RGBA float"),
+ context->buffer, GEGL_AUTO_ROWSTRIDE);
+
+ context->using_buffer = TRUE;
+ context->buffer_x = x1;
+ context->buffer_y = y1;
+ context->buffer_width = x2 - x1 + 1;
+
+ ret = do_plasma_big (context, x1, y1, x2, y2, depth, scale_depth);
+
+ context->using_buffer = FALSE;
+
+ gegl_buffer_set (context->output, &rect, babl_format ("RGBA float"),
+ context->buffer, GEGL_AUTO_ROWSTRIDE);
+
+ return ret;
+ }
+
xm = (x1 + x2) / 2;
ym = (y1 + y2) / 2;
if (depth == -1)
{
random_rgba (context->gr, tl);
- put_pixel_to_buffer (context->output, tl, x1, y1);
+ put_pixel (context, tl, x1, y1);
random_rgba (context->gr, tr);
- put_pixel_to_buffer (context->output, tr, x2, y1);
+ put_pixel (context, tr, x2, y1);
random_rgba (context->gr, bl);
- put_pixel_to_buffer (context->output, bl, x1, y2);
+ put_pixel (context, bl, x1, y2);
random_rgba (context->gr, br);
- put_pixel_to_buffer (context->output, br, x2, y2);
+ put_pixel (context, br, x2, y2);
random_rgba (context->gr, mm);
- put_pixel_to_buffer (context->output, mm, xm, ym);
+ put_pixel (context, mm, xm, ym);
random_rgba (context->gr, ml);
- put_pixel_to_buffer (context->output, ml, x1, ym);
+ put_pixel (context, ml, x1, ym);
random_rgba (context->gr, mr);
- put_pixel_to_buffer (context->output, mr, x2, ym);
+ put_pixel (context, mr, x2, ym);
random_rgba (context->gr, mt);
- put_pixel_to_buffer (context->output, mt, xm, y1);
+ put_pixel (context, mt, xm, y1);
random_rgba (context->gr, mb);
- put_pixel_to_buffer (context->output, mb, xm, y2);
+ put_pixel (context, mb, xm, y2);
return FALSE;
}
@@ -165,62 +219,62 @@ do_plasma_big (PlasmaContext *context,
return FALSE;
gegl_buffer_sample (context->output, x1, y1, 1.0, tl, babl_format ("RGBA float"),
- GEGL_INTERPOLATION_NEAREST);
+ GEGL_INTERPOLATION_NEAREST);
gegl_buffer_sample (context->output, x1, y2, 1.0, bl, babl_format ("RGBA float"),
- GEGL_INTERPOLATION_NEAREST);
+ GEGL_INTERPOLATION_NEAREST);
gegl_buffer_sample (context->output, x2, y1, 1.0, tr, babl_format ("RGBA float"),
- GEGL_INTERPOLATION_NEAREST);
+ GEGL_INTERPOLATION_NEAREST);
gegl_buffer_sample (context->output, x2, y2, 1.0, br, babl_format ("RGBA float"),
- GEGL_INTERPOLATION_NEAREST);
+ GEGL_INTERPOLATION_NEAREST);
ran = context->o->turbulence / (2.0 * scale_depth);
if (xm != x1 || xm != x2)
- {
- /* Left. */
- average_pixel (ml, tl, bl);
- add_random (context->gr, ml, ran);
- put_pixel_to_buffer (context->output, ml, x1, ym);
-
- /* Right. */
- if (x1 != x2)
- {
- average_pixel (mr, tr, br);
- add_random (context->gr, mr, ran);
- put_pixel_to_buffer (context->output, mr, x2, ym);
- }
- }
+ {
+ /* Left. */
+ average_pixel (ml, tl, bl);
+ add_random (context->gr, ml, ran);
+ put_pixel (context, ml, x1, ym);
+
+ /* Right. */
+ if (x1 != x2)
+ {
+ average_pixel (mr, tr, br);
+ add_random (context->gr, mr, ran);
+ put_pixel (context, mr, x2, ym);
+ }
+ }
if (ym != y1 || ym != x2)
- {
- /* Bottom. */
- if (x1 != xm || ym != y2)
- {
- average_pixel (mb, bl, br);
- add_random (context->gr, mb, ran);
- put_pixel_to_buffer (context->output, mb, xm, y2);
- }
-
- if (y1 != y2)
- {
- /* Top. */
- average_pixel (mt, tl, tr);
- add_random (context->gr, mt, ran);
- put_pixel_to_buffer (context->output, mt, xm, y1);
- }
- }
+ {
+ /* Bottom. */
+ if (x1 != xm || ym != y2)
+ {
+ average_pixel (mb, bl, br);
+ add_random (context->gr, mb, ran);
+ put_pixel (context, mb, xm, y2);
+ }
+
+ if (y1 != y2)
+ {
+ /* Top. */
+ average_pixel (mt, tl, tr);
+ add_random (context->gr, mt, ran);
+ put_pixel (context, mt, xm, y1);
+ }
+ }
if (y1 != y2 || x1 != x2)
- {
+ {
/* Middle pixel. */
- average_pixel (mm, tl, br);
- average_pixel (tmp, bl, tr);
- average_pixel (mm, mm, tmp);
+ average_pixel (mm, tl, br);
+ average_pixel (tmp, bl, tr);
+ average_pixel (mm, mm, tmp);
- add_random (context->gr, mm, ran);
- put_pixel_to_buffer (context->output, mm, xm, ym);
- }
+ add_random (context->gr, mm, ran);
+ put_pixel (context, mm, xm, ym);
+ }
return x2 - x1 < 3 && y2 - y1 < 3;
}
@@ -265,6 +319,8 @@ process (GeglOperation *operation,
context = g_new (PlasmaContext, 1);
context->o = GEGL_CHANT_PROPERTIES (operation);
context->output = output;
+ context->buffer = g_malloc (TILE_SIZE * TILE_SIZE * 4 * sizeof (float));
+ context->using_buffer = FALSE;
boundary = plasma_get_bounding_box (operation);
@@ -289,6 +345,7 @@ process (GeglOperation *operation,
while (!do_plasma_big (context, boundary.x, boundary.y, x-1, y-1, depth, 0))
depth++;
+ g_free (context->buffer);
g_free (context);
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]