gegl r2178 - in trunk: . gegl gegl/buffer
- From: ok svn gnome org
- To: svn-commits-list gnome org
- Subject: gegl r2178 - in trunk: . gegl gegl/buffer
- Date: Wed, 16 Apr 2008 21:24:58 +0100 (BST)
Author: ok
Date: Wed Apr 16 21:24:57 2008
New Revision: 2178
URL: http://svn.gnome.org/viewvc/gegl?rev=2178&view=rev
Log:
Made the tile caching in GeglBuffer work more correctly, earlier
completely fresh tiles as well as generated zoom tiles needed to
be written to backend/swap before being re-read into the cache.
Now the code uses a global queue for the tile cache, this can later
be changed to properly gauge the amount of memory used by the cache
(shared data should be taken into account then).
* gegl/buffer/gegl-buffer-load.c:
* gegl/buffer/gegl-buffer-save.c: fixed includes.
* gegl/buffer/gegl-buffer-private.h: makde GeglBuffer be a subclass
of GeglHandler not GeglHandlers.
* gegl/buffer/gegl-buffer.c: do not create buffers via gegl-allocator
but create a new storage for each toplevel buffer.
* gegl/buffer/gegl-handler-cache.[ch]: made all tile caches share a
global queue.
* gegl/buffer/gegl-handler-zoom.c: (get_tile):
* gegl/buffer/gegl-handler-empty.c: (get_tile): add capability to add
newly created tiles to the relevant tile cache. (for now the cache
is fetched via g_object_get_data (empty. "cache")
* gegl/buffer/gegl-storage.c: (gegl_storage_constructor): set cache
data on empty and zoom handlers.
* gegl/buffer/gegl-tile.c: (gegl_tile_void): set storage to NULL so
that a voided tile will not be written to storage.
* gegl/gegl-init.c: (gegl_exit): call gegl_tile_cache_destroy to
destroy the global cache queue upon GEGL shutdown.
* gegl/buffer/gegl-buffer-allocator.c: removed
* gegl/buffer/gegl-buffer-allocator.h: removed
* gegl/buffer/Makefile.am: removed reference to
gegl-buffer-allocator.*
Removed:
trunk/gegl/buffer/gegl-buffer-allocator.c
trunk/gegl/buffer/gegl-buffer-allocator.h
Modified:
trunk/ChangeLog
trunk/gegl/buffer/Makefile.am
trunk/gegl/buffer/gegl-buffer-load.c
trunk/gegl/buffer/gegl-buffer-private.h
trunk/gegl/buffer/gegl-buffer-save.c
trunk/gegl/buffer/gegl-buffer.c
trunk/gegl/buffer/gegl-handler-cache.c
trunk/gegl/buffer/gegl-handler-cache.h
trunk/gegl/buffer/gegl-handler-empty.c
trunk/gegl/buffer/gegl-handler-zoom.c
trunk/gegl/buffer/gegl-storage.c
trunk/gegl/buffer/gegl-tile.c
trunk/gegl/gegl-init.c
Modified: trunk/gegl/buffer/Makefile.am
==============================================================================
--- trunk/gegl/buffer/Makefile.am (original)
+++ trunk/gegl/buffer/Makefile.am Wed Apr 16 21:24:57 2008
@@ -1,7 +1,6 @@
noinst_LTLIBRARIES = libbuffer.la
BUFFER_sources = \
- gegl-buffer-allocator.c \
gegl-buffer-save.c \
gegl-buffer-load.c \
gegl-buffer.c \
@@ -28,7 +27,6 @@
gegl-source.c
BUFFER_headers = \
- gegl-buffer-allocator.h \
gegl-buffer.h \
gegl-buffer-private.h \
gegl-buffer-save.h \
Modified: trunk/gegl/buffer/gegl-buffer-load.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-load.c (original)
+++ trunk/gegl/buffer/gegl-buffer-load.c Wed Apr 16 21:24:57 2008
@@ -45,7 +45,6 @@
#include "gegl-handler-cache.h"
#include "gegl-handler-log.h"
#include "gegl-handler-empty.h"
-#include "gegl-buffer-allocator.h"
#include "gegl-types.h"
#include "gegl-utils.h"
#include "gegl-buffer-save.h"
Modified: trunk/gegl/buffer/gegl-buffer-private.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-private.h (original)
+++ trunk/gegl/buffer/gegl-buffer-private.h Wed Apr 16 21:24:57 2008
@@ -20,7 +20,7 @@
#define __GEGL_BUFFER_PRIVATE_H__
#include "gegl-buffer.h"
-#include "gegl-handlers.h"
+#include "gegl-handler.h"
#define GEGL_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEGL_TYPE_BUFFER, GeglBufferClass))
#define GEGL_IS_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_BUFFER))
@@ -29,7 +29,7 @@
struct _GeglBuffer
{
- GeglHandlers parent_instance; /* which is a GeglHandler which has a
+ GeglHandler parent_instance; /* which is a GeglHandler which has a
source field which is used for chaining
sub buffers with their anchestors */
@@ -62,7 +62,7 @@
struct _GeglBufferClass
{
- GeglHandlersClass parent_class;
+ GeglHandlerClass parent_class;
};
@@ -83,4 +83,9 @@
const gchar * gegl_swap_dir (void);
+
+void gegl_tile_cache_init (void);
+
+void gegl_tile_cache_destroy (void);
+
#endif
Modified: trunk/gegl/buffer/gegl-buffer-save.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-save.c (original)
+++ trunk/gegl/buffer/gegl-buffer-save.c Wed Apr 16 21:24:57 2008
@@ -43,6 +43,7 @@
#include "gegl-buffer-types.h"
#include "gegl-buffer.h"
+#include "gegl-buffer-private.h"
#include "gegl-storage.h"
#include "gegl-tile-backend.h"
#include "gegl-handler.h"
@@ -50,7 +51,6 @@
#include "gegl-handler-cache.h"
#include "gegl-handler-log.h"
#include "gegl-handler-empty.h"
-#include "gegl-buffer-allocator.h"
#include "gegl-types.h"
#include "gegl-utils.h"
#include "gegl-buffer-save.h"
Modified: trunk/gegl/buffer/gegl-buffer.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer.c (original)
+++ trunk/gegl/buffer/gegl-buffer.c Wed Apr 16 21:24:57 2008
@@ -20,22 +20,40 @@
#include <math.h>
#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef G_OS_WIN32
+#include <process.h>
+#define getpid() _getpid()
+#endif
#include <glib-object.h>
+#include <glib/gstdio.h>
+#include <glib/gprintf.h>
#include "gegl-types.h"
#include "gegl-buffer-types.h"
#include "gegl-buffer.h"
-#include "gegl-buffer-allocator.h"
+#include "gegl-buffer-private.h"
+#include "gegl-handler.h"
#include "gegl-storage.h"
#include "gegl-tile-backend.h"
-#include "gegl-handler.h"
#include "gegl-tile.h"
#include "gegl-handler-cache.h"
#include "gegl-handler-log.h"
#include "gegl-handler-empty.h"
-#include "gegl-buffer-allocator.h"
#include "gegl-sampler-nearest.h"
#include "gegl-sampler-linear.h"
#include "gegl-sampler-cubic.h"
@@ -44,7 +62,7 @@
#include "gegl-id-pool.h"
-G_DEFINE_TYPE (GeglBuffer, gegl_buffer, GEGL_TYPE_HANDLERS)
+G_DEFINE_TYPE (GeglBuffer, gegl_buffer, GEGL_TYPE_HANDLER)
#if ENABLE_MP
GStaticRecMutex mutex = G_STATIC_REC_MUTEX_INIT;
@@ -70,6 +88,11 @@
PROP_PIXELS
};
+static GeglBuffer * gegl_buffer_new_from_format (const void *babl_format,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
static inline gint needed_tiles (gint w,
gint stride)
@@ -234,10 +257,11 @@
gegl_buffer_sample_cleanup (buffer);
if (handler->source &&
- GEGL_IS_BUFFER_ALLOCATOR (handler->source))
+ GEGL_IS_STORAGE (handler->source))
{
gegl_buffer_void (buffer);
#if 0
+ g_object_unref (handler->source);
handler->source = NULL; /* this might be a dangerous way of marking that we have already voided */
#endif
}
@@ -297,7 +321,6 @@
{
GObject *object;
GeglBuffer *buffer;
- GeglHandlers *handlers;
GeglTileBackend *backend;
GeglHandler *handler;
GeglSource *source;
@@ -307,7 +330,6 @@
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
buffer = GEGL_BUFFER (object);
- handlers = GEGL_HANDLERS (object);
handler = GEGL_HANDLER (object);
source = handler->source;
backend = gegl_buffer_backend (buffer);
@@ -330,10 +352,10 @@
g_assert (buffer->format);
source = GEGL_SOURCE (gegl_buffer_new_from_format (buffer->format,
- buffer->extent.x,
- buffer->extent.y,
- buffer->extent.width,
- buffer->extent.height));
+ buffer->extent.x,
+ buffer->extent.y,
+ buffer->extent.width,
+ buffer->extent.height));
/* after construction,. x and y should be set to reflect
* the top level behavior exhibited by this buffer object.
*/
@@ -441,66 +463,47 @@
buffer->storage = gegl_buffer_storage (buffer);
- if (0) gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_EMPTY,
- "backend", backend,
- NULL));
-
- /* add a full width (should probably add height as well) sized cache for
- * this gegl_buffer only if the width is < 16384. The huge buffers used
- * by the allocator are thus not affected, but all other buffers should
- * have a enough tiles to be scanline iteratable.
- */
-
- if (0 && buffer->extent.width < 1 << 14)
- gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_CACHE,
- "size",
- needed_tiles (buffer->extent.width, tile_width) + 1,
- NULL));
-
return object;
}
static GeglTile *
-get_tile (GeglSource *buffer,
+get_tile (GeglSource *source,
gint x,
gint y,
gint z)
{
- GeglHandlers *handlers = (GeglHandlers*)(buffer);
- GeglSource *source = ((GeglHandler*)buffer)->source;
- GeglTile *tile = NULL;
-
- if (handlers->chain != NULL)
- tile = gegl_source_get_tile ((GeglSource*)(handlers->chain->data),
- x, y, z);
- else if (source)
+ GeglHandler *handler = GEGL_HANDLER (source);
+ GeglTile *tile = NULL;
+ source = handler->source;
+
+ if (source)
tile = gegl_source_get_tile (source, x, y, z);
else
g_assert (0);
if (tile)
{
- GeglBuffer *buf = (GeglBuffer*)(buffer);
+ GeglBuffer *buffer = GEGL_BUFFER (handler);
tile->x = x;
tile->y = y;
tile->z = z;
- if (x < buf->min_x)
- buf->min_x = x;
- if (y < buf->min_y)
- buf->min_y = y;
- if (x > buf->max_x)
- buf->max_x = x;
- if (y > buf->max_y)
- buf->max_y = y;
- if (z > buf->max_z)
- buf->max_z = z;
+ if (x < buffer->min_x)
+ buffer->min_x = x;
+ if (y < buffer->min_y)
+ buffer->min_y = y;
+ if (x > buffer->max_x)
+ buffer->max_x = x;
+ if (y > buffer->max_y)
+ buffer->max_y = y;
+ if (z > buffer->max_z)
+ buffer->max_z = z;
/* storing information in tile, to enable the dispose function of the
* tile instance to "hook" back to the storage with correct coordinates.
*/
{
- tile->storage = buf->storage;
+ tile->storage = buffer->storage;
tile->storage_x = x;
tile->storage_y = y;
tile->storage_z = z;
@@ -512,16 +515,21 @@
static gpointer
-command (GeglSource *buffer,
+command (GeglSource *source,
GeglTileCommand command,
gint x,
gint y,
gint z,
gpointer data)
{
- if (command == GEGL_TILE_GET)
- return get_tile (buffer, x, y, z);
- return gegl_handler_chain_up (GEGL_HANDLER(buffer), command, x, y, z, data);
+ GeglHandler *handler = GEGL_HANDLER (source);
+ switch (command)
+ {
+ case GEGL_TILE_GET:
+ return get_tile (source, x, y, z);
+ default:
+ return gegl_handler_chain_up (handler, command, x, y, z, data);
+ }
}
static void
@@ -692,12 +700,6 @@
}
}
-
-/*
- * babl conversion should probably be done on a tile by tile, or even scanline by
- * scanline basis instead of allocating large temporary buffers. (using babl for "memcpy")
- */
-
#ifdef BABL
#undef BABL
#endif
@@ -749,9 +751,9 @@
gint tiledx = buffer_x + buffer->shift_x + x;
GeglTile *tile = gegl_source_get_tile ((GeglSource *) (buffer),
- gegl_tile_indice (tiledx, tile_width),
- gegl_tile_indice (tiledy, tile_height),
- 0);
+ gegl_tile_indice (tiledx, tile_width),
+ gegl_tile_indice (tiledy, tile_height),
+ 0);
if (tile)
{
@@ -1937,7 +1939,6 @@
return id;
}
-#include <glib/gprintf.h>
void
gegl_buffer_make_uri (gchar *buf_128,
@@ -2004,3 +2005,95 @@
g_warning ("don't know how to handle buffer path: %s", uri);
return NULL;
}
+
+
+
+static GeglBuffer *
+gegl_buffer_new_from_format (const void *babl_format,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GeglStorage *storage;
+ GeglBuffer *buffer;
+ gchar *filename;
+ gchar *path;
+ static gint no=1;
+
+ filename = g_strdup_printf ("GEGL-%i-%s-%i.swap",
+ getpid (),
+ babl_name ((Babl *) babl_format),
+ no++);
+
+ filename = g_strdup_printf ("%i-%i", getpid(), no++);
+
+ path = g_build_filename (gegl_swap_dir (), filename, NULL);
+ g_free (filename);
+
+ if (gegl_swap_dir ())
+ {
+ storage = g_object_new (GEGL_TYPE_STORAGE,
+ "format", babl_format,
+ "path", path,
+ NULL);
+ }
+ else
+ {
+ storage = g_object_new (GEGL_TYPE_STORAGE,
+ "format", babl_format,
+ NULL);
+ }
+ buffer = g_object_new (GEGL_TYPE_BUFFER,
+ "source", storage,
+ "x", x,
+ "y", y,
+ "width", width,
+ "height", height,
+ NULL);
+
+ g_object_unref (storage);
+ return buffer;
+}
+
+
+/* if this function is made to return NULL swapping is disabled */
+const gchar *
+gegl_swap_dir (void)
+{
+ static gchar *swapdir = "";
+
+ if (swapdir && swapdir[0] == '\0')
+ {
+ if (g_getenv ("GEGL_SWAP"))
+ {
+ if (g_str_equal (g_getenv ("GEGL_SWAP"), "RAM"))
+ swapdir = NULL;
+ else
+ swapdir = g_strdup (g_getenv ("GEGL_SWAP"));
+ }
+ else
+ {
+ swapdir = g_build_filename (g_get_home_dir(),
+ "." GEGL_LIBRARY,
+ "swap",
+ NULL);
+ }
+
+ /* Fall back to "swapping to RAM" if not able to create swap dir
+ */
+ if (swapdir &&
+ ! g_file_test (swapdir, G_FILE_TEST_IS_DIR) &&
+ g_mkdir_with_parents (swapdir, S_IRUSR | S_IWUSR | S_IXUSR) != 0)
+ {
+ gchar *name = g_filename_display_name (swapdir);
+
+ g_warning ("unable to create swapdir '%s': %s",
+ name, g_strerror (errno));
+ g_free (name);
+
+ swapdir = NULL;
+ }
+ }
+ return swapdir;
+};
Modified: trunk/gegl/buffer/gegl-handler-cache.c
==============================================================================
--- trunk/gegl/buffer/gegl-handler-cache.c (original)
+++ trunk/gegl/buffer/gegl-handler-cache.c Wed Apr 16 21:24:57 2008
@@ -23,9 +23,30 @@
#include "../gegl-types.h"
#include "gegl-buffer.h"
+#include "gegl-buffer-private.h"
#include "gegl-tile.h"
#include "gegl-handler-cache.h"
+/* FIXME: this global cache should have configurable size and wash percentage */
+
+static GQueue *cache_queue = NULL;
+static gint cache_size = 512;
+static gint cache_wash_percentage = 20;
+static gint cache_hits = 0;
+static gint cache_misses = 0;
+
+void gegl_tile_cache_init (void)
+{
+ if (cache_queue == NULL)
+ cache_queue = g_queue_new ();
+}
+
+void gegl_tile_cache_destroy (void)
+{
+ if (cache_queue)
+ g_queue_free (cache_queue);
+ cache_queue = NULL;
+}
static gboolean gegl_handler_cache_wash (GeglHandlerCache *cache);
@@ -38,7 +59,7 @@
gint x,
gint y,
gint z);
-static void gegl_handler_cache_insert (GeglHandlerCache *cache,
+ void gegl_handler_cache_insert (GeglHandlerCache *cache,
GeglTile *tile,
gint x,
gint y,
@@ -50,27 +71,23 @@
G_DEFINE_TYPE (GeglHandlerCache, gegl_handler_cache, GEGL_TYPE_HANDLER)
-enum
-{
- PROP_0,
- PROP_SIZE,
- PROP_WASH_PERCENTAGE
-};
-
typedef struct CacheItem
{
+ GeglHandlerCache *handler; /* identify the handler as well, thus allowing
+ * all buffers to share a common cache
+ */
GeglTile *tile;
gint x;
gint y;
gint z;
} CacheItem;
+
static void
finalize (GObject *object)
{
- GeglHandlerCache *cache = (GeglHandlerCache *) object;
-
- g_queue_free (cache->queue);
+ GeglHandlerCache *cache;
+ cache = (GeglHandlerCache *) object;
G_OBJECT_CLASS (gegl_handler_cache_parent_class)->finalize (object);
}
@@ -78,40 +95,45 @@
static void
dispose (GObject *object)
{
- GeglHandlerCache *cache = (GeglHandlerCache *) object;
+ GeglHandlerCache *cache;
CacheItem *item;
+ cache = (GeglHandlerCache *) object;
if (0)
g_printerr ("Disposing tile-cache of size %i, hits: %i misses: %i hit percentage:%f)\n",
- cache->size, cache->hits, cache->misses,
- cache->hits * 100.0 / (cache->hits + cache->misses));
+ cache_size, cache_hits, cache_misses,
+ cache_hits * 100.0 / (cache_hits + cache_misses));
- while ((item = g_queue_pop_head (cache->queue)))
+ /* FIXME: only throw out this cache's items */
+ while ((item = g_queue_pop_head (cache_queue)))
{
g_object_unref (item->tile);
g_slice_free (CacheItem, item);
}
+ /* FIXME: if queue is empty destroy global queue */
G_OBJECT_CLASS (gegl_handler_cache_parent_class)->dispose (object);
}
static GeglTile *
get_tile (GeglSource *tile_store,
- gint x,
- gint y,
- gint z)
+ gint x,
+ gint y,
+ gint z)
{
GeglHandlerCache *cache = GEGL_HANDLER_CACHE (tile_store);
- GeglSource *source = GEGL_HANDLER (tile_store)->source;
+ GeglSource *source = GEGL_HANDLER (tile_store)->source;
GeglTile *tile = NULL;
+ if(0)g_print ("%f%% hit:%i miss:%i \r", cache_hits*100.0/(cache_hits+cache_misses), cache_hits, cache_misses);
+
tile = gegl_handler_cache_get_tile (cache, x, y, z);
if (tile)
{
- cache->hits++;
+ cache_hits++;
return tile;
}
- cache->misses++;
+ cache_misses++;
if (source)
tile = gegl_source_get_tile (source, x, y, z);
@@ -135,86 +157,33 @@
GeglHandlerCache *cache = GEGL_HANDLER_CACHE (handler);
/* FIXME: replace with switch */
-
- if (command == GEGL_TILE_GET)
- {
- return get_tile (tile_store, x, y, z);
- }
-
- if (command == GEGL_TILE_IS_CACHED)
- {
- return (gpointer)gegl_handler_cache_has_tile (cache, x, y, z);
- }
- if (command == GEGL_TILE_EXIST)
- {
- gboolean is_cached = gegl_handler_cache_has_tile (cache, x, y, z);
- if (is_cached)
- return (gpointer)TRUE; /* XXX: perhaps we could return an integer/pointer
- * value over the bus instead of a boolean?
- */
- /* otherwise pass on the request */
- }
-
- if (command == GEGL_TILE_IDLE)
- {
- gboolean action = gegl_handler_cache_wash (cache);
- if (action)
- return (gpointer)action;
- }
- if (command == GEGL_TILE_VOID)
- {
- gegl_handler_cache_void (cache, x, y, z);
- return NULL;
- }
- return gegl_handler_chain_up (handler, command, x, y, z, data);
-}
-
-static void
-get_property (GObject *gobject,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GeglHandlerCache *cache = GEGL_HANDLER_CACHE (gobject);
-
- switch (property_id)
- {
- case PROP_SIZE:
- g_value_set_int (value, cache->size);
- break;
-
- case PROP_WASH_PERCENTAGE:
- g_value_set_int (value, cache->wash_percentage);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
- break;
- }
-}
-
-static void
-set_property (GObject *gobject,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GeglHandlerCache *cache = GEGL_HANDLER_CACHE (gobject);
-
- switch (property_id)
+ switch (command)
{
- case PROP_SIZE:
- cache->size = g_value_get_int (value);
- return;
-
- case PROP_WASH_PERCENTAGE:
- cache->wash_percentage = g_value_get_int (value);
- return;
-
+ case GEGL_TILE_GET:
+ return get_tile (tile_store, x, y, z);
+ case GEGL_TILE_IS_CACHED:
+ return (gpointer)gegl_handler_cache_has_tile (cache, x, y, z);
+ case GEGL_TILE_EXIST:
+ {
+ gboolean exist = gegl_handler_cache_has_tile (cache, x, y, z);
+ if (exist)
+ return (gpointer)TRUE;
+ }
+ break; /* chain up */
+ case GEGL_TILE_IDLE:
+ {
+ gboolean action = gegl_handler_cache_wash (cache);
+ if (action)
+ return (gpointer)action;
+ break;
+ }
+ case GEGL_TILE_VOID:
+ gegl_handler_cache_void (cache, x, y, z);
+ /* fallthrough */
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
break;
}
+ return gegl_handler_chain_up (handler, command, x, y, z, data);
}
static void
@@ -223,37 +192,18 @@
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
GeglSourceClass *source_class = GEGL_SOURCE_CLASS (class);
- gobject_class->set_property = set_property;
- gobject_class->get_property = get_property;
gobject_class->finalize = finalize;
gobject_class->dispose = dispose;
source_class->command = command;
-
- g_object_class_install_property (gobject_class, PROP_SIZE,
- g_param_spec_int ("size",
- "size",
- "Number of tiles in cache",
- 0, G_MAXINT, 32,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (gobject_class, PROP_WASH_PERCENTAGE,
- g_param_spec_int ("wash-percentage",
- "wash percentage",
- "(integer 0..100, percentage to wash)",
- 0, 100, 20,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
}
static void
gegl_handler_cache_init (GeglHandlerCache *cache)
{
- cache->queue = g_queue_new ();
+ gegl_tile_cache_init ();
}
-
/* write the least recently used dirty tile to disk if it
* is in the wash_percentage (20%) least recently used tiles,
* calling this function in an idle handler distributes the
@@ -264,10 +214,10 @@
{
GeglTile *last_dirty = NULL;
guint count = 0;
- gint wash_tiles = cache->wash_percentage * cache->size / 100;
+ gint wash_tiles = cache_wash_percentage * cache_size / 100;
GList *link;
- for (link = g_queue_peek_head_link (cache->queue); link; link = link->next)
+ for (link = g_queue_peek_head_link (cache_queue); link; link = link->next)
{
CacheItem *item = link->data;
GeglTile *tile = item->tile;
@@ -275,7 +225,7 @@
count++;
if (!gegl_tile_is_stored (tile))
{
- if (count > cache->size - wash_tiles)
+ if (count > cache_size - wash_tiles)
{
last_dirty = tile;
}
@@ -300,12 +250,13 @@
{
GList *link;
- for (link = g_queue_peek_head_link (cache->queue); link; link = link->next)
+ for (link = g_queue_peek_head_link (cache_queue); link; link = link->next)
{
CacheItem *item = link->data;
GeglTile *tile = item->tile;
if (tile != NULL &&
+ item->handler == cache &&
item->x == x &&
item->y == y &&
item->z == z)
@@ -313,8 +264,8 @@
/* move the link to the front of the queue */
if (link->prev != NULL)
{
- g_queue_unlink (cache->queue, link);
- g_queue_push_head_link (cache->queue, link);
+ g_queue_unlink (cache_queue, link);
+ g_queue_push_head_link (cache_queue, link);
}
return g_object_ref (tile);
@@ -345,7 +296,7 @@
static gboolean
gegl_handler_cache_trim (GeglHandlerCache *cache)
{
- CacheItem *last_writable = g_queue_pop_tail (cache->queue);
+ CacheItem *last_writable = g_queue_pop_tail (cache_queue);
if (last_writable != NULL)
{
@@ -366,7 +317,7 @@
{
GList *link;
- for (link = g_queue_peek_head_link (cache->queue); link; link = link->next)
+ for (link = g_queue_peek_head_link (cache_queue); link; link = link->next)
{
CacheItem *item = link->data;
GeglTile *tile = item->tile;
@@ -374,12 +325,13 @@
if (tile != NULL &&
item->x == x &&
item->y == y &&
- item->z == z)
+ item->z == z &&
+ item->handler == cache)
{
gegl_tile_void (tile);
g_object_unref (tile);
g_slice_free (CacheItem, item);
- g_queue_delete_link (cache->queue, link);
+ g_queue_delete_link (cache_queue, link);
return;
}
}
@@ -395,18 +347,19 @@
CacheItem *item = g_slice_new (CacheItem);
guint count;
- item->tile = g_object_ref (tile);
- item->x = x;
- item->y = y;
- item->z = z;
+ item->handler = cache;
+ item->tile = g_object_ref (tile);
+ item->x = x;
+ item->y = y;
+ item->z = z;
- g_queue_push_head (cache->queue, item);
+ g_queue_push_head (cache_queue, item);
- count = g_queue_get_length (cache->queue);
+ count = g_queue_get_length (cache_queue);
- if (count > cache->size)
+ if (count > cache_size)
{
- gint to_remove = count - cache->size;
+ gint to_remove = count - cache_size;
while (--to_remove && gegl_handler_cache_trim (cache)) ;
}
Modified: trunk/gegl/buffer/gegl-handler-cache.h
==============================================================================
--- trunk/gegl/buffer/gegl-handler-cache.h (original)
+++ trunk/gegl/buffer/gegl-handler-cache.h Wed Apr 16 21:24:57 2008
@@ -36,11 +36,11 @@
{
GeglHandler parent_instance;
- GQueue *queue;
+/* GQueue *queue;
gint size;
gint wash_percentage;
gint hits;
- gint misses;
+ gint misses;*/
};
struct _GeglHandlerCacheClass
Modified: trunk/gegl/buffer/gegl-handler-empty.c
==============================================================================
--- trunk/gegl/buffer/gegl-handler-empty.c (original)
+++ trunk/gegl/buffer/gegl-handler-empty.c Wed Apr 16 21:24:57 2008
@@ -21,6 +21,7 @@
#include "gegl-handler.h"
#include "gegl-handler-empty.h"
+#include "gegl-handler-cache.h"
G_DEFINE_TYPE (GeglHandlerEmpty, gegl_handler_empty, GEGL_TYPE_HANDLER)
@@ -41,6 +42,12 @@
G_OBJECT_CLASS (gegl_handler_empty_parent_class)->finalize (object);
}
+void gegl_handler_cache_insert (GeglHandlerCache *cache,
+ GeglTile *tile,
+ gint x,
+ gint y,
+ gint z);
+
static GeglTile *
get_tile (GeglSource *gegl_source,
gint x,
@@ -57,6 +64,14 @@
return tile;
tile = gegl_tile_dup (empty->tile);
+ tile->x = x;
+ tile->y = y;
+ tile->z = z;
+ {
+ GeglHandlerCache *cache = g_object_get_data (G_OBJECT (gegl_source), "cache");
+ if (cache)
+ gegl_handler_cache_insert (cache, tile, x, y, z);
+ }
return tile;
}
Modified: trunk/gegl/buffer/gegl-handler-zoom.c
==============================================================================
--- trunk/gegl/buffer/gegl-handler-zoom.c (original)
+++ trunk/gegl/buffer/gegl-handler-zoom.c Wed Apr 16 21:24:57 2008
@@ -21,6 +21,8 @@
#include "gegl-handler.h"
#include "gegl-handler-zoom.h"
+#include "gegl-handler-cache.h"
+
G_DEFINE_TYPE (GeglHandlerZoom, gegl_handler_zoom, GEGL_TYPE_HANDLER)
@@ -34,6 +36,11 @@
#include <babl/babl.h>
#include "gegl-tile-backend.h"
+void gegl_handler_cache_insert (GeglHandlerCache *cache,
+ GeglTile *tile,
+ gint x,
+ gint y,
+ gint z);
static inline void set_blank (GeglTile *dst_tile,
gint width,
gint height,
@@ -296,8 +303,16 @@
tile->y = y;
tile->z = z;
tile->storage = zoom->storage;
- tile->stored_rev = 0;
+ tile->stored_rev = 1;
tile->rev = 1;
+
+ {
+ GeglHandlerCache *cache = g_object_get_data (G_OBJECT (gegl_source), "cache");
+ if (cache)
+ {
+ gegl_handler_cache_insert (cache, tile, x, y, z);
+ }
+ }
}
gegl_tile_lock (tile);
data = gegl_tile_get_data (tile);
Modified: trunk/gegl/buffer/gegl-storage.c
==============================================================================
--- trunk/gegl/buffer/gegl-storage.c (original)
+++ trunk/gegl/buffer/gegl-storage.c Wed Apr 16 21:24:57 2008
@@ -175,6 +175,8 @@
GeglStorage *storage;
GeglHandlers *handlers;
GeglHandler *handler;
+ GeglHandler *empty = NULL;
+ GeglHandler *zoom = NULL;
GeglHandler *cache = NULL;
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
@@ -221,46 +223,31 @@
"px-size", &storage->px_size,
NULL);
+ g_object_unref (handler->source); /* eeek */
+
if (g_getenv("GEGL_LOG_TILE_BACKEND"))
gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_LOG, NULL));
- /* FIXME: the cache should be made shared between all GeglStorages,
- * to get a better gauge of memory use (ideally we would want to make
- * to adapt to an approximate number of bytes to be allocated)
- */
-
- if (1)
- cache = gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_CACHE,
- "size", 128,
- NULL));
- if (g_getenv("GEGL_LOG_TILE_CACHE"))
- gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_LOG, NULL));
-
- if (1) gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_ZOOM,
- "backend", handler->source,
- "storage", storage,
- NULL));
- if (g_getenv("GEGL_LOG_TILE_ZOOM"))
- gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_LOG, NULL));
+ cache = gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_CACHE,
+ NULL));
+ zoom = gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_ZOOM,
+ "backend", handler->source,
+ "storage", storage,
+ NULL));
+ empty = gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_EMPTY,
+ "backend", handler->source,
+ NULL));
- /* moved here to allow sharing between buffers (speeds up, but only
- * allows nulled (transparent) blank tiles, or we would need a separate
- * gegl-storage for each tile.
- */
- if (1) gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_EMPTY,
- "backend", handler->source,
- NULL));
- if (g_getenv("GEGL_LOG_TILE_EMPTY"))
+ if (g_getenv("GEGL_LOG_TILE_CACHE"))
gegl_handlers_add (handlers, g_object_new (GEGL_TYPE_HANDLER_LOG, NULL));
+ g_object_set_data (G_OBJECT (empty), "cache", cache);
+ g_object_set_data (G_OBJECT (zoom), "cache", cache);
- /* it doesn't really matter that empty tiles are not cached, since they
- * are Copy on Write.
- */
storage->idle_swapper = g_timeout_add_full (G_PRIORITY_LOW,
- 500,
+ 250,
storage_idle,
storage,
NULL);
Modified: trunk/gegl/buffer/gegl-tile.c
==============================================================================
--- trunk/gegl/buffer/gegl-tile.c (original)
+++ trunk/gegl/buffer/gegl-tile.c Wed Apr 16 21:24:57 2008
@@ -344,6 +344,7 @@
gegl_tile_void (GeglTile *tile)
{
tile->stored_rev = tile->rev;
+ tile->storage = NULL;
/* FIXME: make sure the tile is evicted from any storage/buffer caches
* as well
*/
Modified: trunk/gegl/gegl-init.c
==============================================================================
--- trunk/gegl/gegl-init.c (original)
+++ trunk/gegl/gegl-init.c Wed Apr 16 21:24:57 2008
@@ -39,8 +39,6 @@
#include "module/geglmodule.h"
#include "module/geglmoduledb.h"
-#include "buffer/gegl-buffer-allocator.h"
-
#include "operation/gegl-operation.h"
#include "operation/gegl-operations.h"
#include "operation/gegl-extension-handler.h"
@@ -141,9 +139,9 @@
{
glong timing = gegl_ticks ();
+ gegl_tile_cache_destroy ();
gegl_operation_gtype_cleanup ();
gegl_extension_handler_cleanup ();
- gegl_buffer_allocators_free ();
if (module_db != NULL)
{
@@ -172,6 +170,7 @@
if (gegl_buffer_leaks ())
g_print (" buffer-leaks: %i", gegl_buffer_leaks ());
+ gegl_tile_cache_destroy ();
if (gegl_swap_dir())
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]