[gegl] Re-enable shared read-write buffers.
- From: Øyvind Kolås <ok src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gegl] Re-enable shared read-write buffers.
- Date: Tue, 1 Dec 2009 00:17:22 +0000 (UTC)
commit 66a7cd72883baff6575fd25295bf499767258fd3
Author: �yvind Kolås <pippin gimp org>
Date: Fri Nov 27 00:41:46 2009 +0000
Re-enable shared read-write buffers.
glib provides the ability to open files read/write now, re-enabled
code that synchronises access from multiple concurrent GEGL processes.
The code seems to have some flakiness but it basically works.
examples/geglbuffer-clock.c | 9 +++-
examples/multiplayer-paint.sh | 10 ++--
gegl/buffer/Makefile.am | 1 +
gegl/buffer/gegl-buffer-access.c | 2 -
gegl/buffer/gegl-buffer-iterator.c | 5 ++-
gegl/buffer/gegl-buffer-linear.c | 2 +-
gegl/buffer/gegl-buffer.c | 27 +++++------
gegl/buffer/gegl-tile-backend-file.c | 83 +++++++++++++++++++--------------
gegl/buffer/gegl-tile.c | 4 --
gegl/gegl-config.c | 4 +-
gegl/property-types/gegl-path.c | 12 +++--
operations/common/buffer-source.c | 14 ++++++
12 files changed, 101 insertions(+), 72 deletions(-)
---
diff --git a/examples/geglbuffer-clock.c b/examples/geglbuffer-clock.c
index 4691883..6dd2656 100644
--- a/examples/geglbuffer-clock.c
+++ b/examples/geglbuffer-clock.c
@@ -11,6 +11,7 @@ main (gint argc,
gchar **argv)
{
GeglNode *gegl; /* the gegl graph we're using as a node factor */
+ GeglBuffer *buffer;
GeglNode *display,
*text,
*layer,
@@ -31,6 +32,8 @@ main (gint argc,
gegl = gegl_node_new ();
+ buffer = gegl_buffer_open (argv[1]);
+
blank = gegl_node_new_child (gegl,
"operation", "gegl:color",
"value", gegl_color_new ("rgba(0.0,0.0,0.0,0.4)"),
@@ -57,11 +60,11 @@ main (gint argc,
text = gegl_node_new_child (gegl,
"operation", "gegl:text",
"size", 20.0,
- /* "color", gegl_color_new ("rgb(0.0,0.0,0.0)"),*/
+ "color", gegl_color_new ("rgb(1.0,1.0,1.0)"),
NULL);
display = gegl_node_new_child (gegl,
- "operation", "gegl:composite-buffer",
- "path", argv[1],
+ "operation", "gegl:write-buffer",
+ "buffer", buffer,
NULL);
gegl_node_link_many (blank, crop, layer, shift, display, NULL);
diff --git a/examples/multiplayer-paint.sh b/examples/multiplayer-paint.sh
index d47e1cf..7d72f90 100755
--- a/examples/multiplayer-paint.sh
+++ b/examples/multiplayer-paint.sh
@@ -1,12 +1,12 @@
#!/bin/sh
+killall -9 geglbuffer-clock gegl-paint lt-geglbuffer-clock lt-gegl-paint
+
./2geglbuffer data/surfer.png test.gegl
-./geglbuffer-add-image test.gegl data/surfer.png 64 64
-./geglbuffer-clock test.gegl &
./gegl-paint test.gegl &
./gegl-paint test.gegl &
+sleep 3
+#./geglbuffer-add-image test.gegl data/surfer.png 64 64
+./geglbuffer-clock test.gegl
-gegl -x '<gegl><open-buffer path="test.gegl"/></gegl>'
-
-killall -9 geglbuffer-clock gegl-paint lt-geglbuffer-clock lt-gegl-paint
diff --git a/gegl/buffer/Makefile.am b/gegl/buffer/Makefile.am
index 21c44a6..5458703 100644
--- a/gegl/buffer/Makefile.am
+++ b/gegl/buffer/Makefile.am
@@ -41,6 +41,7 @@ libbuffer_la_SOURCES = \
gegl-tile-storage.c \
gegl-tile-backend.c \
gegl-tile-backend-file.c \
+ gegl-tile-backend-gio.c \
gegl-tile-backend-ram.c \
gegl-tile-handler.c \
gegl-tile-handler-cache.c \
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index ac0ddd0..d8f4afb 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -1061,9 +1061,7 @@ gegl_buffer_get (GeglBuffer *buffer,
gint rowstride)
{
g_return_if_fail (GEGL_IS_BUFFER (buffer));
- gegl_buffer_lock (buffer);
gegl_buffer_get_unlocked (buffer, scale, rect, format, dest_buf, rowstride);
- gegl_buffer_unlock (buffer);
}
const GeglRectangle *
diff --git a/gegl/buffer/gegl-buffer-iterator.c b/gegl/buffer/gegl-buffer-iterator.c
index 4973d38..b716d23 100644
--- a/gegl/buffer/gegl-buffer-iterator.c
+++ b/gegl/buffer/gegl-buffer-iterator.c
@@ -433,7 +433,10 @@ gboolean gegl_buffer_iterator_next (GeglBufferIterator *iterator)
ensure_buf (i, no);
- gegl_buffer_set_unlocked (i->buffer[no], &(i->roi[no]), i->format[no], i->buf[no], GEGL_AUTO_ROWSTRIDE);
+ /* XXX: should perhaps use _set_unlocked, and keep the lock in the
+ * iterator.
+ */
+ gegl_buffer_set (i->buffer[no], &(i->roi[no]), i->format[no], i->buf[no], GEGL_AUTO_ROWSTRIDE);
}
}
}
diff --git a/gegl/buffer/gegl-buffer-linear.c b/gegl/buffer/gegl-buffer-linear.c
index 6977a2f..0626359 100644
--- a/gegl/buffer/gegl-buffer-linear.c
+++ b/gegl/buffer/gegl-buffer-linear.c
@@ -243,7 +243,7 @@ gegl_buffer_linear_close (GeglBuffer *buffer,
*/
}
- gegl_buffer_set_unlocked (buffer, &info->extent, info->format, info->buf, 0);
+ gegl_buffer_set (buffer, &info->extent, info->format, info->buf, 0);
break;
}
else
diff --git a/gegl/buffer/gegl-buffer.c b/gegl/buffer/gegl-buffer.c
index ff8d91c..3d9bbac 100644
--- a/gegl/buffer/gegl-buffer.c
+++ b/gegl/buffer/gegl-buffer.c
@@ -1206,14 +1206,13 @@ gboolean gegl_buffer_is_shared (GeglBuffer *buffer)
gboolean gegl_buffer_try_lock (GeglBuffer *buffer)
{
-#if 0
+ gboolean ret;
GeglTileBackend *backend = gegl_buffer_backend (buffer);
if (buffer->lock_count>0)
{
buffer->lock_count++;
return TRUE;
}
- gboolean ret;
if (gegl_buffer_is_shared(buffer))
ret =gegl_tile_backend_file_try_lock (GEGL_TILE_BACKEND_FILE (backend));
else
@@ -1221,26 +1220,26 @@ gboolean gegl_buffer_try_lock (GeglBuffer *buffer)
if (ret)
buffer->lock_count++;
return TRUE;
-#else
- //return g_mutex_trylock (buffer->tile_storage->mutex);
- return FALSE;
-#endif
}
-#if 1
+/* this locking is for synchronising shared buffers */
gboolean gegl_buffer_lock (GeglBuffer *buffer)
{
-#if ENABLE_MT
- if(0)g_mutex_lock (buffer->tile_storage->mutex);
-#endif
+ while (gegl_buffer_try_lock (buffer)==FALSE)
+ {
+ g_print ("waiting to aquire buffer..");
+ g_usleep (100000);
+ }
return TRUE;
}
gboolean gegl_buffer_unlock (GeglBuffer *buffer)
{
-#if ENABLE_MT
- if(0)g_mutex_unlock (buffer->tile_storage->mutex);
-#endif
+ GeglTileBackend *backend = gegl_buffer_backend (buffer);
+ g_assert (buffer->lock_count >=0);
+ buffer->lock_count--;
+ g_assert (buffer->lock_count >=0);
+ if (buffer->lock_count == 0 && gegl_buffer_is_shared (buffer))
+ return gegl_tile_backend_file_unlock (GEGL_TILE_BACKEND_FILE (backend));
return TRUE;
}
-#endif
diff --git a/gegl/buffer/gegl-tile-backend-file.c b/gegl/buffer/gegl-tile-backend-file.c
index da29058..061897a 100644
--- a/gegl/buffer/gegl-tile-backend-file.c
+++ b/gegl/buffer/gegl-tile-backend-file.c
@@ -95,12 +95,16 @@ struct _GeglTileBackendFile
/* GFile refering to our buffer */
GFile *file;
- /* for writing */
- GOutputStream *o;
+ /* for reading/writing */
+ GIOStream *io;
/* for reading */
GInputStream *i;
+ /* for writing */
+ GOutputStream *o;
+
+
/* Before using mmap we'll use GIO's infrastructure for monitoring
* the file for changes, this should also be more portable. This is
* used for for cooperated sharing of a buffer file
@@ -687,10 +691,12 @@ gegl_tile_backend_file_finalize (GObject *object)
GEGL_NOTE (GEGL_DEBUG_TILE_BACKEND, "finalizing buffer %s", self->path);
#if HAVE_GIO
- if (self->i)
- g_object_unref (self->i);
- if (self->o)
- g_object_unref (self->o);
+ if (self->io)
+ {
+ g_io_stream_close (self->io, NULL, NULL);
+ g_object_unref (self->io);
+ self->io = NULL;
+ }
if (self->file)
g_file_delete (self->file, NULL, NULL);
@@ -886,6 +892,7 @@ gegl_tile_backend_file_constructor (GType type,
#endif
self->index = g_hash_table_new (gegl_tile_backend_file_hashfunc, gegl_tile_backend_file_equalfunc);
+
/* If the file already exists open it, assuming it is a GeglBuffer. */
#if HAVE_GIO
if (g_file_query_exists (self->file, NULL))
@@ -905,19 +912,19 @@ gegl_tile_backend_file_constructor (GType type,
G_CALLBACK (gegl_tile_backend_file_file_changed),
self);
-#ifndef HACKED_GIO_WITH_READWRITE
- g_error ("not able to open a file readwrite properly with GIO");
-#else
- /* this construct uses a hacked up version of GIO that detects the
- * createflag to be passed as G_FILE_CREATE_READWRITE for the append
- * call on local files, and provides a suitable inputstream as istream
- * data on the object.
- */
- self->o = G_OUTPUT_STREAM (g_file_append_to (self->file,
- G_FILE_CREATE_READWRITE,
- NULL, NULL));
- self->i = g_object_get_data (G_OBJECT (self->o), "istream");
-#endif
+ {
+ GError *error = NULL;
+ self->io = G_IO_STREAM (g_file_open_readwrite (self->file, NULL, &error));
+ if (error)
+ {
+ g_warning ("%s: %s", G_STRLOC, error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+ self->o = g_io_stream_get_output_stream (self->io);
+ self->i = g_io_stream_get_input_stream (self->io);
+ }
+
#else
self->o = open (self->path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
self->i = dup (self->o);
@@ -967,30 +974,35 @@ gegl_tile_backend_file_ensure_exist (GeglTileBackendFile *self)
if (!self->exist)
{
GeglTileBackend *backend;
+ GError *error = NULL;
self->exist = TRUE;
+
+ if (self->io)
+ {
+ g_print ("we already existed\n");
+ return;
+ }
+
backend = GEGL_TILE_BACKEND (self);
GEGL_NOTE (GEGL_DEBUG_TILE_BACKEND, "creating swapfile %s", self->path);
-#ifdef HACKED_GIO_WITH_READWRITE
-
- self->o = G_OUTPUT_STREAM (g_file_append_to (self->file,
- G_FILE_CREATE_READWRITE,
- NULL, NULL));
- gegl_buffer_header_init (&self->header,
- backend->tile_width,
- backend->tile_height,
- backend->px_size,
- backend->format
- );
- gegl_tile_backend_file_write_header (self);
- g_output_stream_flush (self->o, NULL, NULL);
- self->i = g_object_get_data (G_OBJECT (self->o), "istream");
-#else
#if HAVE_GIO
self->o = G_OUTPUT_STREAM (g_file_replace (self->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
g_output_stream_flush (self->o, NULL, NULL);
+ g_output_stream_close (self->o, NULL, NULL);
+
+ self->io = G_IO_STREAM (g_file_open_readwrite (self->file, NULL, &error));
+ if (error)
+ {
+ g_warning ("%s: %s", G_STRLOC, error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+ self->o = g_io_stream_get_output_stream (self->io);
+ self->i = g_io_stream_get_input_stream (self->io);
+
#else
self->o = open (self->path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
#endif
@@ -1015,11 +1027,11 @@ gegl_tile_backend_file_ensure_exist (GeglTileBackendFile *self)
self->i = dup (self->o);
#endif
-#endif
/*self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));*/
self->next_pre_alloc = 256; /* reserved space for header */
self->total = 256; /* reserved space for header */
#if HAVE_GIO
+ g_assert (self->io);
g_assert (self->i);
g_assert (self->o);
#else
@@ -1061,6 +1073,7 @@ gegl_tile_backend_file_init (GeglTileBackendFile *self)
self->path = NULL;
#if HAVE_GIO
self->file = NULL;
+ self->io = NULL;
self->i = NULL;
self->o = NULL;
#else
diff --git a/gegl/buffer/gegl-tile.c b/gegl/buffer/gegl-tile.c
index 3388ad2..2381c9a 100644
--- a/gegl/buffer/gegl-tile.c
+++ b/gegl/buffer/gegl-tile.c
@@ -198,7 +198,6 @@ gegl_tile_lock (GeglTile *tile)
/*fprintf (stderr, "global tile locking: %i %i\n", locks, unlocks);*/
gegl_tile_unclone (tile);
- /*gegl_buffer_add_dirty (tile->buffer, tile->x, tile->y);*/
}
static void
@@ -295,9 +294,6 @@ gegl_tile_swp (GeglTile *a,
gegl_tile_unclone (a);
gegl_tile_unclone (b);
-/* gegl_buffer_add_dirty (a->buffer, a->x, a->y);
- gegl_buffer_add_dirty (b->buffer, b->x, b->y);*/
-
g_assert (a->size == b->size);
tmp = a->data;
diff --git a/gegl/gegl-config.c b/gegl/gegl-config.c
index 74a5365..21db5f4 100644
--- a/gegl/gegl-config.c
+++ b/gegl/gegl-config.c
@@ -220,8 +220,8 @@ gegl_config_init (GeglConfig *self)
self->quality = 1.0;
self->cache_size = 256 * 1024 * 1024;
self->chunk_size = 512 * 512;
- self->tile_width = 64;
- self->tile_height = 128;
+ self->tile_width = 128;
+ self->tile_height = 64;
#if ENABLE_MT
self->threads = 2;
#endif
diff --git a/gegl/property-types/gegl-path.c b/gegl/property-types/gegl-path.c
index 88c8a9a..a187dc5 100644
--- a/gegl/property-types/gegl-path.c
+++ b/gegl/property-types/gegl-path.c
@@ -1355,7 +1355,7 @@ gegl_path_get_node (GeglPath *vector,
static void gegl_path_item_free (GeglPathList *p)
{
InstructionInfo *info = lookup_instruction_info(p->d.type);
- g_slice_free1 (sizeof (gpointer) + sizeof (gchar) + sizeof (gfloat)*2 * (info->n_items+1)/2, p);
+ g_slice_free1 (sizeof (gpointer) + sizeof (gchar) + sizeof (gfloat)*2 * (info->n_items+3)/2, p);
}
void gegl_path_remove_node (GeglPath *vector,
@@ -1406,7 +1406,7 @@ void gegl_path_insert_node (GeglPath *vector,
{
if (count == pos)
{
- GeglPathList *new = g_slice_alloc0 (sizeof (gpointer) + sizeof (gchar) + sizeof (gfloat)*2 *(info->n_items+1)/2);
+ GeglPathList *new = g_slice_alloc0 (sizeof (gpointer) + sizeof (gchar) + sizeof (gfloat)*2 *(info->n_items+3)/2);
new->d.type=knot->type;
copy_data (knot, &new->d);
new->next = iter->next;
@@ -1423,7 +1423,7 @@ void gegl_path_insert_node (GeglPath *vector,
}
if (pos==-1)
{
- GeglPathList *new = g_slice_alloc0 (sizeof (gpointer) + sizeof (gchar) + sizeof (gfloat)*2 *(info->n_items+1)/2);
+ GeglPathList *new = g_slice_alloc0 (sizeof (gpointer) + sizeof (gchar) + sizeof (gfloat)*2 *(info->n_items+3)/2);
new->d.type = knot->type;
copy_data (knot, &new->d);
new->next = NULL;
@@ -2087,7 +2087,8 @@ void gegl_path_stroke (GeglBuffer *buffer,
{
return;
}
- gegl_buffer_lock (buffer);
+ if (gegl_buffer_is_shared (buffer))
+ while (!gegl_buffer_try_lock (buffer));
/*gegl_buffer_clear (buffer, &extent);*/
@@ -2166,7 +2167,8 @@ void gegl_path_stroke (GeglBuffer *buffer,
iter=iter->next;
}
- gegl_buffer_unlock (buffer);
+ if (gegl_buffer_is_shared (buffer))
+ gegl_buffer_unlock (buffer);
}
gint gegl_path_type_get_n_items (gchar type)
diff --git a/operations/common/buffer-source.c b/operations/common/buffer-source.c
index 5f19c5d..6b5b5fe 100644
--- a/operations/common/buffer-source.c
+++ b/operations/common/buffer-source.c
@@ -32,6 +32,14 @@ gegl_chant_object(buffer, _("Input buffer"),
#include "gegl-chant.h"
+static void buffer_changed (GeglBuffer *buffer,
+ const GeglRectangle *rect,
+ gpointer userdata)
+{
+ gegl_operation_invalidate (GEGL_OPERATION (userdata), rect, FALSE);
+}
+
+
static GeglRectangle
get_bounding_box (GeglOperation *operation)
{
@@ -56,6 +64,12 @@ process (GeglOperation *operation,
if (o->buffer)
{
+ if (!o->chant_data)
+ {
+ o->chant_data = (void*)0xf00;
+ g_signal_connect (o->buffer, "changed",
+ G_CALLBACK(buffer_changed), operation);
+ }
g_object_ref (o->buffer); /* Add an extra reference, since
* gegl_operation_set_data is
* stealing one.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]