[gegl] buffer: cache and reuse tile-storages
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: cache and reuse tile-storages
- Date: Fri, 17 Dec 2010 18:31:06 +0000 (UTC)
commit f2bbd06f50959b0bff47b7348727c93962b0f9f0
Author: �yvind Kolås <pippin gimp org>
Date: Fri Dec 17 17:36:24 2010 +0000
buffer: cache and reuse tile-storages
gegl/buffer/gegl-buffer.c | 134 ++++++++++++++++++++++++++++++---------
gegl/buffer/gegl-tile-handler.c | 8 ++-
gegl/gegl-init.c | 2 +
3 files changed, 113 insertions(+), 31 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer.c b/gegl/buffer/gegl-buffer.c
index 89baa16..fef5cbf 100644
--- a/gegl/buffer/gegl-buffer.c
+++ b/gegl/buffer/gegl-buffer.c
@@ -1037,6 +1037,110 @@ gegl_buffer_destroy (GeglBuffer *buffer)
g_object_unref (buffer);
}
+typedef struct TileStorageCacheItem {
+ GeglTileStorage *storage;
+ gboolean ram;
+ gint tile_width;
+ gint tile_height;
+ const void *babl_fmt;
+} TileStorageCacheItem;
+
+static GStaticMutex storage_cache_mutex = G_STATIC_MUTEX_INIT;
+static GSList *storage_cache = NULL;
+
+/* returns TRUE if it could be done */
+gboolean gegl_tile_storage_cached_release (GeglTileStorage *storage);
+gboolean gegl_tile_storage_cached_release (GeglTileStorage *storage)
+{
+ TileStorageCacheItem *item = g_object_get_data (G_OBJECT (storage), "storage-cache-item");
+
+ if (!item)
+ return FALSE;
+ g_static_mutex_lock (&storage_cache_mutex);
+ storage_cache = g_slist_prepend (storage_cache, item);
+ g_static_mutex_unlock (&storage_cache_mutex);
+ return TRUE;
+}
+
+void gegl_tile_storage_cache_cleanup (void);
+void gegl_tile_storage_cache_cleanup (void)
+{
+ g_static_mutex_lock (&storage_cache_mutex);
+ for (;storage_cache; storage_cache = g_slist_remove (storage_cache, storage_cache->data))
+ {
+ TileStorageCacheItem *item = storage_cache->data;
+ g_object_unref (item->storage);
+ }
+ g_static_mutex_unlock (&storage_cache_mutex);
+}
+
+static GeglTileStorage *
+gegl_tile_storage_new_cached (gint tile_width, gint tile_height,
+ const void *babl_fmt, gboolean use_ram)
+{
+ GeglTileStorage *storage = NULL;
+ GSList *iter;
+ g_static_mutex_lock (&storage_cache_mutex);
+ for (iter = storage_cache; iter; iter = iter->next)
+ {
+ TileStorageCacheItem *item = iter->data;
+ if (item->babl_fmt == babl_fmt &&
+ item->tile_width == tile_width &&
+ item->tile_height == tile_height &&
+ item->ram == item->ram)
+ {
+ storage = item->storage;
+ storage_cache = g_slist_remove (storage_cache, item);
+ break;
+ }
+ }
+
+ if (!storage)
+ {
+ TileStorageCacheItem *item = g_new0 (TileStorageCacheItem, 1);
+
+ item->tile_width = tile_width;
+ item->tile_height = tile_height;
+ item->babl_fmt = babl_fmt;
+
+ if (use_ram ||
+ !gegl_config()->swap ||
+ g_str_equal (gegl_config()->swap, "RAM") ||
+ g_str_equal (gegl_config()->swap, "ram"))
+ {
+ item->ram = TRUE;
+ storage = gegl_tile_storage_new (tile_width, tile_height, babl_fmt, NULL);
+ }
+ else
+ {
+ static gint no = 1;
+
+ gchar *filename;
+ gchar *path;
+ item->ram = FALSE;
+
+#if 0
+ filename = g_strdup_printf ("GEGL-%i-%s-%i.swap",
+ getpid (),
+ babl_name ((Babl *) babl_fmt),
+ no++);
+#endif
+
+ filename = g_strdup_printf ("%i-%i", getpid(), no);
+ g_atomic_int_inc (&no);
+ path = g_build_filename (gegl_config()->swap, filename, NULL);
+ g_free (filename);
+
+ storage = gegl_tile_storage_new (tile_width, tile_height, babl_fmt, path);
+ g_free (path);
+ }
+ item->storage = storage;
+ g_object_set_data_full (G_OBJECT (storage), "storage-cache-item", item, g_free);
+ }
+
+ g_static_mutex_unlock (&storage_cache_mutex);
+ return storage;
+}
static GeglBuffer *
gegl_buffer_new_from_format (const void *babl_fmt,
@@ -1051,35 +1155,7 @@ gegl_buffer_new_from_format (const void *babl_fmt,
GeglTileStorage *tile_storage;
GeglBuffer *buffer;
- if (use_ram ||
- !gegl_config()->swap ||
- g_str_equal (gegl_config()->swap, "RAM") ||
- g_str_equal (gegl_config()->swap, "ram"))
- {
- tile_storage = gegl_tile_storage_new (tile_width, tile_height, babl_fmt, NULL);
- }
- else
- {
- static gint no = 1;
-
- gchar *filename;
- gchar *path;
-
-#if 0
- filename = g_strdup_printf ("GEGL-%i-%s-%i.swap",
- getpid (),
- babl_name ((Babl *) babl_fmt),
- no++);
-#endif
-
- filename = g_strdup_printf ("%i-%i", getpid(), no);
- g_atomic_int_inc (&no);
- path = g_build_filename (gegl_config()->swap, filename, NULL);
- g_free (filename);
-
- tile_storage = gegl_tile_storage_new (tile_width, tile_height, babl_fmt, path);
- g_free (path);
- }
+ tile_storage = gegl_tile_storage_new_cached (tile_width, tile_height, babl_fmt, use_ram);
buffer = g_object_new (GEGL_TYPE_BUFFER,
"source", tile_storage,
diff --git a/gegl/buffer/gegl-tile-handler.c b/gegl/buffer/gegl-tile-handler.c
index 888e2d2..e2b0642 100644
--- a/gegl/buffer/gegl-tile-handler.c
+++ b/gegl/buffer/gegl-tile-handler.c
@@ -25,7 +25,7 @@
#include "gegl-tile-source.h"
#include "gegl-tile-handler.h"
#include "gegl-tile-handler-chain.h"
-
+#include "gegl-tile-storage.h"
G_DEFINE_TYPE (GeglTileHandler, gegl_tile_handler, GEGL_TYPE_TILE_SOURCE)
@@ -35,6 +35,8 @@ enum
PROP_SOURCE
};
+gboolean gegl_tile_storage_cached_release (GeglTileStorage *storage);
+
static void
gegl_tile_handler_dispose (GObject *object)
{
@@ -42,7 +44,9 @@ gegl_tile_handler_dispose (GObject *object)
if (handler->source != NULL)
{
- g_object_unref (handler->source);
+ if (!(GEGL_IS_TILE_STORAGE (handler->source) &&
+ gegl_tile_storage_cached_release ((void*)handler->source)))
+ g_object_unref (handler->source);
handler->source = NULL;
}
diff --git a/gegl/gegl-init.c b/gegl/gegl-init.c
index 93a34f4..be718b4 100644
--- a/gegl/gegl-init.c
+++ b/gegl/gegl-init.c
@@ -342,12 +342,14 @@ static void swap_clean (void)
}
}
+void gegl_tile_storage_cache_cleanup (void);
void
gegl_exit (void)
{
glong timing = gegl_ticks ();
+ gegl_tile_storage_cache_cleanup ();
gegl_tile_cache_destroy ();
gegl_operation_gtype_cleanup ();
gegl_extension_handler_cleanup ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]