[gegl] random: improve gegl-random implementation



commit 57af178e6b5a018ef68a3d2d1d99926b1b866f91
Author: Téo Mazars <teomazars gmail com>
Date:   Thu Nov 14 13:21:07 2013 +0100

    random: improve gegl-random implementation
    
    - introduce a GeglRandom structure instead of accessing the LUT each time
    - make a larger cycle for the seed
    - avoid segfault when a negative seed is given
    - use g(u)int64 instead of long to avoid plaform-dependant behavior
    - make opencl and operations follow that api change
    - build the GeglRandom structure in the gegl-chant machinery when using
      gegl_chant_seed
    - make sure the pointer gegl_random_data is 32bits aligned when used with
      CL_MEM_USE_HOST_PTR

 gegl/Makefile.am                  |    1 +
 gegl/gegl-chant.h                 |   30 +++--
 gegl/gegl-init.c                  |    2 +
 gegl/gegl-random-priv.h           |   15 ++-
 gegl/gegl-random.c                |  266 +++++++++++++++++++++++--------------
 gegl/gegl-random.h                |  131 ++++++++++++++++++
 gegl/gegl-types.h                 |    4 +
 gegl/gegl.h                       |   61 +---------
 gegl/opencl/gegl-cl-random.c      |   32 ++---
 gegl/opencl/gegl-cl-random.h      |    5 +-
 opencl/noise-hurl.cl              |   35 +++---
 opencl/noise-hurl.cl.h            |   35 +++---
 opencl/random.cl                  |  111 ++++++++--------
 opencl/random.cl.h                |  107 ++++++++-------
 operations/common/cubism.c        |    2 +-
 operations/common/mosaic.c        |   38 +++---
 operations/common/noise-cie-lch.c |   39 +++---
 operations/common/noise-hsv.c     |   38 +++---
 operations/common/noise-hurl.c    |   47 +++----
 operations/common/noise-pick.c    |    4 +-
 operations/common/noise-rgb.c     |   10 +-
 operations/common/noise-slur.c    |    4 +-
 operations/common/noise-spread.c  |   24 ++--
 operations/common/plasma.c        |    2 +-
 operations/common/shift.c         |    4 +-
 operations/common/wind.c          |    2 +-
 26 files changed, 609 insertions(+), 440 deletions(-)
---
diff --git a/gegl/Makefile.am b/gegl/Makefile.am
index e779ab0..c998f8c 100644
--- a/gegl/Makefile.am
+++ b/gegl/Makefile.am
@@ -45,6 +45,7 @@ GEGL_introspectable_headers = \
        gegl-utils.h                    \
        gegl-matrix.h                   \
        gegl-lookup.h                   \
+       gegl-random.h                   \
        gegl-version.h                  \
        buffer/gegl-buffer.h            \
        buffer/gegl-buffer-iterator.h   \
diff --git a/gegl/gegl-chant.h b/gegl/gegl-chant.h
index 4920dee..007bc2d 100644
--- a/gegl/gegl-chant.h
+++ b/gegl/gegl-chant.h
@@ -349,7 +349,7 @@ gegl_module_register (GTypeModule *module)
 #define gegl_chant_format(name, nick, blurb)
 #define gegl_chant_color(name, nick, def, blurb)
 #define gegl_chant_curve(name, nick, blurb)
-#define gegl_chant_seed(name, nick, blurb)
+#define gegl_chant_seed(name, rand_name, nick, blurb)
 #define gegl_chant_path(name, nick, blurb)
 #define gegl_chant_register_enum(enum_name) \
 typedef enum {
@@ -434,7 +434,8 @@ struct _GeglChantO
 #define gegl_chant_format(name, nick, blurb)                                    gpointer           name;
 #define gegl_chant_color(name, nick, def, blurb)                                GeglColor         *name;
 #define gegl_chant_curve(name, nick, blurb)                                     GeglCurve         *name;
-#define gegl_chant_seed(name, nick, blurb)                                      gint               name;
+#define gegl_chant_seed(name, rand_name, nick, blurb)                           gint               name;\
+                                                                                GeglRandom        *rand_name;
 #define gegl_chant_path(name, nick, blurb)                                      GeglPath          *name;\
                                                                                 gulong path_changed_handler;
 
@@ -477,7 +478,7 @@ enum
 #define gegl_chant_format(name, nick, blurb)                                    PROP_##name,
 #define gegl_chant_color(name, nick, def, blurb)                                PROP_##name,
 #define gegl_chant_curve(name, nick, blurb)                                     PROP_##name,
-#define gegl_chant_seed(name, nick, blurb)                                      PROP_##name,
+#define gegl_chant_seed(name, rand_name, nick, blurb)                           PROP_##name,
 #define gegl_chant_path(name, nick, blurb)                                      PROP_##name,
 
 #include GEGL_CHANT_C_FILE
@@ -569,7 +570,7 @@ get_property (GObject      *gobject,
     case PROP_##name:                                         \
       g_value_set_object (value, properties->name);           \
       break;
-#define gegl_chant_seed(name, nick, blurb)                    \
+#define gegl_chant_seed(name, rand_name, nick, blurb)         \
     case PROP_##name:                                         \
       g_value_set_int (value, properties->name);              \
       break;
@@ -683,10 +684,14 @@ set_property (GObject      *gobject,
          g_object_unref (properties->name);                           \
       properties->name = g_value_dup_object (value);                  \
       break;
-#define gegl_chant_seed(name, nick, blurb)                            \
+#define gegl_chant_seed(name, rand_name, nick, blurb)                 \
     case PROP_##name:                                                 \
       properties->name = g_value_get_int (value);                     \
-    break;
+      if (!properties->rand_name)                                     \
+        properties->rand_name = gegl_random_new_with_seed (properties->name);\
+      else                                                            \
+        gegl_random_set_seed (properties->rand_name, properties->name);\
+      break;
 #define gegl_chant_path(name, nick, blurb)                            \
     case PROP_##name:                                                 \
       if (properties->name != NULL)                                   \
@@ -781,7 +786,12 @@ static void gegl_chant_destroy_notify (gpointer data)
       g_object_unref (properties->name);            \
       properties->name = NULL;                      \
     }
-#define gegl_chant_seed(name, nick, blurb)
+#define gegl_chant_seed(name, rand_name, nick, blurb)\
+  if (properties->rand_name)                         \
+    {                                                \
+      gegl_random_free (properties->rand_name);      \
+      properties->rand_name = NULL;                  \
+    }
 #define gegl_chant_path(name, nick, blurb)          \
   if (properties->name)                             \
     {                                               \
@@ -840,7 +850,9 @@ gegl_chant_constructor (GType                  type,
 #define gegl_chant_color(name, nick, def, blurb)              \
     if (properties->name == NULL) \
     {properties->name = gegl_color_new(def?def:"black");}
-#define gegl_chant_seed(name, nick, blurb)
+#define gegl_chant_seed(name, rand_name, nick, blurb)         \
+    if (properties->rand_name == NULL)                        \
+      {properties->rand_name = gegl_random_new_with_seed (0);}
 #define gegl_chant_path(name, nick, blurb)
 #define gegl_chant_curve(name, nick, blurb)
 
@@ -981,7 +993,7 @@ gegl_chant_class_intern_init (gpointer klass)
                                                           G_PARAM_READWRITE |\
                                                           G_PARAM_CONSTRUCT | \
                                                           GEGL_PARAM_PAD_INPUT)));
-#define gegl_chant_seed(name, nick, blurb)                                   \
+#define gegl_chant_seed(name, rand_name, nick, blurb)                        \
   g_object_class_install_property (object_class, PROP_##name,                \
                                    gegl_param_spec_seed (#name, nick, blurb, \
                                                      (GParamFlags) (         \
diff --git a/gegl/gegl-init.c b/gegl/gegl-init.c
index 2fd5275..9c3723b 100644
--- a/gegl/gegl-init.c
+++ b/gegl/gegl-init.c
@@ -103,6 +103,7 @@ guint gegl_debug_flags = 0;
 #include "buffer/gegl-tile-backend-file.h"
 #include "gegl-config.h"
 #include "graph/gegl-node.h"
+#include "gegl-random-priv.h"
 
 static const gchar *makefile (void);
 
@@ -450,6 +451,7 @@ gegl_exit (void)
   gegl_tile_cache_destroy ();
   gegl_operation_gtype_cleanup ();
   gegl_extension_handler_cleanup ();
+  gegl_random_cleanup ();
 
   if (module_db != NULL)
     {
diff --git a/gegl/gegl-random-priv.h b/gegl/gegl-random-priv.h
index c5e2391..0442dd9 100644
--- a/gegl/gegl-random-priv.h
+++ b/gegl/gegl-random-priv.h
@@ -19,10 +19,19 @@
 #ifndef __GEGL_RANDOM_PRIV_H__
 #define __GEGL_RANDOM_PRIV_H__
 
-#define PRIMES_SIZE       533
-#define RANDOM_DATA_SIZE (15083+15091+15101)
+#define RANDOM_DATA_SIZE (15101 * 3)
+
+struct _GeglRandom
+{
+  guint16 prime0;
+  guint16 prime1;
+  guint16 prime2;
+};
+
+guint32*
+gegl_random_get_data (void);
 
 void
-gegl_random_init (void);
+gegl_random_cleanup (void);
 
 #endif /* __GEGL_RANDOM_PRIV_H__ */
diff --git a/gegl/gegl-random.c b/gegl/gegl-random.c
index 52a4135..a81f97a 100644
--- a/gegl/gegl-random.c
+++ b/gegl/gegl-random.c
@@ -14,6 +14,7 @@
  * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
  *
  * Copyright 2012, 2013 Øyvind Kolås
+ * Copyright 2013       Téo Mazars <teomazars gmail com>
  */
 
 /* This file provides random access - reproducable random numbers in three
@@ -24,25 +25,24 @@
  * it is there in the API to provide for mip-map behavior later.
  *
  * The way it works is by xoring three lookup tables that are iterated
- * cyclically, each LUT has a prime number as a size, thus the combination
- * of the three values xored will have a period of prime1 * prime2 * prime3,
- * with the primes used this yields roughly 3TB of random, non-repeating
- * data from ~300kb of lookup data.
+ * cyclically, each LUT has a different prime number as a size, thus
+ * the combination of the three values xored will have a period of
+ * prime1 * prime2 * prime3, with the primes used this yields more than
+ * 1TB of random, non-repeating data from ~180kb of lookup data.
  *
  * The data for the LUTs is shared between different random seeds, it
- * is just the sizes of the LUTs that change, currently with 468 primes
- * there is about 101847096 different seeds achivable (with 45 primes
- * only 83160 combinations are possible (maybe this would have been enough
- * though)
+ * is just the sizes of the LUTs that change, currently with 533 primes
+ * there is about 533 * 532 * 531 different seeds achivable.
  */
 
 #include <glib.h>
 #include <gegl.h>
+#include "gegl-random.h"
 #include "gegl-random-priv.h"
 
 /* a set of reasonably large primes to choose from for array sizes
  */
-long gegl_random_primes[PRIMES_SIZE]={
+guint16 gegl_random_primes[533]={
 10007,10009,10037,10039,10061,10067,10069,10079,10091,10093,10099,10103,10111,
 10133,10139,10141,10151,10159,10163,10169,10177,10181,10193,10211,10223,10243,
 10247,10253,10259,10267,10271,10273,10289,10301,10303,10313,10321,10331,10333,
@@ -87,119 +87,191 @@ long gegl_random_primes[PRIMES_SIZE]={
 };
 
 /* these primes should not exist in the above set */
-#define XPRIME     103423
-#define YPRIME     101359
-#define NPRIME     101111
-#define MAX_TABLES 3
+#define XPRIME 103423LL
+#define YPRIME 101359LL
+#define NPRIME 101111LL
 
-gint32          gegl_random_data[RANDOM_DATA_SIZE];
-static gboolean random_data_inited = FALSE;
+#define SQR(x) ((x)*(x))
 
-void
+static guint32  *gegl_random_data;
+static gboolean  random_data_inited = FALSE;
+
+static void
 gegl_random_init (void)
 {
-  if (G_LIKELY (random_data_inited))
+  if (random_data_inited)
     return;
+  else
+    {
+      GRand *gr = g_rand_new_with_seed (42);
+      gint   i;
+
+      /* Ensure alignment, needed with the use of CL_MEM_USE_HOST_PTR */
+      gegl_random_data = gegl_malloc (RANDOM_DATA_SIZE * sizeof (guint32));
 
-  {
-    GRand *gr = g_rand_new_with_seed (42);
-    int i;
-    for (i = 0; i < RANDOM_DATA_SIZE; i++)
-      gegl_random_data[i] = g_rand_int (gr);
-    g_rand_free (gr);
-    random_data_inited = TRUE;
-  }
+      for (i = 0; i < RANDOM_DATA_SIZE; i++)
+        gegl_random_data[i] = g_rand_int (gr);
+
+      g_rand_free (gr);
+      random_data_inited = TRUE;
+    }
 }
 
+void
+gegl_random_cleanup (void)
+{
+  if (random_data_inited)
+    {
+      gegl_free (gegl_random_data);
+      gegl_random_data = NULL;
+      random_data_inited = FALSE;
+    }
+}
 
-static inline guint32
-_gegl_random_int (int seed,
-                 int x,
-                 int y,
-                 int z,
-                 int n)
+guint32*
+gegl_random_get_data (void)
 {
-  unsigned long idx = x * XPRIME + 
-                      y * YPRIME * XPRIME + 
-                      n * NPRIME * YPRIME * XPRIME;
-#define ROUNDS 3
-    /* 3 rounds gives a reasonably high cycle for */
-                         /*   our synthesized larger random set. */
-  long * prime = &gegl_random_primes[seed % (G_N_ELEMENTS (gegl_random_primes)
-                                     - 1 - ROUNDS)];
   gegl_random_init ();
-#define UNROLLED
-
-#ifdef UNROLLED
-
-  {
-    int prime0 = prime[0],
-        prime1 = prime[1],
-        prime2 = prime[2];
-    return
-    gegl_random_data[idx % prime0] ^
-    gegl_random_data[prime0 + (idx % (prime1))] ^
-    gegl_random_data[prime0 + prime1 + (idx % (prime2))];
-  }
-#else
-  {
-    gint32 ret = 0;
-    int i;
-    int offset = 0;
-
-    for (i = 0; i < ROUNDS; i++) 
-      ret ^= gegl_random_data[offset + (idx % (prime[i]))];
-      offset += prime[i];
-
-
-    return ret;
-  }
-#endif
+  return gegl_random_data;
+}
+
+GeglRandom*
+gegl_random_new (void)
+{
+  guint seed = (guint) g_random_int();
+
+  return gegl_random_new_with_seed (seed);
+}
+
+GeglRandom*
+gegl_random_new_with_seed (guint32 seed)
+{
+  GeglRandom *rand = g_new (GeglRandom, 1);
+
+  gegl_random_set_seed (rand, seed);
+
+  return rand;
+}
+
+void
+gegl_random_free (GeglRandom *rand)
+{
+  g_free (rand);
+}
+
+void
+gegl_random_set_seed (GeglRandom *rand,
+                      guint32     seed)
+{
+  guint number_elem = G_N_ELEMENTS (gegl_random_primes);
+  guint id0, id1, id2;
+
+  /* XXX: Probably needs to be done at gegl-init */
+  gegl_random_init ();
+
+  /* gives roughly number_elem^3 different sets */
+  id0 =  seed % number_elem;
+  id1 = (seed / number_elem) % number_elem;
+  id2 = (seed / SQR (number_elem)) % number_elem;
+
+  /* Shuffle a bit to avoid to hit edge cases near 0 */
+  id0  = (id0 + 42)  % number_elem;
+  id1  = (id1 + 212) % number_elem;
+  id2  = (id2 + 17)  % number_elem;
+
+  /* all primes numbers must be distincts */
+  while (id0 == id1 || id0 == id2)
+    id0 = (id0 + 1) % number_elem;
+
+  while (id1 == id0 || id1 == id2)
+    id1 = (id1 + 1) % number_elem;
+
+  rand->prime0 = gegl_random_primes[id0];
+  rand->prime1 = gegl_random_primes[id1];
+  rand->prime2 = gegl_random_primes[id2];
+}
+
+GeglRandom*
+gegl_random_duplicate (GeglRandom *gegl_random)
+{
+  GeglRandom *result = g_new (GeglRandom, 1);
+
+  *result = *gegl_random;
+
+  return result;
+}
+
+GType
+gegl_random_get_type (void)
+{
+  static GType our_type = 0;
+
+  if (our_type == 0)
+    our_type = g_boxed_type_register_static (g_intern_static_string ("GeglRandom"),
+                                             (GBoxedCopyFunc) gegl_random_duplicate,
+                                             (GBoxedFreeFunc) g_free);
+  return our_type;
+}
+
+static inline guint32
+_gegl_random_int (const GeglRandom *rand,
+                  gint              x,
+                  gint              y,
+                  gint              z,
+                  gint              n)
+{
+  guint64 idx = x * XPRIME +
+                y * YPRIME * XPRIME +
+                n * NPRIME * YPRIME * XPRIME;
+  return
+    gegl_random_data[idx % rand->prime0] ^
+    gegl_random_data[rand->prime0 + (idx % (rand->prime1))] ^
+    gegl_random_data[rand->prime0 + rand->prime1 + (idx % (rand->prime2))];
 }
 
 guint32
-gegl_random_int (int seed,
-                 int x,
-                 int y,
-                 int z,
-                 int n)
+gegl_random_int (const GeglRandom *rand,
+                 gint              x,
+                 gint              y,
+                 gint              z,
+                 gint              n)
 {
-  return _gegl_random_int (seed, x, y, z, n);
+  return _gegl_random_int (rand, x, y, z, n);
 }
 
 gint32
-gegl_random_int_range (int seed,
-                       int x,
-                       int y,
-                       int z,
-                       int n,
-                       int min,
-                       int max)
+gegl_random_int_range (const GeglRandom *rand,
+                       gint              x,
+                       gint              y,
+                       gint              z,
+                       gint              n,
+                       gint              min,
+                       gint              max)
 {
-  guint32 ret = _gegl_random_int (seed, x, y, z, n);
-  return (ret % (max-min)) + min;
+  guint32 ret = _gegl_random_int (rand, x, y, z, n);
+  return (ret % (max - min)) + min;
 }
 
 #define G_RAND_FLOAT_TRANSFORM  0.00001525902189669642175
 
-float
-gegl_random_float (int seed,
-                   int x,
-                   int y,
-                   int z,
-                   int n)
+gfloat
+gegl_random_float (const GeglRandom *rand,
+                   gint              x,
+                   gint              y,
+                   gint              z,
+                   gint              n)
 {
-  return (_gegl_random_int (seed, x, y, z, n) & 0xffff) * G_RAND_FLOAT_TRANSFORM;
+  return (_gegl_random_int (rand, x, y, z, n) & 0xffff) * G_RAND_FLOAT_TRANSFORM;
 }
 
-float
-gegl_random_float_range (int seed,
-                         int x,
-                         int y,
-                         int z,
-                         int n,
-                         float min,
-                         float max)
+gfloat
+gegl_random_float_range (const GeglRandom *rand,
+                         gint              x,
+                         gint              y,
+                         gint              z,
+                         gint              n,
+                         gfloat            min,
+                         gfloat            max)
 {
-  return gegl_random_float (seed, x, y, z, n) * (max - min) + min;
+  return gegl_random_float (rand, x, y, z, n) * (max - min) + min;
 }
diff --git a/gegl/gegl-random.h b/gegl/gegl-random.h
new file mode 100644
index 0000000..d7f3dfc
--- /dev/null
+++ b/gegl/gegl-random.h
@@ -0,0 +1,131 @@
+/* This file is part of GEGL
+ *
+ * GEGL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright 2006 Øyvind Kolås
+ * Copyright 2013 Téo Mazars <teomazars gmail com>
+ */
+
+#ifndef __GEGL_RANDOM_H__
+#define __GEGL_RANDOM_H__
+
+#include "gegl-types.h"
+
+G_BEGIN_DECLS
+
+/**
+ * gegl_random_new_with_seed:
+ * @seed: an integer seed, change for different permutation.
+ *
+ * Return an opaque structure associated to the seed.
+ * This structure needs to be freed by the user with gegl_random_free();
+ */
+GeglRandom* gegl_random_new_with_seed (guint32 seed);
+
+/**
+ * gegl_random_new:
+ *
+ * Creates a new random number generator initialized with a random seed.
+ * This structure needs to be freed by the user with gegl_random_free();
+ */
+GeglRandom* gegl_random_new (void);
+
+/**
+ * gegl_random_duplicate:
+ * @rand: The GeglRandom to duplicate
+ *
+ * Return a new copy of an existing GeglRandom
+ */
+GeglRandom* gegl_random_duplicate (GeglRandom *rand);
+
+/**
+ * gegl_random_free:
+ * @rand: The GeglRandom structure to free
+ *
+ * Free a GeglRandom structure created with gegl_random_new() or gegl_random_new_with_seed()
+ */
+void gegl_random_free (GeglRandom *rand);
+
+/**
+ * gegl_random_set_seed:
+ * @rand: The GeglRandom to set
+ * @seed: an integer seed, change for different permutation.
+ *
+ * Change the seed of an existing GeglRandom.
+ */
+void gegl_random_set_seed (GeglRandom *rand, guint32 seed);
+
+/**
+ * gegl_random_float_range:
+ * @rand: a GeglRandom
+ * @x: x coordinate
+ * @y: y coordinate
+ * @z: z coordinate (mipmap level)
+ * @n: number no (each x,y coordinate provides its own sequence of
+ * numbers
+ * @min: minimum value
+ * @max: maxmimum value
+ *
+ * Return a random floating point number in the range specified,
+ * for the given x,y coordinates and GeglRandom provided, if multiple different
+ * numbers are needed pass in incrementing n's.
+ */
+gfloat gegl_random_float_range (const GeglRandom *rand, gint x, gint y, gint z, gint n, gfloat min, gfloat 
max);
+
+/**
+ * gegl_random_int_range:
+ * @rand: a GeglRandom
+ * @x: x coordinate
+ * @y: y coordinate
+ * @z: z coordinate (mipmap level)
+ * @n: number no (each x,y coordinate provides its own sequence of
+ * numbers
+ * @min: minimum value
+ * @max: maxmimum value+1
+ *
+ * Return a random integer point number in the range specified,
+ * for the given x,y coordinates and GeglRandom provided, if multiple different
+ * numbers are needed pass in incrementing n's.
+ */
+gint32 gegl_random_int_range (const GeglRandom *rand, gint x, gint y, gint z, gint n, gint min, gint max);
+
+/**
+ * gegl_random_int:
+ * @rand: a GeglRandom
+ * @x: x coordinate
+ * @y: y coordinate
+ * @z: z coordinate (mipmap level)
+ * @n: number no (each x,y coordinate provides its own sequence of
+ * numbers
+ *
+ * Return a random integer number in range 0 .. MAX_UINT
+ */
+guint32 gegl_random_int (const GeglRandom *rand, gint x, gint y, gint z, gint n);
+
+/**
+ * gegl_random_float:
+ * @rand: a GeglRandom
+ * @x: x coordinate
+ * @y: y coordinate
+ * @z: z coordinate (mipmap level)
+ * @n: number no (each x,y coordinate provides its own sequence of
+ * numbers
+ *
+ * Return a random floating point number in range 0.0 .. 1.0.
+ */
+gfloat gegl_random_float (const GeglRandom *rand, gint x, gint y, gint z, gint n);
+
+G_END_DECLS
+
+#endif /* __GEGL_RANDOM_H__ */
diff --git a/gegl/gegl-types.h b/gegl/gegl-types.h
index 58fdde6..aa87ea4 100644
--- a/gegl/gegl-types.h
+++ b/gegl/gegl-types.h
@@ -77,6 +77,10 @@ GType gegl_processor_get_type  (void) G_GNUC_CONST;
 #define GEGL_PROCESSOR(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEGL_TYPE_PROCESSOR, GeglProcessor))
 #define GEGL_IS_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_PROCESSOR))
 
+typedef struct _GeglRandom  GeglRandom;
+GType gegl_random_get_type  (void) G_GNUC_CONST;
+#define GEGL_TYPE_RANDOM    (gegl_random_get_type())
+
 G_END_DECLS
 
 #endif /* __GEGL_TYPES_H__ */
diff --git a/gegl/gegl.h b/gegl/gegl.h
index b5421ad..af36f25 100644
--- a/gegl/gegl.h
+++ b/gegl/gegl.h
@@ -31,6 +31,7 @@
 #include <gegl-matrix.h>
 #include <gegl-utils.h>
 #include <gegl-version.h>
+#include <gegl-random.h>
 
 
 /***
@@ -995,66 +996,6 @@ GeglNode *gegl_node (const gchar *op_type,
  */
 GeglNode *gegl_graph (GeglNode *node);
 
-/**
- * gegl_random_float_range:
- * @seed: an integer seed, change for different permutation
- * @x: x coordinate
- * @y: y coordinate
- * @z: z coordinate (mipmap level)
- * @n: number no (each x,y coordinate provides its own sequence of
- * numbers
- * @min: minimum value
- * @max: maxmimum value
- *
- * Return a random floating point number in the range specified,
- * for the given x,y coordinates and seed provided, if multiple different
- * numbers are needed pass in incrementing n's.
- */
-float gegl_random_float_range (int seed, int x, int y, int z, int n, float min, float max);
-
-
-/**
- * gegl_random_int_range:
- * @seed: an integer seed, change for different permutation
- * @x: x coordinate
- * @y: y coordinate
- * @z: z coordinate (mipmap level)
- * @n: number no (each x,y coordinate provides its own sequence of
- * numbers
- * @min: minimum value
- * @max: maxmimum value+1
- *
- * Return a random integer point number in the range specified,
- * for the given x,y coordinates and seed provided, if multiple different
- * numbers are needed pass in incrementing n's.
- */
-gint32 gegl_random_int_range    (int seed, int x, int y, int z, int n, int min, int max);
-
-/**
- * gegl_random_int:
- * @seed: an integer seed, change for different permutation
- * @x: x coordinate
- * @y: y coordinate
- * @z: z coordinate (mipmap level)
- * @n: number no (each x,y coordinate provides its own sequence of
- * numbers
- *
- * Return a random integer number in range 0 .. MAX_UINT
- */
-guint32 gegl_random_int         (int seed, int x, int y, int z, int n);
-
-/**
- * gegl_random_float:
- * @seed: an integer seed, change for different permutation
- * @x: x coordinate
- * @y: y coordinate
- * @z: z coordinate (mipmap level)
- * @n: number no (each x,y coordinate provides its own sequence of
- * numbers
- *
- * Return a random floating point number in range 0.0 .. 1.0.
- */
-float  gegl_random_float        (int seed, int x, int y, int z, int n);
 
 #define GEGL_ALIGNED __restrict__ __attribute__((__aligned__ (16)))
 
diff --git a/gegl/opencl/gegl-cl-random.c b/gegl/opencl/gegl-cl-random.c
index 4724cd5..46e88a0 100644
--- a/gegl/opencl/gegl-cl-random.c
+++ b/gegl/opencl/gegl-cl-random.c
@@ -21,33 +21,27 @@
 #include "opencl/gegl-cl.h"
 #include "gegl-random-priv.h"
 
-/*XXX: defined in gegl-random.c*/
-
-extern gint32 *gegl_random_data;
-extern long   *gegl_random_primes;
-
 cl_mem
 gegl_cl_load_random_data (gint *cl_err)
 {
-  cl_mem cl_random_data;
-  gegl_random_init ();
+  cl_mem   cl_random_data;
+  guint32 *random_data;
+
+  random_data = gegl_random_get_data ();
   cl_random_data = gegl_clCreateBuffer (gegl_cl_get_context (),
                                         CL_MEM_USE_HOST_PTR | CL_MEM_READ_ONLY,
-                                        RANDOM_DATA_SIZE * sizeof (gint32),
-                                        (void*) &gegl_random_data,
+                                        RANDOM_DATA_SIZE * sizeof (guint32),
+                                        (void*) random_data,
                                         cl_err);
   return cl_random_data;
 }
 
-cl_mem
-gegl_cl_load_random_primes (gint *cl_err)
+void
+gegl_cl_random_get_ushort4 (const GeglRandom *in_rand,
+                                  cl_ushort4 *out_rand)
 {
-  cl_mem cl_random_primes;
-  cl_random_primes = gegl_clCreateBuffer (gegl_cl_get_context (),
-                                          CL_MEM_USE_HOST_PTR | CL_MEM_READ_ONLY,
-                                          PRIMES_SIZE * sizeof (long),
-                                          (void*) &gegl_random_primes,
-                                          cl_err);
-  return cl_random_primes;
+  out_rand->x = in_rand->prime0;
+  out_rand->y = in_rand->prime1;
+  out_rand->z = in_rand->prime2;
+  out_rand->w = 0;
 }
-
diff --git a/gegl/opencl/gegl-cl-random.h b/gegl/opencl/gegl-cl-random.h
index 186827d..33b7bda 100644
--- a/gegl/opencl/gegl-cl-random.h
+++ b/gegl/opencl/gegl-cl-random.h
@@ -20,10 +20,11 @@
 #define __GEGL_CL_RANDOM_H__
 
 #include "gegl-cl-types.h"
+#include "gegl-types.h"
 /** Load the random data needed to generate random numbers in the GPU*/
 cl_mem gegl_cl_load_random_data (int *cl_err);
 
-/** Load the primes needed to generate random numbers in the GPU*/
-cl_mem gegl_cl_load_random_primes (int *cl_err);
+void
+gegl_cl_random_get_ushort4 (const GeglRandom *in_rand, cl_ushort4 *out_rand);
 
 #endif
diff --git a/opencl/noise-hurl.cl b/opencl/noise-hurl.cl
index 6cc0412..ccb44be 100644
--- a/opencl/noise-hurl.cl
+++ b/opencl/noise-hurl.cl
@@ -16,16 +16,15 @@
  * Copyright 2013 Carlos Zubieta <czubieta dev gmail com>
  */
 
-__kernel void cl_noise_hurl(__global       float4 *src,
-                            __global const int    *random_data,
-                            __global const long   *random_primes,
-                                           int     x_offset,
-                                           int     y_offset,
-                                           int     roi_width,
-                                           int     whole_region_width,
-                                           int     seed,
-                                           float   pct_random,
-                                           int     offset)
+__kernel void cl_noise_hurl(__global       float4    *src,
+                            __global const int       *random_data,
+                                           int        x_offset,
+                                           int        y_offset,
+                                           int        roi_width,
+                                           int        whole_region_width,
+                                           GeglRandom rand,
+                                           float      pct_random,
+                                           int        offset)
 {
   int gid  = get_global_id(0);
   int gidy = gid / roi_width;
@@ -37,14 +36,14 @@ __kernel void cl_noise_hurl(__global       float4 *src,
 
   float4 src_v = src[gid];
 
-  float pc          = gegl_cl_random_float_range (random_data, random_primes,
-                                                  seed, x, y, 0, n, 0, 100);
-  float red_noise   = gegl_cl_random_float (random_data, random_primes,
-                                            seed, x, y, 0, n+1);
-  float green_noise = gegl_cl_random_float (random_data, random_primes,
-                                            seed, x, y, 0, n+2);
-  float blue_noise  = gegl_cl_random_float (random_data, random_primes,
-                                            seed, x, y, 0, n+3);
+  float pc          = gegl_cl_random_float_range (random_data,
+                                                  rand, x, y, 0, n, 0, 100);
+  float red_noise   = gegl_cl_random_float (random_data,
+                                            rand, x, y, 0, n+1);
+  float green_noise = gegl_cl_random_float (random_data,
+                                            rand, x, y, 0, n+2);
+  float blue_noise  = gegl_cl_random_float (random_data,
+                                            rand, x, y, 0, n+3);
 
   if(pc <= pct_random)
     {
diff --git a/opencl/noise-hurl.cl.h b/opencl/noise-hurl.cl.h
index 9cc9f78..b57b32b 100644
--- a/opencl/noise-hurl.cl.h
+++ b/opencl/noise-hurl.cl.h
@@ -17,16 +17,15 @@ static const char* noise_hurl_cl_source =
 " * Copyright 2013 Carlos Zubieta <czubieta dev gmail com>                     \n"
 " */                                                                           \n"
 "                                                                              \n"
-"__kernel void cl_noise_hurl(__global       float4 *src,                       \n"
-"                            __global const int    *random_data,               \n"
-"                            __global const long   *random_primes,             \n"
-"                                           int     x_offset,                  \n"
-"                                           int     y_offset,                  \n"
-"                                           int     roi_width,                 \n"
-"                                           int     whole_region_width,        \n"
-"                                           int     seed,                      \n"
-"                                           float   pct_random,                \n"
-"                                           int     offset)                    \n"
+"__kernel void cl_noise_hurl(__global       float4    *src,                    \n"
+"                            __global const int       *random_data,            \n"
+"                                           int        x_offset,               \n"
+"                                           int        y_offset,               \n"
+"                                           int        roi_width,              \n"
+"                                           int        whole_region_width,     \n"
+"                                           GeglRandom rand,                   \n"
+"                                           float      pct_random,             \n"
+"                                           int        offset)                 \n"
 "{                                                                             \n"
 "  int gid  = get_global_id(0);                                                \n"
 "  int gidy = gid / roi_width;                                                 \n"
@@ -38,14 +37,14 @@ static const char* noise_hurl_cl_source =
 "                                                                              \n"
 "  float4 src_v = src[gid];                                                    \n"
 "                                                                              \n"
-"  float pc          = gegl_cl_random_float_range (random_data, random_primes, \n"
-"                                                  seed, x, y, 0, n, 0, 100);  \n"
-"  float red_noise   = gegl_cl_random_float (random_data, random_primes,       \n"
-"                                            seed, x, y, 0, n+1);              \n"
-"  float green_noise = gegl_cl_random_float (random_data, random_primes,       \n"
-"                                            seed, x, y, 0, n+2);              \n"
-"  float blue_noise  = gegl_cl_random_float (random_data, random_primes,       \n"
-"                                            seed, x, y, 0, n+3);              \n"
+"  float pc          = gegl_cl_random_float_range (random_data,                \n"
+"                                                  rand, x, y, 0, n, 0, 100);  \n"
+"  float red_noise   = gegl_cl_random_float (random_data,                      \n"
+"                                            rand, x, y, 0, n+1);              \n"
+"  float green_noise = gegl_cl_random_float (random_data,                      \n"
+"                                            rand, x, y, 0, n+2);              \n"
+"  float blue_noise  = gegl_cl_random_float (random_data,                      \n"
+"                                            rand, x, y, 0, n+3);              \n"
 "                                                                              \n"
 "  if(pc <= pct_random)                                                        \n"
 "    {                                                                         \n"
diff --git a/opencl/random.cl b/opencl/random.cl
index e6e3340..b900b37 100644
--- a/opencl/random.cl
+++ b/opencl/random.cl
@@ -17,77 +17,85 @@
  */
 
 /* XXX: this file should be kept in sync with gegl-random. */
-#define XPRIME     103423
-#define YPRIME     101359
-#define NPRIME     101111
+__constant const long XPRIME = 103423;
+__constant const long YPRIME = 101359;
+__constant const long NPRIME = 101111;
 
-#define RANDOM_DATA_SIZE (15083+15091+15101)
-#define PRIME_SIZE 533u
+#define RANDOM_DATA_SIZE (15101 * 3)
 
-inline uint _gegl_cl_random_int  (__global const int  *cl_random_data,
-                                  __global const long *cl_random_primes,
-                                  int seed, int x, int y, int z, int n);
+typedef ushort4 GeglRandom;
 
-uint gegl_cl_random_int          (__global const int  *cl_random_data,
-                                  __global const long *cl_random_primes,
-                                  int seed, int x, int y, int z, int n);
+unsigned int _gegl_cl_random_int (__global const int *cl_random_data,
+                                  const GeglRandom  rand,
+                                  int x,
+                                  int y,
+                                  int z,
+                                  int n);
+
+unsigned int gegl_cl_random_int  (__global const int *cl_random_data,
+                                  const GeglRandom  rand,
+                                  int x,
+                                  int y,
+                                  int z,
+                                  int n);
 
 int gegl_cl_random_int_range     (__global const int  *cl_random_data,
-                                  __global const long *cl_random_primes,
-                                  int seed, int x, int y, int z, int n,
-                                  int min, int max);
+                                  const GeglRandom  rand,
+                                  int x,
+                                  int y,
+                                  int z,
+                                  int n,
+                                  int min,
+                                  int max);
 
 float gegl_cl_random_float       (__global const int  *cl_random_data,
-                                  __global const long *cl_random_primes,
-                                  int seed, int x, int y, int z, int n);
+                                  const GeglRandom  rand,
+                                  int x,
+                                  int y,
+                                  int z,
+                                  int n);
 
 float gegl_cl_random_float_range (__global const int  *cl_random_data,
-                                  __global const long *cl_random_primes,
-                                  int seed, int x, int y, int z, int n,
-                                  float min, float max);
+                                  const GeglRandom  rand,
+                                  int x,
+                                  int y,
+                                  int z,
+                                  int n,
+                                  float min,
+                                  float max);
 
-inline uint
+unsigned int
 _gegl_cl_random_int (__global const int  *cl_random_data,
-                     __global const long *cl_random_primes,
-                     int                 seed,
+                     const GeglRandom    rand,
                      int                 x,
                      int                 y,
                      int                 z,
                      int                 n)
 {
-  unsigned long idx = x * XPRIME + 
-                      y * YPRIME * XPRIME + 
+  unsigned long idx = x * XPRIME +
+                      y * YPRIME * XPRIME +
                       n * NPRIME * YPRIME * XPRIME;
-#define ROUNDS 3
-    /* 3 rounds gives a reasonably high cycle for */
-    /*   our synthesized larger random set. */
-  unsigned long seed_idx = seed % (PRIME_SIZE - 1 - ROUNDS);
-  int prime0 = cl_random_primes[seed_idx],
-      prime1 = cl_random_primes[seed_idx+1],
-      prime2 = cl_random_primes[seed_idx+2];
-  int r0 = cl_random_data[idx % prime0],
-      r1 = cl_random_data[prime0 + (idx % (prime1))],
-      r2 = cl_random_data[prime0 + prime1 + (idx % (prime2))];
+
+  int r0 = cl_random_data[idx % rand.x],
+      r1 = cl_random_data[rand.x + (idx % rand.y)],
+      r2 = cl_random_data[rand.x + rand.y + (idx % rand.z)];
   return r0 ^ r1 ^ r2;
 }
 
-uint
-gegl_cl_random_int (__global const int  *cl_random_data,
-                    __global const long *cl_random_primes,
-                    int                 seed,
+unsigned int
+gegl_cl_random_int (__global const int *cl_random_data,
+                    const GeglRandom    rand,
                     int                 x,
                     int                 y,
                     int                 z,
                     int                 n)
 {
-  return _gegl_cl_random_int (cl_random_data, cl_random_primes,
-                              seed, x, y, z, n);
+  return _gegl_cl_random_int (cl_random_data, rand, x, y, z, n);
 }
 
 int
 gegl_cl_random_int_range (__global const int  *cl_random_data,
-                          __global const long *cl_random_primes,
-                          int                 seed,
+                          const GeglRandom    rand,
                           int                 x,
                           int                 y,
                           int                 z,
@@ -95,8 +103,7 @@ gegl_cl_random_int_range (__global const int  *cl_random_data,
                           int                 min,
                           int                 max)
 {
-  uint ret = _gegl_cl_random_int (cl_random_data, cl_random_primes,
-                                  seed, x, y, z, n);
+  int ret = _gegl_cl_random_int (cl_random_data, rand, x, y, z, n);
   return (ret % (max-min)) + min;
 }
 
@@ -104,23 +111,20 @@ gegl_cl_random_int_range (__global const int  *cl_random_data,
 #define G_RAND_FLOAT_TRANSFORM  0.00001525902189669642175f
 
 float
-gegl_cl_random_float (__global const int  *cl_random_data,
-                      __global const long *cl_random_primes,
-                      int                 seed,
+gegl_cl_random_float (__global const int *cl_random_data,
+                      const GeglRandom    rand,
                       int                 x,
                       int                 y,
                       int                 z,
                       int                 n)
 {
-  uint u = _gegl_cl_random_int (cl_random_data, cl_random_primes,
-                                seed, x, y, z, n);
+  int u = _gegl_cl_random_int (cl_random_data, rand, x, y, z, n);
   return (u & 0xffff) * G_RAND_FLOAT_TRANSFORM;
 }
 
 float
-gegl_cl_random_float_range (__global const int  *cl_random_data,
-                            __global const long *cl_random_primes,
-                            int                 seed,
+gegl_cl_random_float_range (__global const int *cl_random_data,
+                            const GeglRandom    rand,
                             int                 x,
                             int                 y,
                             int                 z,
@@ -128,7 +132,6 @@ gegl_cl_random_float_range (__global const int  *cl_random_data,
                             float               min,
                             float               max)
 {
-  float f = gegl_cl_random_float (cl_random_data, cl_random_primes,
-                                  seed, x, y, z, n);
+  float f = gegl_cl_random_float (cl_random_data, rand, x, y, z, n);
   return f * (max - min) + min;
 }
diff --git a/opencl/random.cl.h b/opencl/random.cl.h
index 6b78951..d48e087 100644
--- a/opencl/random.cl.h
+++ b/opencl/random.cl.h
@@ -18,39 +18,56 @@ static const char* random_cl_source =
 " */                                                                           \n"
 "                                                                              \n"
 "/* XXX: this file should be kept in sync with gegl-random. */                 \n"
-"#define XPRIME     103423                                                     \n"
-"#define YPRIME     101359                                                     \n"
-"#define NPRIME     101111                                                     \n"
+"__constant const long XPRIME = 103423;                                        \n"
+"__constant const long YPRIME = 101359;                                        \n"
+"__constant const long NPRIME = 101111;                                        \n"
 "                                                                              \n"
-"#define RANDOM_DATA_SIZE (15083+15091+15101)                                  \n"
-"#define PRIME_SIZE 533u                                                       \n"
+"#define RANDOM_DATA_SIZE (15101 * 3)                                          \n"
 "                                                                              \n"
-"inline uint _gegl_cl_random_int  (__global const int  *cl_random_data,        \n"
-"                                  __global const long *cl_random_primes,      \n"
-"                                  int seed, int x, int y, int z, int n);      \n"
+"typedef ushort4 GeglRandom;                                                   \n"
 "                                                                              \n"
-"uint gegl_cl_random_int          (__global const int  *cl_random_data,        \n"
-"                                  __global const long *cl_random_primes,      \n"
-"                                  int seed, int x, int y, int z, int n);      \n"
+"unsigned int _gegl_cl_random_int (__global const int *cl_random_data,         \n"
+"                                  const GeglRandom  rand,                     \n"
+"                                  int x,                                      \n"
+"                                  int y,                                      \n"
+"                                  int z,                                      \n"
+"                                  int n);                                     \n"
+"                                                                              \n"
+"unsigned int gegl_cl_random_int  (__global const int *cl_random_data,         \n"
+"                                  const GeglRandom  rand,                     \n"
+"                                  int x,                                      \n"
+"                                  int y,                                      \n"
+"                                  int z,                                      \n"
+"                                  int n);                                     \n"
 "                                                                              \n"
 "int gegl_cl_random_int_range     (__global const int  *cl_random_data,        \n"
-"                                  __global const long *cl_random_primes,      \n"
-"                                  int seed, int x, int y, int z, int n,       \n"
-"                                  int min, int max);                          \n"
+"                                  const GeglRandom  rand,                     \n"
+"                                  int x,                                      \n"
+"                                  int y,                                      \n"
+"                                  int z,                                      \n"
+"                                  int n,                                      \n"
+"                                  int min,                                    \n"
+"                                  int max);                                   \n"
 "                                                                              \n"
 "float gegl_cl_random_float       (__global const int  *cl_random_data,        \n"
-"                                  __global const long *cl_random_primes,      \n"
-"                                  int seed, int x, int y, int z, int n);      \n"
+"                                  const GeglRandom  rand,                     \n"
+"                                  int x,                                      \n"
+"                                  int y,                                      \n"
+"                                  int z,                                      \n"
+"                                  int n);                                     \n"
 "                                                                              \n"
 "float gegl_cl_random_float_range (__global const int  *cl_random_data,        \n"
-"                                  __global const long *cl_random_primes,      \n"
-"                                  int seed, int x, int y, int z, int n,       \n"
-"                                  float min, float max);                      \n"
+"                                  const GeglRandom  rand,                     \n"
+"                                  int x,                                      \n"
+"                                  int y,                                      \n"
+"                                  int z,                                      \n"
+"                                  int n,                                      \n"
+"                                  float min,                                  \n"
+"                                  float max);                                 \n"
 "                                                                              \n"
-"inline uint                                                                   \n"
+"unsigned int                                                                  \n"
 "_gegl_cl_random_int (__global const int  *cl_random_data,                     \n"
-"                     __global const long *cl_random_primes,                   \n"
-"                     int                 seed,                                \n"
+"                     const GeglRandom    rand,                                \n"
 "                     int                 x,                                   \n"
 "                     int                 y,                                   \n"
 "                     int                 z,                                   \n"
@@ -59,36 +76,27 @@ static const char* random_cl_source =
 "  unsigned long idx = x * XPRIME +                                            \n"
 "                      y * YPRIME * XPRIME +                                   \n"
 "                      n * NPRIME * YPRIME * XPRIME;                           \n"
-"#define ROUNDS 3                                                              \n"
-"    /* 3 rounds gives a reasonably high cycle for */                          \n"
-"    /*   our synthesized larger random set. */                                \n"
-"  unsigned long seed_idx = seed % (PRIME_SIZE - 1 - ROUNDS);                  \n"
-"  int prime0 = cl_random_primes[seed_idx],                                    \n"
-"      prime1 = cl_random_primes[seed_idx+1],                                  \n"
-"      prime2 = cl_random_primes[seed_idx+2];                                  \n"
-"  int r0 = cl_random_data[idx % prime0],                                      \n"
-"      r1 = cl_random_data[prime0 + (idx % (prime1))],                         \n"
-"      r2 = cl_random_data[prime0 + prime1 + (idx % (prime2))];                \n"
+"                                                                              \n"
+"  int r0 = cl_random_data[idx % rand.x],                                      \n"
+"      r1 = cl_random_data[rand.x + (idx % rand.y)],                           \n"
+"      r2 = cl_random_data[rand.x + rand.y + (idx % rand.z)];                  \n"
 "  return r0 ^ r1 ^ r2;                                                        \n"
 "}                                                                             \n"
 "                                                                              \n"
-"uint                                                                          \n"
-"gegl_cl_random_int (__global const int  *cl_random_data,                      \n"
-"                    __global const long *cl_random_primes,                    \n"
-"                    int                 seed,                                 \n"
+"unsigned int                                                                  \n"
+"gegl_cl_random_int (__global const int *cl_random_data,                       \n"
+"                    const GeglRandom    rand,                                 \n"
 "                    int                 x,                                    \n"
 "                    int                 y,                                    \n"
 "                    int                 z,                                    \n"
 "                    int                 n)                                    \n"
 "{                                                                             \n"
-"  return _gegl_cl_random_int (cl_random_data, cl_random_primes,               \n"
-"                              seed, x, y, z, n);                              \n"
+"  return _gegl_cl_random_int (cl_random_data, rand, x, y, z, n);              \n"
 "}                                                                             \n"
 "                                                                              \n"
 "int                                                                           \n"
 "gegl_cl_random_int_range (__global const int  *cl_random_data,                \n"
-"                          __global const long *cl_random_primes,              \n"
-"                          int                 seed,                           \n"
+"                          const GeglRandom    rand,                           \n"
 "                          int                 x,                              \n"
 "                          int                 y,                              \n"
 "                          int                 z,                              \n"
@@ -96,8 +104,7 @@ static const char* random_cl_source =
 "                          int                 min,                            \n"
 "                          int                 max)                            \n"
 "{                                                                             \n"
-"  uint ret = _gegl_cl_random_int (cl_random_data, cl_random_primes,           \n"
-"                                  seed, x, y, z, n);                          \n"
+"  int ret = _gegl_cl_random_int (cl_random_data, rand, x, y, z, n);           \n"
 "  return (ret % (max-min)) + min;                                             \n"
 "}                                                                             \n"
 "                                                                              \n"
@@ -105,23 +112,20 @@ static const char* random_cl_source =
 "#define G_RAND_FLOAT_TRANSFORM  0.00001525902189669642175f                    \n"
 "                                                                              \n"
 "float                                                                         \n"
-"gegl_cl_random_float (__global const int  *cl_random_data,                    \n"
-"                      __global const long *cl_random_primes,                  \n"
-"                      int                 seed,                               \n"
+"gegl_cl_random_float (__global const int *cl_random_data,                     \n"
+"                      const GeglRandom    rand,                               \n"
 "                      int                 x,                                  \n"
 "                      int                 y,                                  \n"
 "                      int                 z,                                  \n"
 "                      int                 n)                                  \n"
 "{                                                                             \n"
-"  uint u = _gegl_cl_random_int (cl_random_data, cl_random_primes,             \n"
-"                                seed, x, y, z, n);                            \n"
+"  int u = _gegl_cl_random_int (cl_random_data, rand, x, y, z, n);             \n"
 "  return (u & 0xffff) * G_RAND_FLOAT_TRANSFORM;                               \n"
 "}                                                                             \n"
 "                                                                              \n"
 "float                                                                         \n"
-"gegl_cl_random_float_range (__global const int  *cl_random_data,              \n"
-"                            __global const long *cl_random_primes,            \n"
-"                            int                 seed,                         \n"
+"gegl_cl_random_float_range (__global const int *cl_random_data,               \n"
+"                            const GeglRandom    rand,                         \n"
 "                            int                 x,                            \n"
 "                            int                 y,                            \n"
 "                            int                 z,                            \n"
@@ -129,8 +133,7 @@ static const char* random_cl_source =
 "                            float               min,                          \n"
 "                            float               max)                          \n"
 "{                                                                             \n"
-"  float f = gegl_cl_random_float (cl_random_data, cl_random_primes,           \n"
-"                                  seed, x, y, z, n);                          \n"
+"  float f = gegl_cl_random_float (cl_random_data, rand, x, y, z, n);          \n"
 "  return f * (max - min) + min;                                               \n"
 "}                                                                             \n"
 ;
diff --git a/operations/common/cubism.c b/operations/common/cubism.c
index 6814907..e6c9a46 100644
--- a/operations/common/cubism.c
+++ b/operations/common/cubism.c
@@ -39,7 +39,7 @@ gegl_chant_color  (bg_color, _("Background Color"),
                    "rgba(0.0, 0.0, 0.0, 0.0)",
                    _("The tiles' background color"))
 
-gegl_chant_seed   (seed, _("Seed"),
+gegl_chant_seed   (seed, rand, _("Seed"),
                    _("Random seed"))
 
 #else
diff --git a/operations/common/mosaic.c b/operations/common/mosaic.c
index 5c34580..6205f94 100644
--- a/operations/common/mosaic.c
+++ b/operations/common/mosaic.c
@@ -70,7 +70,7 @@ gegl_chant_color     (light_color, _("Light color"), "white", _("Light color"))
 gegl_chant_double    (light_dir,  _("Light direction"),
                       0.0, 360.0, 135, _("Direction of light-source (in degrees)"))
 
-gegl_chant_seed      (seed, _("Random seed"), _("Random seed"))
+gegl_chant_seed      (seed, rand, _("Random seed"), _("Random seed"))
 
 gegl_chant_boolean   (antialiasing, _("Antialiasing"), TRUE,
                       _("Enables smoother tile output"))
@@ -310,12 +310,12 @@ static gboolean  polygon_extents       (Polygon             *poly,
                                         gdouble             *max_x,
                                         gdouble             *max_y);
 static void      polygon_reset         (Polygon             *poly);
-static gfloat    rand_f                (gint                 seed,
+static gfloat    rand_f                (GeglRandom          *rand,
                                         gfloat               pos_x,
                                         gfloat               pos_y,
                                         gfloat               min,
                                         gfloat               max);
-static gint      rand_i                (gint                 seed,
+static gint      rand_i                (GeglRandom          *rand,
                                         gfloat               pos_x,
                                         gfloat               pos_y,
                                         gint                 min,
@@ -331,24 +331,24 @@ static gfloat    distance              (SpecVec             *vec,
 #define SQR(v)     ((v)*(v))
 
 static gfloat
-rand_f (gint   seed,
-        gfloat pos_x,
-        gfloat pos_y,
-        gfloat min,
-        gfloat max)
+rand_f (GeglRandom *rand,
+        gfloat      pos_x,
+        gfloat      pos_y,
+        gfloat      min,
+        gfloat      max)
 {
-  return gegl_random_float_range (seed, ROUND (pos_x), ROUND (pos_y),
+  return gegl_random_float_range (rand, ROUND (pos_x), ROUND (pos_y),
                                   0, 0, min, max);
 }
 
 static gint
-rand_i (gint   seed,
-        gfloat pos_x,
-        gfloat pos_y,
-        gint   min,
-        gint   max)
+rand_i (GeglRandom *rand,
+        gfloat      pos_x,
+        gfloat      pos_y,
+        gint        min,
+        gint        max)
 {
-  return gegl_random_int_range (seed, ROUND (pos_x), ROUND (pos_y),
+  return gegl_random_int_range (rand, ROUND (pos_x), ROUND (pos_y),
                                 0, 0, min, max);
 }
 
@@ -1042,10 +1042,10 @@ grid_localize (const GeglRectangle *result,
         if (rand_localize > EPSILON)
           {
             /* Rely on global values to make gegl's tiles seamless */
-            max_x = pt->x + (gint) rand_f (o->seed,
+            max_x = pt->x + (gint) rand_f (o->rand,
                                            result->x + pt->x, result->y + pt->y,
                                            - rand_localize / 2.0, rand_localize / 2.0);
-            max_y = pt->y + (gint) rand_f (o->seed,
+            max_y = pt->y + (gint) rand_f (o->rand,
                                            result->y + pt->y, result->x + pt->x, /*sic*/
                                            - rand_localize / 2.0, rand_localize / 2.0);
           }
@@ -1357,12 +1357,12 @@ process_poly (Polygon             *poly,
   size = (mdatas->width * mdatas->height);
   frac_size = size * o->color_variation;
 
-  vary = rand_i (o->seed, result->x + cx, result->y + cy, 0, size) < frac_size;
+  vary = rand_i (o->rand, result->x + cx, result->y + cy, 0, size) < frac_size;
 
   /*  determine the variation of tile color based on tile number  */
   if (vary)
     {
-      color_vary = rand_f (o->seed, result->x + cx, result->y + cy,
+      color_vary = rand_f (o->rand, result->x + cx, result->y + cy,
                            - o->color_variation * 0.5, o->color_variation * 0.5);
     }
 
diff --git a/operations/common/noise-cie-lch.c b/operations/common/noise-cie-lch.c
index 4874653..1b98bf3 100644
--- a/operations/common/noise-cie-lch.c
+++ b/operations/common/noise-cie-lch.c
@@ -38,6 +38,9 @@ gegl_chant_double (hue_distance, _("Hue"),
                    0.0, 180.0,  3.0,
                    _("Hue"))
 
+gegl_chant_seed   (seed, rand, _("Seed"),
+                   _("Random seed"))
+
 #else
 
 #define GEGL_CHANT_TYPE_POINT_FILTER
@@ -49,33 +52,32 @@ gegl_chant_double (hue_distance, _("Hue"),
 #include <math.h>
 #include <stdlib.h>
 
-#define SEED 1913
-
 static gfloat
-randomize_value (gfloat     now,
-                 gfloat     min,
-                 gfloat     max,
-                 gboolean   wraps_around,
-                 gfloat     rand_max,
-                 gint       holdness,
-                 gint       x,
-                 gint       y,
-                 gint       n)
+randomize_value (gfloat      now,
+                 gfloat      min,
+                 gfloat      max,
+                 gboolean    wraps_around,
+                 gfloat      rand_max,
+                 gint        holdness,
+                 gint        x,
+                 gint        y,
+                 gint        n,
+                 GeglRandom *rand)
 {
   gint    flag, i;
   gfloat rand_val, new_val, steps;
 
   steps = max - min + 0.5;
-  rand_val = gegl_random_float (SEED, x, y, 0, n++);
+  rand_val = gegl_random_float (rand, x, y, 0, n++);
 
   for (i = 1; i < holdness; i++)
   {
-    float tmp = gegl_random_float (SEED, x, y, 0, n++);
+    float tmp = gegl_random_float (rand, x, y, 0, n++);
     if (tmp < rand_val)
       rand_val = tmp;
   }
 
-  flag = (gegl_random_float (SEED, x, y, 0, n) < 0.5) ? -1 : 1;
+  flag = (gegl_random_float (rand, x, y, 0, n) < 0.5) ? -1 : 1;
   new_val = now + flag * fmod (rand_max * rand_val, steps);
 
   if (new_val < min)
@@ -142,20 +144,21 @@ process (GeglOperation       *operation,
 
     if ((o->hue_distance > 0) && (chroma > 0))
       hue = randomize_value (hue, 0.0, 359.0, TRUE, o->hue_distance,
-                             o->holdness, x, y, n);
+                             o->holdness, x, y, n, o->rand);
 
     n += o->holdness + 1;
     if (o->chroma_distance > 0) {
       if (chroma == 0)
-        hue = gegl_random_float_range (SEED, x, y, 0, n, 0.0, 360.0);
+        hue = gegl_random_float_range (o->rand, x, y, 0, n, 0.0, 360.0);
       chroma = randomize_value (chroma, 0.0, 100.0, FALSE, o->chroma_distance,
-                                o->holdness, x, y, n+1);
+                                o->holdness, x, y, n+1, o->rand);
     }
 
     n += o->holdness + 2;
     if (o->lightness_distance > 0)
       lightness = randomize_value (lightness, 0.0, 100.0, FALSE,
-                                   o->lightness_distance, o->holdness, x, y, n);
+                                   o->lightness_distance, o->holdness,
+                                   x, y, n, o->rand);
 
     /*n += o->holdness + 1*/
     out_pixel[0] = lightness;
diff --git a/operations/common/noise-hsv.c b/operations/common/noise-hsv.c
index 90bbd5a..9d358b6 100644
--- a/operations/common/noise-hsv.c
+++ b/operations/common/noise-hsv.c
@@ -40,6 +40,9 @@ gegl_chant_double (value_distance, _("Value"),
                    0.0, 1.0, 0.04,
                    _("Value"))
 
+gegl_chant_seed   (seed, rand, _("Seed"),
+                   _("Random seed"))
+
 #else
 
 #define GEGL_CHANT_TYPE_POINT_FILTER
@@ -50,33 +53,32 @@ gegl_chant_double (value_distance, _("Value"),
 #include <math.h>
 #include <stdlib.h>
 
-#define SEED 1913
-
 static gfloat
-randomize_value (gfloat     now,
-                 gfloat     min,
-                 gfloat     max,
-                 gboolean   wraps_around,
-                 gfloat     rand_max,
-                 gint       holdness,
-                 gint       x,
-                 gint       y,
-                 gint       n)
+randomize_value (gfloat      now,
+                 gfloat      min,
+                 gfloat      max,
+                 gboolean    wraps_around,
+                 gfloat      rand_max,
+                 gint        holdness,
+                 gint        x,
+                 gint        y,
+                 gint        n,
+                 GeglRandom *rand)
 {
   gint    flag, i;
   gfloat rand_val, new_val, steps;
 
   steps = max - min;
-  rand_val = gegl_random_float (SEED, x, y, 0, n++);
+  rand_val = gegl_random_float (rand, x, y, 0, n++);
 
   for (i = 1; i < holdness; i++)
   {
-    gfloat tmp = gegl_random_float (SEED, x, y, 0, n++);
+    gfloat tmp = gegl_random_float (rand, x, y, 0, n++);
     if (tmp < rand_val)
       rand_val = tmp;
   }
 
-  flag = (gegl_random_float (SEED, x, y, 0, n) < 0.5) ? -1 : 1;
+  flag = (gegl_random_float (rand, x, y, 0, n) < 0.5) ? -1 : 1;
   new_val = now + flag * fmod (rand_max * rand_val, steps);
 
   if (new_val < min)
@@ -144,22 +146,22 @@ process (GeglOperation       *operation,
     /* there is no need for scattering hue of desaturated pixels here */
     if ((o->hue_distance > 0) && (saturation > 0))
       hue = randomize_value (hue, 0.0, 1.0, TRUE, o->hue_distance / 360.0,
-                             o->holdness, x, y, n);
+                             o->holdness, x, y, n, o->rand);
 
     n += o->holdness + 1;
     /* desaturated pixels get random hue before increasing saturation */
     if (o->saturation_distance > 0) {
       if (saturation == 0)
-        hue = gegl_random_float_range (SEED, x, y, 0, n, 0.0, 1.0);
+        hue = gegl_random_float_range (o->rand, x, y, 0, n, 0.0, 1.0);
       saturation = randomize_value (saturation, 0.0, 1.0, FALSE,
                                     o->saturation_distance, o->holdness,
-                                    x, y, n+1);
+                                    x, y, n+1, o->rand);
     }
 
     n += o->holdness + 2;
     if (o->value_distance > 0)
       value = randomize_value (value, 0.0, 1.0, FALSE, o->value_distance,
-                               o->holdness, x, y, n);
+                               o->holdness, x, y, n, o->rand);
 
     out_pixel[0] = hue;
     out_pixel[1] = saturation;
diff --git a/operations/common/noise-hurl.c b/operations/common/noise-hurl.c
index a8692dd..9c9f560 100644
--- a/operations/common/noise-hurl.c
+++ b/operations/common/noise-hurl.c
@@ -28,7 +28,7 @@
 
 #ifdef GEGL_CHANT_PROPERTIES
 
-gegl_chant_seed   (seed, _("Seed"),
+gegl_chant_seed   (seed, rand, _("Seed"),
                    _("Random seed"))
 
 gegl_chant_double (pct_random, _("Randomization (%)"),
@@ -86,12 +86,12 @@ process (GeglOperation       *operation,
           {
             gint n = 4 * (idx + cnt * total_size);
 
-            if (gegl_random_float_range (o->seed, x, y, 0, n, 0.0, 100.0) <=
+            if (gegl_random_float_range (o->rand, x, y, 0, n, 0.0, 100.0) <=
                 o->pct_random)
               {
-                red   = gegl_random_float (o->seed, x, y, 0, n+1);
-                green = gegl_random_float (o->seed, x, y, 0, n+2);
-                blue  = gegl_random_float (o->seed, x, y, 0, n+3);
+                red   = gegl_random_float (o->rand, x, y, 0, n+1);
+                green = gegl_random_float (o->rand, x, y, 0, n+2);
+                blue  = gegl_random_float (o->rand, x, y, 0, n+3);
                 break;
               }
           }
@@ -124,18 +124,19 @@ cl_process (GeglOperation       *operation,
   GeglChantO    *o          = GEGL_CHANT_PROPERTIES (operation);
   GeglRectangle *wr         = gegl_operation_source_get_bounding_box (operation,
                                                                       "input");
-  cl_int   cl_err           = 0;
-  cl_mem   cl_random_data   = NULL;
-  cl_mem   cl_random_primes = NULL;
-  cl_float pct_random       = o->pct_random;
-  cl_int   seed             = o->seed;
-  cl_int   x_offset         = roi->x;
-  cl_int   y_offset         = roi->y;
-  cl_int   roi_width        = roi->width;
-  cl_int   wr_width         = wr->width;
-  int      total_size       = wr->width*wr->height;
-  cl_int   offset;
-  int      it;
+  cl_int      cl_err           = 0;
+  cl_mem      cl_random_data   = NULL;
+  cl_float    pct_random       = o->pct_random;
+  cl_int      x_offset         = roi->x;
+  cl_int      y_offset         = roi->y;
+  cl_int      roi_width        = roi->width;
+  cl_int      wr_width         = wr->width;
+  int         total_size       = wr->width*wr->height;
+  cl_int      offset;
+  int         it;
+  cl_ushort4  rand;
+
+  gegl_cl_random_get_ushort4 (o->rand, &rand);
 
   if (!cl_data)
   {
@@ -149,8 +150,6 @@ cl_process (GeglOperation       *operation,
   {
   cl_random_data = gegl_cl_load_random_data (&cl_err);
   CL_CHECK;
-  cl_random_primes = gegl_cl_load_random_primes (&cl_err);
-  CL_CHECK;
 
   cl_err = gegl_clEnqueueCopyBuffer (gegl_cl_get_command_queue(),
                                      in , out , 0 , 0 ,
@@ -161,12 +160,11 @@ cl_process (GeglOperation       *operation,
   gegl_cl_set_kernel_args (cl_data->kernel[0],
                            sizeof(cl_mem),   &out,
                            sizeof(cl_mem),   &cl_random_data,
-                           sizeof(cl_mem),   &cl_random_primes,
                            sizeof(cl_int),   &x_offset,
                            sizeof(cl_int),   &y_offset,
                            sizeof(cl_int),   &roi_width,
                            sizeof(cl_int),   &wr_width,
-                           sizeof(cl_int),   &seed,
+                           sizeof(cl_ushort4), &rand,
                            sizeof(cl_float), &pct_random,
                            NULL);
   CL_CHECK;
@@ -175,7 +173,7 @@ cl_process (GeglOperation       *operation,
 
   for(it = 0; it < o->repeat; ++it)
     {
-      cl_err = gegl_clSetKernelArg (cl_data->kernel[0], 9, sizeof(cl_int),
+      cl_err = gegl_clSetKernelArg (cl_data->kernel[0], 8, sizeof(cl_int),
                                     (void*)&offset);
       CL_CHECK;
       cl_err = gegl_clEnqueueNDRangeKernel (gegl_cl_get_command_queue (),
@@ -192,9 +190,6 @@ cl_process (GeglOperation       *operation,
 
   cl_err = gegl_clReleaseMemObject (cl_random_data);
   CL_CHECK_ONLY (cl_err);
-
-  cl_err = gegl_clReleaseMemObject (cl_random_primes);
-  CL_CHECK_ONLY (cl_err);
   }
 
   return  FALSE;
@@ -202,8 +197,6 @@ cl_process (GeglOperation       *operation,
 error:
   if (cl_random_data)
     gegl_clReleaseMemObject (cl_random_data);
-  if (cl_random_primes)
-    gegl_clReleaseMemObject (cl_random_primes);
 
   return TRUE;
 }
diff --git a/operations/common/noise-pick.c b/operations/common/noise-pick.c
index 2cb8563..3c70d1b 100644
--- a/operations/common/noise-pick.c
+++ b/operations/common/noise-pick.c
@@ -29,7 +29,7 @@
 
 #ifdef GEGL_CHANT_PROPERTIES
 
-gegl_chant_seed   (seed, _("Seed"),
+gegl_chant_seed   (seed, rand, _("Seed"),
                    _("Random seed"))
 
 gegl_chant_double (pct_random, _("Randomization (%)"),
@@ -105,7 +105,7 @@ process (GeglOperation       *operation,
 
             for (r = 0; r < o->repeat; r++)
               {
-                guint  rand = gegl_random_int (o->seed, pos_x, pos_y, 0, r);
+                guint  rand = gegl_random_int (o->rand, pos_x, pos_y, 0, r);
                 gfloat pct  = RAND_UINT_TO_FLOAT (rand) * 100.0;
 
                 if (pct <= o->pct_random)
diff --git a/operations/common/noise-rgb.c b/operations/common/noise-rgb.c
index 1bd8c61..1566be9 100644
--- a/operations/common/noise-rgb.c
+++ b/operations/common/noise-rgb.c
@@ -49,7 +49,7 @@ gegl_chant_double  (alpha, _("Alpha"),
                     0.0, 1.0, 0.00,
                     _("Alpha"))
 
-gegl_chant_seed    (seed, _("Seed"),
+gegl_chant_seed    (seed, rand, _("Seed"),
                     _("Random seed"))
 
 #else
@@ -71,16 +71,16 @@ gegl_chant_seed    (seed, _("Seed"),
  * K+M, ACM Trans Math Software 3 (1977) 257-260.
 */
 static gdouble
-gauss (int seed, int *i, int xx, int yy)
+gauss (GeglRandom *rand, int *i, int xx, int yy)
 {
   gdouble u, v, x;
 
   do
   {
-    v = gegl_random_float (seed, xx, yy, 0, (*i)++);
+    v = gegl_random_float (rand, xx, yy, 0, (*i)++);
 
     do
-      u = gegl_random_float (seed, xx, yy, 0, (*i)++);
+      u = gegl_random_float (rand, xx, yy, 0, (*i)++);
     while (u == 0);
 
     /* Const 1.715... = sqrt(8/e) */
@@ -133,7 +133,7 @@ process (GeglOperation       *operation,
     for (b = 0; b < 4; b++)
     {
       if (b == 0 || o->independent || b == 3 )
-         noise_coeff = noise[b] * gauss (o->seed, &rint, x, y) * 0.5;
+         noise_coeff = noise[b] * gauss (o->rand, &rint, x, y) * 0.5;
 
       if (noise[b] > 0.0)
       {
diff --git a/operations/common/noise-slur.c b/operations/common/noise-slur.c
index f9f4ad7..4c73b7f 100644
--- a/operations/common/noise-slur.c
+++ b/operations/common/noise-slur.c
@@ -31,7 +31,7 @@
 
 #ifdef GEGL_CHANT_PROPERTIES
 
-gegl_chant_seed   (seed, _("Seed"),
+gegl_chant_seed   (seed, rand, _("Seed"),
                    _("Random seed"))
 
 gegl_chant_double (pct_random, _("Randomization (%)"),
@@ -106,7 +106,7 @@ process (GeglOperation       *operation,
 
             for (r = 0; r < o->repeat; r++)
               {
-                guint  rand = gegl_random_int (o->seed, pos_x, pos_y, 0, r);
+                guint  rand = gegl_random_int (o->rand, pos_x, pos_y, 0, r);
                 gfloat pct  = RAND_UINT_TO_FLOAT (rand) * 100.0;
 
                 if (pct <= o->pct_random)
diff --git a/operations/common/noise-spread.c b/operations/common/noise-spread.c
index 7f543c3..f4acb29 100644
--- a/operations/common/noise-spread.c
+++ b/operations/common/noise-spread.c
@@ -34,7 +34,7 @@ gegl_chant_int  (amount_y, _("Vertical"),
                  0, 256, 5,
                  _("Vertical spread amount"))
 
-gegl_chant_seed (seed, _("Seed"),
+gegl_chant_seed (seed, rand, _("Seed"),
                  _("Random seed"))
 
 #else
@@ -46,23 +46,23 @@ gegl_chant_seed (seed, _("Seed"),
 #include <math.h>
 
 static inline void
-calc_sample_coords (gint  src_x,
-                    gint  src_y,
-                    gint  amount_x,
-                    gint  amount_y,
-                    gint  seed,
-                    gint *x,
-                    gint *y)
+calc_sample_coords (gint        src_x,
+                    gint        src_y,
+                    gint        amount_x,
+                    gint        amount_y,
+                    GeglRandom *rand,
+                    gint       *x,
+                    gint       *y)
 {
   gdouble angle;
   gint    xdist, ydist;
 
   /* get random angle, x distance, and y distance */
-  xdist = amount_x > 0 ? gegl_random_int_range (seed, src_x, src_y, 0, 0,
+  xdist = amount_x > 0 ? gegl_random_int_range (rand, src_x, src_y, 0, 0,
                                                 -amount_x, amount_x + 1) : 0;
-  ydist = amount_y > 0 ? gegl_random_int_range (seed, src_x, src_y, 0, 1,
+  ydist = amount_y > 0 ? gegl_random_int_range (rand, src_x, src_y, 0, 1,
                                                 -amount_y, amount_y + 1) : 0;
-  angle = gegl_random_float_range (seed, src_x, src_y, 0, 2, -G_PI, G_PI);
+  angle = gegl_random_float_range (rand, src_x, src_y, 0, 2, -G_PI, G_PI);
 
   *x = src_x + floor (sin (angle) * xdist);
   *y = src_y + floor (cos (angle) * ydist);
@@ -123,7 +123,7 @@ process (GeglOperation       *operation,
           {
             gint x, y;
 
-            calc_sample_coords (i, j, amount_x, amount_y, o->seed, &x, &y);
+            calc_sample_coords (i, j, amount_x, amount_y, o->rand, &x, &y);
 
             gegl_buffer_sample (input, x, y, NULL, data, format,
                                 GEGL_SAMPLER_NEAREST, GEGL_ABYSS_CLAMP);
diff --git a/operations/common/plasma.c b/operations/common/plasma.c
index 24d5f25..028307d 100644
--- a/operations/common/plasma.c
+++ b/operations/common/plasma.c
@@ -33,7 +33,7 @@
 
 #ifdef GEGL_CHANT_PROPERTIES
 
-gegl_chant_seed (seed, _("Random seed"), _("Random seed"))
+gegl_chant_seed (seed, rand, _("Random seed"), _("Random seed"))
 
 gegl_chant_double (turbulence, _("Turbulence"), 0.0, 7.0, 1.0,
                    _("The value of the turbulence"))
diff --git a/operations/common/shift.c b/operations/common/shift.c
index bea7baa..86a5348 100644
--- a/operations/common/shift.c
+++ b/operations/common/shift.c
@@ -32,7 +32,7 @@ gegl_chant_int  (shift, _("Shift"),
                  1, 200, 5,
                  _("Maximum amount to shift"))
 
-gegl_chant_seed (seed, _("Seed"),
+gegl_chant_seed (seed, rand, _("Seed"),
                  _("Random seed"))
 
 gegl_chant_enum (direction, _("Direction"),
@@ -133,7 +133,7 @@ process (GeglOperation       *operation,
 
           for (i = 0; i < array_size; i++)
             {
-              r = gegl_random_int_range (o->seed, i, 0, 0, 0, -s, s + 1);
+              r = gegl_random_int_range (o->rand, i, 0, 0, 0, -s, s + 1);
               g_array_append_val (offsets, r);
             }
           o->chant_data = offsets;
diff --git a/operations/common/wind.c b/operations/common/wind.c
index b10ef41..46a3c31 100644
--- a/operations/common/wind.c
+++ b/operations/common/wind.c
@@ -30,7 +30,7 @@ gegl_chant_double (threshold, _("Threshold"), 0.0, 100.0, 10.0,
 gegl_chant_int (strength, _("Strength"), 1, 1000, 40,
                 _("Higher values increase the magnitude of the effect"))
 
-gegl_chant_seed (seed, _("Seed"), _("Random seed"))
+gegl_chant_seed (seed, rand, _("Seed"), _("Random seed"))
 
 #else
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]