[gegl] random: improve gegl-random implementation
- From: Téo Mazars <teom src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] random: improve gegl-random implementation
- Date: Thu, 14 Nov 2013 18:19:21 +0000 (UTC)
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]