[gegl] Made the number of threads configurable.
- From: Øyvind Kolås <ok src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gegl] Made the number of threads configurable.
- Date: Sun, 22 Nov 2009 16:42:10 +0000 (UTC)
commit e3e11f3f9d72daf377d1b1e88fee7e83bc60356a
Author: �yvind Kolås <pippin gimp org>
Date: Sun Nov 22 16:11:32 2009 +0000
Made the number of threads configurable.
Added a threads member to GeglConfig which is picked up by
environment variable or commandline. Default value 2.
gegl/buffer/gegl-cache.c | 1 +
gegl/gegl-config.c | 26 +++++++++++++++++++++++++-
gegl/gegl-config.h | 3 +++
gegl/gegl-init.c | 19 ++++++++++++++++++-
gegl/gegl-instrument.c | 2 --
gegl/graph/gegl-node.c | 6 +++++-
gegl/operation/gegl-operation.c | 12 +++++++++++-
gegl/process/gegl-eval-mgr.c | 4 +++-
gegl/process/gegl-have-visitor.c | 6 ++++++
gegl/process/gegl-prepare-visitor.c | 12 ++++++++++++
gegl/property-types/gegl-path.c | 2 +-
operations/external/path.c | 4 +++-
12 files changed, 88 insertions(+), 9 deletions(-)
---
diff --git a/gegl/buffer/gegl-cache.c b/gegl/buffer/gegl-cache.c
index 356330a..4b4be21 100644
--- a/gegl/buffer/gegl-cache.c
+++ b/gegl/buffer/gegl-cache.c
@@ -33,6 +33,7 @@
#include "gegl-cache.h"
#include "gegl-region.h"
+#undef ENABLE_MT
#if ENABLE_MT
static GStaticRecMutex mutex = G_STATIC_REC_MUTEX_INIT;
#endif
diff --git a/gegl/gegl-config.c b/gegl/gegl-config.c
index 5f61a02..74a5365 100644
--- a/gegl/gegl-config.c
+++ b/gegl/gegl-config.c
@@ -19,7 +19,7 @@
#include <glib-object.h>
#include <string.h>
#include <glib/gprintf.h>
-
+#include "config.h"
#include "gegl.h"
#include "gegl-types-internal.h"
#include "gegl-config.h"
@@ -38,6 +38,9 @@ enum
PROP_BABL_TOLERANCE,
PROP_TILE_WIDTH,
PROP_TILE_HEIGHT
+#if ENABLE_MT
+ ,PROP_THREADS
+#endif
};
static void
@@ -78,6 +81,12 @@ get_property (GObject *gobject,
g_value_set_string (value, config->swap);
break;
+#if ENABLE_MT
+ case PROP_THREADS:
+ g_value_set_int (value, config->threads);
+ break;
+#endif
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
break;
@@ -126,6 +135,11 @@ set_property (GObject *gobject,
g_free (config->swap);
config->swap = g_value_dup_string (value);
break;
+#if ENABLE_MT
+ case PROP_THREADS:
+ config->threads = g_value_get_int (value);
+ return;
+#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
break;
@@ -190,6 +204,13 @@ gegl_config_class_init (GeglConfigClass *klass)
g_object_class_install_property (gobject_class, PROP_SWAP,
g_param_spec_string ("swap", "Swap", "where gegl stores it's swap files", NULL,
G_PARAM_READWRITE));
+
+#if ENABLE_MT
+ g_object_class_install_property (gobject_class, PROP_TILE_HEIGHT,
+ g_param_spec_int ("threads", "Number of concurrent evaluation threads", "default tile height for created buffers.",
+ 0, 16, 2,
+ G_PARAM_READWRITE));
+#endif
}
static void
@@ -201,4 +222,7 @@ gegl_config_init (GeglConfig *self)
self->chunk_size = 512 * 512;
self->tile_width = 64;
self->tile_height = 128;
+#if ENABLE_MT
+ self->threads = 2;
+#endif
}
diff --git a/gegl/gegl-config.h b/gegl/gegl-config.h
index 4ec92d1..f7bbd46 100644
--- a/gegl/gegl-config.h
+++ b/gegl/gegl-config.h
@@ -44,6 +44,9 @@ struct _GeglConfig
gdouble babl_tolerance;
gint tile_width;
gint tile_height;
+#if ENABLE_MT
+ gint threads;
+#endif
};
struct _GeglConfigClass
diff --git a/gegl/gegl-init.c b/gegl/gegl-init.c
index 81e0fba..950f27a 100644
--- a/gegl/gegl-init.c
+++ b/gegl/gegl-init.c
@@ -205,6 +205,9 @@ static gchar *cmd_gegl_chunk_size=NULL;
static gchar *cmd_gegl_quality=NULL;
static gchar *cmd_gegl_tile_size=NULL;
static gchar *cmd_babl_tolerance =NULL;
+#if ENABLE_MT
+static gchar *cmd_gegl_threads=NULL;
+#endif
static const GOptionEntry cmd_entries[]=
{
@@ -238,6 +241,13 @@ static const GOptionEntry cmd_entries[]=
G_OPTION_ARG_STRING, &cmd_gegl_quality,
N_("The quality of rendering a value between 0.0(fast) and 1.0(reference)"), "<quality>"
},
+#if ENABLE_MT
+ {
+ "gegl-threads", 0, 0,
+ G_OPTION_ARG_STRING, &cmd_gegl_threads,
+ N_("The number of concurrent processing threads to use."), "<threads>"
+ },
+#endif
{ NULL }
};
@@ -284,6 +294,10 @@ GeglConfig *gegl_config (void)
if (str)
config->tile_height = atoi(str+1);
}
+#if ENABLE_MT
+ if (g_getenv ("GEGL_THREADS"))
+ config->threads = atoi(g_getenv("GEGL_THREADS"));
+#endif
if (gegl_swap_dir())
config->swap = g_strdup(gegl_swap_dir ());
}
@@ -476,7 +490,10 @@ gegl_post_parse_hook (GOptionContext *context,
if (str)
config->tile_height = atoi(str+1);
}
-
+#if ENABLE_MT
+ if (cmd_gegl_threads)
+ config->threads = atoi (cmd_gegl_threads);
+#endif
if (cmd_babl_tolerance)
g_object_set (config, "babl-tolerance", atof(cmd_babl_tolerance), NULL);
diff --git a/gegl/gegl-instrument.c b/gegl/gegl-instrument.c
index 2683274..1292b67 100644
--- a/gegl/gegl-instrument.c
+++ b/gegl/gegl-instrument.c
@@ -104,8 +104,6 @@ gegl_instrument (const gchar *parent_name,
Timing *iter;
Timing *parent;
- return;
-
if (root == NULL)
{
root = g_slice_new0 (Timing);
diff --git a/gegl/graph/gegl-node.c b/gegl/graph/gegl-node.c
index d0f9df8..37e5470 100644
--- a/gegl/graph/gegl-node.c
+++ b/gegl/graph/gegl-node.c
@@ -33,6 +33,7 @@
#include "gegl-pad.h"
#include "gegl-utils.h"
#include "gegl-visitable.h"
+#include "gegl-config.h"
#include "operation/gegl-operation.h"
#include "operation/gegl-operations.h"
@@ -916,12 +917,15 @@ gegl_node_blit (GeglNode *self,
gint rowstride,
GeglBlitFlags flags)
{
+#if ENABLE_MT
gint threads;
+#endif
g_return_if_fail (GEGL_IS_NODE (self));
g_return_if_fail (roi != NULL);
- threads = 2; /* tunable here for now, should be picked up through GeglConfig */
#if ENABLE_MT
+ threads = gegl_config ()->threads;
+
if (pool == NULL)
{
pool = g_thread_pool_new (spawnrender, NULL, threads, TRUE, NULL);
diff --git a/gegl/operation/gegl-operation.c b/gegl/operation/gegl-operation.c
index 8df8e70..caf0fc0 100644
--- a/gegl/operation/gegl-operation.c
+++ b/gegl/operation/gegl-operation.c
@@ -276,7 +276,17 @@ gegl_operation_source_get_bounding_box (GeglOperation *operation,
GeglNode *node = gegl_operation_get_source_node (operation, input_pad_name);
if (node)
- return &node->have_rect;
+ {
+ GeglRectangle *ret;
+#if ENABLE_MT
+ g_mutex_lock (node->mutex);
+#endif
+ ret = &node->have_rect;
+#if ENABLE_MT
+ g_mutex_unlock (node->mutex);
+#endif
+ return ret;
+ }
return NULL;
}
diff --git a/gegl/process/gegl-eval-mgr.c b/gegl/process/gegl-eval-mgr.c
index b8a4ab7..9c96ff0 100644
--- a/gegl/process/gegl-eval-mgr.c
+++ b/gegl/process/gegl-eval-mgr.c
@@ -163,6 +163,7 @@ gegl_eval_mgr_apply (GeglEvalMgr *self)
gegl_visitor_reset (self->have_visitor);
gegl_visitor_dfs_traverse (self->have_visitor, GEGL_VISITABLE (root));
case NEED_CONTEXT_SETUP_TRAVERSAL:
+
gegl_visitor_reset (self->prepare_visitor);
gegl_visitor_dfs_traverse (self->prepare_visitor, GEGL_VISITABLE (root));
self->state = NEED_CONTEXT_SETUP_TRAVERSAL;
@@ -209,7 +210,8 @@ gegl_eval_mgr_apply (GeglEvalMgr *self)
{ /* pull on the input of our sink if no pad of the given pad-name
was available, we take this as an indication that we're in fact
doing processing on a sink (and the ROI inidcates the data to
- be written.
+ be written, note that GEGL might subdivide this roi
+ in its processing.
*/
GeglPad *pad = gegl_node_get_pad (root, "input");
gegl_visitor_dfs_traverse (self->eval_visitor, GEGL_VISITABLE (pad));
diff --git a/gegl/process/gegl-have-visitor.c b/gegl/process/gegl-have-visitor.c
index 850e7b2..28e9cac 100644
--- a/gegl/process/gegl-have-visitor.c
+++ b/gegl/process/gegl-have-visitor.c
@@ -64,9 +64,15 @@ gegl_have_visitor_visit_node (GeglVisitor *self,
if (!node)
return;
operation = node->operation;
+#if ENABLE_MT
+ g_mutex_lock (node->mutex);
+#endif
rect = gegl_operation_get_bounding_box (operation);
node->have_rect = rect;
+#if ENABLE_MT
+ g_mutex_unlock (node->mutex);
+#endif
time = gegl_ticks () - time;
gegl_instrument ("process", gegl_node_get_operation (node), time);
diff --git a/gegl/process/gegl-prepare-visitor.c b/gegl/process/gegl-prepare-visitor.c
index 91be7f5..e430c49 100644
--- a/gegl/process/gegl-prepare-visitor.c
+++ b/gegl/process/gegl-prepare-visitor.c
@@ -80,15 +80,27 @@ gegl_prepare_visitor_visit_node (GeglVisitor *self,
g_assert (graph);
if (GEGL_NODE (graph)->operation)
{
+#if ENABLE_MT
+ g_mutex_lock (GEGL_NODE (graph)->mutex);
+#endif
/* issuing a prepare on the graph, FIXME: we might need to do
* a cycle of prepares as deep as the nesting of graphs,.
* (or find a better way to do this) */
gegl_operation_prepare (GEGL_NODE (graph)->operation);
+#if ENABLE_MT
+ g_mutex_unlock (GEGL_NODE (graph)->mutex);
+#endif
}
}
}
+#if ENABLE_MT
+ g_mutex_lock (node->mutex);
+#endif
gegl_operation_prepare (operation);
+#if ENABLE_MT
+ g_mutex_unlock (node->mutex);
+#endif
{
/* initialise the "needed rectangle" to an empty one */
GeglRectangle empty ={0,};
diff --git a/gegl/property-types/gegl-path.c b/gegl/property-types/gegl-path.c
index 88c8a9a..7d94c4a 100644
--- a/gegl/property-types/gegl-path.c
+++ b/gegl/property-types/gegl-path.c
@@ -1961,7 +1961,7 @@ static void gegl_path_stamp (GeglBuffer *buffer,
gdouble opacity)
{
gfloat col[4];
- static StampStatic s = {FALSE,}; /* XXX:
+ StampStatic s = {FALSE,}; /* XXX:
we will ultimately leak the last valid
cached brush. */
diff --git a/operations/external/path.c b/operations/external/path.c
index d689bfa..30b63ff 100644
--- a/operations/external/path.c
+++ b/operations/external/path.c
@@ -187,10 +187,11 @@ process (GeglOperation *operation,
a *= o->fill_opacity;
if (a>0.001)
{
+ GStaticMutex mutex = G_STATIC_MUTEX_INIT;
cairo_t *cr;
cairo_surface_t *surface;
+ g_static_mutex_lock (&mutex);
guchar *data = (void*)gegl_buffer_linear_open (output, result, NULL, babl_format ("B'aG'aR'aA u8"));
-
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
result->width,
@@ -220,6 +221,7 @@ process (GeglOperation *operation,
}
#endif
+ g_static_mutex_unlock (&mutex);
gegl_buffer_linear_close (output, data);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]