[gegl] buffer: add API for pluggable buffers



commit 3ce74b696162bbd042321eef3dc4496e1cf5807d
Author: �yvind Kolås <pippin gimp org>
Date:   Sun Feb 13 16:36:33 2011 +0000

    buffer: add API for pluggable buffers
    
    Adds an API that allows providing pluggin alternate Tile storage backends in
    GeglBuffer, this allows plugging existing low-level tile-level access APIs i
    backends for GeglBuffer, permitting a low-level of integration with external
    systems wrapping a GIMP, Krita, Blender, open streetmap or other (potentiall
    mip-mapped) tile backends allowing unified access through the GeglBuffer API
    
    This system should ease both migating GIMPs codebase to be more GEGL focused
    even in a transition period where GIMP is not fully migrated to use GEGL.

 gegl/Makefile.am                        |    4 +
 gegl/buffer/gegl-buffer-access.c        |   12 ++--
 gegl/buffer/gegl-buffer-private.h       |   64 +++++++++++++++++
 gegl/buffer/gegl-buffer-types.h         |   29 ++++++--
 gegl/buffer/gegl-buffer.c               |  115 ++++++++++++++++++++++++++-----
 gegl/buffer/gegl-buffer.h               |   15 ++++
 gegl/buffer/gegl-tile-backend-file.c    |   69 ++++++++++++-------
 gegl/buffer/gegl-tile-backend-ram.c     |   23 +++----
 gegl/buffer/gegl-tile-backend-tiledir.c |    8 ++-
 gegl/buffer/gegl-tile-backend.c         |   57 ++++++++++++----
 gegl/buffer/gegl-tile-backend.h         |   31 +++++----
 gegl/buffer/gegl-tile-handler-chain.c   |    2 +
 gegl/buffer/gegl-tile-handler-empty.c   |    9 ++-
 gegl/buffer/gegl-tile-handler-log.c     |    1 +
 gegl/buffer/gegl-tile-handler-zoom.c    |   12 ++-
 gegl/buffer/gegl-tile-handler.c         |    1 +
 gegl/buffer/gegl-tile-source.c          |    1 +
 gegl/buffer/gegl-tile-source.h          |   26 +++++---
 gegl/buffer/gegl-tile-storage.c         |   59 ++++------------
 gegl/buffer/gegl-tile-storage.h         |    6 +-
 gegl/buffer/gegl-tile.c                 |   56 ++++++---------
 gegl/buffer/gegl-tile.h                 |   77 ++-------------------
 22 files changed, 410 insertions(+), 267 deletions(-)
---
diff --git a/gegl/Makefile.am b/gegl/Makefile.am
index bb161df..c9acc5a 100644
--- a/gegl/Makefile.am
+++ b/gegl/Makefile.am
@@ -36,6 +36,10 @@ GEGL_public_HEADERS =	\
     gegl-version.h			\
     buffer/gegl-buffer.h		\
     buffer/gegl-buffer-iterator.h	\
+    buffer/gegl-buffer-backend.h	\
+    buffer/gegl-tile.h			\
+    buffer/gegl-tile-backend.h		\
+    buffer/gegl-tile-source.h		\
     property-types/gegl-paramspecs.h	\
     property-types/gegl-color.h		\
     property-types/gegl-path.h		\
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index 34f70fa..cb5b93b 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -303,12 +303,14 @@ gegl_buffer_flush (GeglBuffer *buffer)
       gegl_tile_unref (buffer->hot_tile);
       buffer->hot_tile = NULL;
     }
-  if ((GeglBufferHeader*)(backend->header))
+
+  if ((GeglBufferHeader*)(backend->priv->header))
     {
-      ((GeglBufferHeader*)(backend->header))->x =buffer->extent.x;
-      ((GeglBufferHeader*)(backend->header))->y =buffer->extent.y;
-      ((GeglBufferHeader*)(backend->header))->width =buffer->extent.width;
-      ((GeglBufferHeader*)(backend->header))->height =buffer->extent.height;
+      GeglBufferHeader* header = backend->priv->header;
+      header->x = buffer->extent.x;
+      header->y = buffer->extent.y;
+      header->width =buffer->extent.width;
+      header->height =buffer->extent.height;
     }
 
   gegl_tile_source_command (GEGL_TILE_SOURCE (buffer),
diff --git a/gegl/buffer/gegl-buffer-private.h b/gegl/buffer/gegl-buffer-private.h
index 33a14e9..dec56e1 100644
--- a/gegl/buffer/gegl-buffer-private.h
+++ b/gegl/buffer/gegl-buffer-private.h
@@ -20,6 +20,7 @@
 #ifndef __GEGL_BUFFER_PRIVATE_H__
 #define __GEGL_BUFFER_PRIVATE_H__
 
+#include "gegl-buffer-types.h"
 #include "gegl-buffer.h"
 #include "gegl-sampler.h"
 #include "gegl-tile-handler.h"
@@ -71,6 +72,8 @@ struct _GeglBuffer
 
   gchar            *alloc_stack_trace; /* Stack trace for allocation,
                                           useful for debugging */
+
+  gpointer          backend;
 };
 
 struct _GeglBufferClass
@@ -130,4 +133,65 @@ void            gegl_buffer_sampler           (GeglBuffer     *buffer,
                                                gpointer        sampler);
 
 
+
+/* the instance size of a GeglTile is a bit large, and should if possible be
+ * trimmed down
+ */
+struct _GeglTile
+{
+ /* GObject          parent_instance;*/
+  gint             ref_count;
+
+  guchar          *data;        /* actual pixel data for tile, a linear buffer*/
+  gint             size;        /* The size of the linear buffer */
+
+  GeglTileStorage *tile_storage; /* the buffer from which this tile was
+                                  * retrieved needed for the tile to be able to
+                                  * store itself back (for instance when it is
+                                  * unreffed for the last time)
+                                  */
+  gint             x, y, z;
+
+
+  guint            rev;         /* this tile revision */
+  guint            stored_rev;  /* what revision was we when we from tile_storage?
+                                   (currently set to 1 when loaded from disk */
+
+  gchar            lock;        /* number of times the tile is write locked
+                                 * should in theory just have the values 0/1
+                                 */
+  GMutex          *mutex;
+
+  /* the shared list is a doubly linked circular list */
+  GeglTile        *next_shared;
+  GeglTile        *prev_shared;
+
+  void (*destroy_notify) (gpointer pixels,
+                          gpointer data);
+  gpointer         destroy_notify_data;
+};
+
+#ifndef __GEGL_TILE_C
+#define gegl_tile_get_data(tile)  ((guchar*)((tile)->data))
+#endif // __GEGL_TILE_C
+
+
+/* computes the positive integer remainder (also for negative dividends)
+ */
+#define GEGL_REMAINDER(dividend, divisor) \
+                   (((dividend) < 0) ? \
+                    (divisor) - 1 - ((-((dividend) + 1)) % (divisor)) : \
+                    (dividend) % (divisor))
+
+#define gegl_tile_offset(coordinate, stride) GEGL_REMAINDER((coordinate), (stride))
+
+/* helper function to compute tile indices and offsets for coordinates
+ * based on a tile stride (tile_width or tile_height)
+ */
+#define gegl_tile_indice(coordinate,stride) \
+  (((coordinate) >= 0)?\
+      (coordinate) / (stride):\
+      ((((coordinate) + 1) /(stride)) - 1))
+
+
 #endif
diff --git a/gegl/buffer/gegl-buffer-types.h b/gegl/buffer/gegl-buffer-types.h
index 3e6d48f..fedfbf4 100644
--- a/gegl/buffer/gegl-buffer-types.h
+++ b/gegl/buffer/gegl-buffer-types.h
@@ -19,16 +19,33 @@
 #ifndef __GEGL_BUFFER_TYPES_H__
 #define __GEGL_BUFFER_TYPES_H__
 
+typedef struct _GeglTileClass             GeglTileClass;
 
+#include "gegl-types.h"
+#include "gegl-buffer-backend.h"
 
-typedef struct _GeglTile                  GeglTile;
-typedef struct _GeglTileClass             GeglTileClass;
 
-typedef struct _GeglTileSource            GeglTileSource;
-typedef struct _GeglTileSourceClass       GeglTileSourceClass;
+/* gegl-buffer-types.h is not installed, thus all of this is private to
+ * GeglBuffer even though some of it leaks among the components of GeglBuffer
+ * here... better than installing it in an installed header at least.
+ */
+
+struct _GeglTileBackendPrivate
+{
+  gint       tile_width;
+  gint       tile_height;
+  Babl      *format;    /* defaults to the babl format "R'G'B'A u8" */
+  gint       px_size;   /* size of a single pixel in bytes */
+  gint       tile_size; /* size of an entire tile in bytes */
+
+  GeglRectangle extent;
+
+  gpointer   header;
+  gpointer   storage;
+  gboolean   shared;
+};
+
 
-typedef struct _GeglTileBackend           GeglTileBackend;
-typedef struct _GeglTileBackendClass      GeglTileBackendClass;
 
 typedef struct _GeglTileHandler           GeglTileHandler;
 typedef struct _GeglTileHandlerClass      GeglTileHandlerClass;
diff --git a/gegl/buffer/gegl-buffer.c b/gegl/buffer/gegl-buffer.c
index 99dfd50..30dca31 100644
--- a/gegl/buffer/gegl-buffer.c
+++ b/gegl/buffer/gegl-buffer.c
@@ -55,6 +55,7 @@
 #include "gegl-tile-storage.h"
 #include "gegl-tile-backend.h"
 #include "gegl-tile-backend-file.h"
+#include "gegl-tile-backend-ram.h"
 #include "gegl-tile.h"
 #include "gegl-tile-handler-cache.h"
 #include "gegl-tile-handler-log.h"
@@ -107,7 +108,8 @@ enum
   PROP_FORMAT,
   PROP_PX_SIZE,
   PROP_PIXELS,
-  PROP_PATH
+  PROP_PATH,
+  PROP_BACKEND
 };
 
 enum {
@@ -199,6 +201,10 @@ gegl_buffer_get_property (GObject    *gobject,
         g_value_set_pointer (value, (void*)buffer->format); /* Eeeek? */
         break;
 
+      case PROP_BACKEND:
+        g_value_set_pointer (value, buffer->backend);
+        break;
+
       case PROP_X:
         g_value_set_int (value, buffer->extent.x);
         break;
@@ -293,6 +299,10 @@ gegl_buffer_set_property (GObject      *gobject,
         if (g_value_get_pointer (value))
           buffer->format = g_value_get_pointer (value);
         break;
+      case PROP_BACKEND:
+        if (g_value_get_pointer (value))
+          buffer->backend = g_value_get_pointer (value);
+        break;
 
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
@@ -317,9 +327,10 @@ gegl_buffer_set_extent (GeglBuffer          *buffer,
   g_return_val_if_fail(GEGL_IS_BUFFER(buffer), FALSE);
    (*(GeglRectangle*)gegl_buffer_get_extent (buffer))=*extent;
 
-  if ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->header))
+  if ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->priv->header))
     {
-      GeglBufferHeader *header = ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->header));
+      GeglBufferHeader *header =
+        ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->priv->header));
       header->x = buffer->extent.x;
       header->y = buffer->extent.y;
       header->width = buffer->extent.width;
@@ -488,7 +499,26 @@ gegl_buffer_constructor (GType                  type,
        * source (this adds a redirection buffer in between for
        * all "allocated from format", type buffers.
        */
-      if (buffer->path && g_str_equal (buffer->path, "RAM"))
+      if (buffer->backend)
+      {
+          void             *storage;
+
+          storage = gegl_tile_storage_new (buffer->backend);
+
+          source = g_object_new (GEGL_TYPE_BUFFER, "source", storage, NULL);
+
+          gegl_tile_handler_set_source ((GeglTileHandler*)(buffer), source);
+          g_object_unref (source);
+
+          g_signal_connect (storage, "changed",
+                            G_CALLBACK(gegl_buffer_storage_changed), buffer);
+
+          g_assert (source);
+          backend = gegl_buffer_backend (GEGL_BUFFER (source));
+          g_assert (backend);
+	  g_assert (backend == buffer->backend);
+	}
+      else if (buffer->path && g_str_equal (buffer->path, "RAM"))
         {
           source = GEGL_TILE_SOURCE (gegl_buffer_new_from_format (buffer->format,
                                                              buffer->extent.x,
@@ -512,10 +542,13 @@ gegl_buffer_constructor (GType                  type,
           GeglBufferHeader *header;
           void             *storage;
 
-          if (buffer->format)
-            storage = gegl_tile_storage_new (-1, -1, buffer->format, buffer->path);
-          else
-            storage = gegl_tile_storage_new (-1, -1, babl_format ("RGBA float"), buffer->path);
+	   backend = g_object_new (GEGL_TYPE_TILE_BACKEND_FILE,
+                                   "tile-width", 128,
+                                   "tile-height", 64,
+                                   "format", buffer->format?buffer->format:babl_format ("RGBA float"),
+                                   "path", buffer->path,
+                                   NULL);
+          storage = gegl_tile_storage_new (backend);
 
           source = g_object_new (GEGL_TYPE_BUFFER, "source", storage, NULL);
 
@@ -531,12 +564,12 @@ gegl_buffer_constructor (GType                  type,
           g_assert (source);
           backend = gegl_buffer_backend (GEGL_BUFFER (source));
           g_assert (backend);
-          header = backend->header;
+          header = backend->priv->header;
           buffer->extent.x = header->x;
           buffer->extent.y = header->y;
           buffer->extent.width = header->width;
           buffer->extent.height = header->height;
-          buffer->format = backend->format;
+          buffer->format = gegl_tile_backend_get_format (backend);
         }
       else if (buffer->format)
         {
@@ -578,8 +611,8 @@ gegl_buffer_constructor (GType                  type,
 
   g_assert (backend);
 
-  tile_width  = backend->tile_width;
-  tile_height = backend->tile_height;
+  tile_width  = backend->priv->tile_width;
+  tile_height = backend->priv->tile_height;
 
   if (buffer->extent.width == -1 &&
       buffer->extent.height == -1) /* no specified extents,
@@ -642,7 +675,7 @@ gegl_buffer_constructor (GType                  type,
       parent.y = GEGL_BUFFER (source)->abyss.y - buffer->shift_y;
       parent.width = GEGL_BUFFER (source)->abyss.width;
       parent.height = GEGL_BUFFER (source)->abyss.height;
-      
+
       request.x = buffer->abyss.x;
       request.y = buffer->abyss.y;
       request.width = buffer->abyss.width;
@@ -821,6 +854,11 @@ gegl_buffer_class_init (GeglBufferClass *class)
                                                          G_PARAM_READWRITE |
                                                          G_PARAM_CONSTRUCT));
 
+  g_object_class_install_property (gobject_class, PROP_BACKEND,
+                                   g_param_spec_pointer ("backend", "backend", "A custom tile-backend instance to use",
+                                                         G_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT));
+
   g_object_class_install_property (gobject_class, PROP_TILE_HEIGHT,
                                    g_param_spec_int ("tile-height", "tile-height", "height of a tile",
                                                      -1, G_MAXINT, gegl_config()->tile_height,
@@ -988,6 +1026,36 @@ gegl_buffer_new (const GeglRectangle *extent,
                        NULL);
 }
 
+GeglBuffer *
+gegl_buffer_new_for_backend (const GeglRectangle *extent,
+                             void                *backend)
+{
+  GeglRectangle rect={0,0,0,0};
+  Babl *format;
+
+  /* if no extent is passed in inherit from backend */
+  if (extent==NULL)
+    {
+      extent = &rect;
+      rect = gegl_tile_backend_get_extent (backend);
+      /* if backend didnt have a rect, make it an infinite plane  */
+      if (gegl_rectangle_is_empty (extent))
+        rect = gegl_rectangle_infinite_plane ();
+    }
+
+  /* use the format of the backend */
+  format = gegl_tile_backend_get_format (backend);
+
+  return g_object_new (GEGL_TYPE_BUFFER,
+                       "x", extent->x,
+                       "y", extent->y,
+                       "width", extent->width,
+                       "height", extent->height,
+                       "format", format,
+                       "backend", backend,
+                       NULL);
+}
+
 
 /* FIXME: this function needs optimizing, perhaps keep a pool
  * of GeglBuffer shells that can be adapted to the needs
@@ -1110,12 +1178,19 @@ gegl_tile_storage_new_cached (gint tile_width, gint tile_height,
           g_str_equal (gegl_config()->swap, "RAM") ||
           g_str_equal (gegl_config()->swap, "ram"))
         {
+          GeglTileBackend *backend;
           item->ram = TRUE;
-          storage = gegl_tile_storage_new (tile_width, tile_height, babl_fmt, NULL);
+          backend = g_object_new (GEGL_TYPE_TILE_BACKEND_RAM,
+                                  "tile-width", tile_width,
+                                  "tile-height", tile_height,
+                                  "format", babl_fmt,
+                                  NULL);
+          storage = gegl_tile_storage_new (backend);
         }
       else
         {
           static gint no = 1;
+          GeglTileBackend *backend;
 
           gchar *filename;
           gchar *path;
@@ -1133,7 +1208,13 @@ gegl_tile_storage_new_cached (gint tile_width, gint tile_height,
           path = g_build_filename (gegl_config()->swap, filename, NULL);
           g_free (filename);
 
-          storage = gegl_tile_storage_new (tile_width, tile_height, babl_fmt, path);
+          backend = g_object_new (GEGL_TYPE_TILE_BACKEND_FILE,
+                                  "tile-width", tile_width,
+                                  "tile-height", tile_height,
+                                  "format", babl_fmt,
+                                  "path", path,
+                                  NULL);
+          storage = gegl_tile_storage_new (backend);
           g_free (path);
         }
       item->storage = storage;
@@ -1180,7 +1261,7 @@ static const void *gegl_buffer_internal_get_format (GeglBuffer *buffer)
   g_assert (buffer);
   if (buffer->format != NULL)
     return buffer->format;
-  return gegl_buffer_backend (buffer)->format;
+  return gegl_tile_backend_get_format (gegl_buffer_backend (buffer));
 }
 
 static void
@@ -1248,7 +1329,7 @@ const Babl    *gegl_buffer_get_format        (GeglBuffer           *buffer)
 gboolean gegl_buffer_is_shared (GeglBuffer *buffer)
 {
   GeglTileBackend *backend = gegl_buffer_backend (buffer);
-  return backend->shared;
+  return backend->priv->shared;
 }
 
 gboolean gegl_buffer_try_lock (GeglBuffer *buffer)
diff --git a/gegl/buffer/gegl-buffer.h b/gegl/buffer/gegl-buffer.h
index bee1c98..369b0d2 100644
--- a/gegl/buffer/gegl-buffer.h
+++ b/gegl/buffer/gegl-buffer.h
@@ -58,6 +58,21 @@ GeglBuffer*     gegl_buffer_new               (const GeglRectangle *extent,
                                                const Babl          *format);
 
 
+
+/**
+ * gegl_buffer_new_for_backend:
+ * @extent: the geometry of the buffer (origin, width and height) a
+ * GeglRectangle.
+ *
+ * Create a new GeglBuffer from a backend, if NULL is passed in the extent of
+ * the buffer will be inherited from the extent of the backend.
+ *
+ * returns a GeglBuffer, that holds a reference to the provided backend.
+ */
+GeglBuffer *
+gegl_buffer_new_for_backend (const GeglRectangle *extent,
+                             void                *backend);
+
 /**
  * gegl_buffer_open:
  * @path: the path to a gegl buffer on disk.
diff --git a/gegl/buffer/gegl-tile-backend-file.c b/gegl/buffer/gegl-tile-backend-file.c
index 3c113cc..299c102 100644
--- a/gegl/buffer/gegl-tile-backend-file.c
+++ b/gegl/buffer/gegl-tile-backend-file.c
@@ -36,8 +36,9 @@
 #include "gegl-tile-backend.h"
 #include "gegl-tile-backend-file.h"
 #include "gegl-buffer-index.h"
+#include "gegl-buffer-types.h"
 #include "gegl-debug.h"
-#include "gegl-types-internal.h"
+//#include "gegl-types-internal.h"
 
 
 struct _GeglTileBackendFile
@@ -134,7 +135,7 @@ gegl_tile_backend_file_file_entry_read (GeglTileBackendFile *self,
 {
   gint     to_be_read;
   gboolean success;
-  gint     tile_size = GEGL_TILE_BACKEND (self)->tile_size;
+  gint     tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self));
   goffset  offset = entry->offset;
 
   gegl_tile_backend_file_ensure_exist (self);
@@ -185,7 +186,7 @@ gegl_tile_backend_file_file_entry_write (GeglTileBackendFile *self,
 {
   gint     to_be_written;
   gboolean success;
-  gint     tile_size = GEGL_TILE_BACKEND (self)->tile_size;
+  gint     tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self));
   goffset  offset = entry->offset;
 
   gegl_tile_backend_file_ensure_exist (self);
@@ -248,7 +249,7 @@ gegl_tile_backend_file_file_entry_new (GeglTileBackendFile *self)
     }
   else
     {
-      gint tile_size = GEGL_TILE_BACKEND (self)->tile_size;
+      gint tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self));
 
       entry->offset = self->next_pre_alloc;
       GEGL_NOTE (GEGL_DEBUG_TILE_BACKEND, "  set offset %i (next allocation)", (gint)entry->offset);
@@ -268,7 +269,7 @@ gegl_tile_backend_file_file_entry_new (GeglTileBackendFile *self)
 #endif
         }
     }
-  gegl_tile_backend_file_dbg_alloc (GEGL_TILE_BACKEND (self)->tile_size);
+  gegl_tile_backend_file_dbg_alloc (gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self)));
   return entry;
 }
 
@@ -282,7 +283,7 @@ gegl_tile_backend_file_file_entry_destroy (GeglBufferTile      *entry,
                                      GUINT_TO_POINTER (offset));
   g_hash_table_remove (self->index, entry);
 
-  gegl_tile_backend_file_dbg_dealloc (GEGL_TILE_BACKEND (self)->tile_size);
+  gegl_tile_backend_file_dbg_dealloc (gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self)));
   g_free (entry);
 }
 
@@ -449,11 +450,11 @@ gegl_tile_backend_file_get_tile (GeglTileSource *self,
           gint            y,
           gint            z)
 {
-
   GeglTileBackend     *backend;
   GeglTileBackendFile *tile_backend_file;
   GeglBufferTile      *entry;
   GeglTile            *tile = NULL;
+  gint                 tile_size;
 
   backend           = GEGL_TILE_BACKEND (self);
   tile_backend_file = GEGL_TILE_BACKEND_FILE (backend);
@@ -462,8 +463,9 @@ gegl_tile_backend_file_get_tile (GeglTileSource *self,
   if (!entry)
     return NULL;
 
-  tile      = gegl_tile_new (backend->tile_size);
-  tile->rev = entry->rev;
+  tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self));
+  tile      = gegl_tile_new (tile_size);
+  gegl_tile_set_rev (tile, entry->rev);
   gegl_tile_mark_as_stored (tile);
 
   gegl_tile_backend_file_file_entry_read (tile_backend_file, entry, gegl_tile_get_data (tile));
@@ -493,7 +495,7 @@ gegl_tile_backend_file_set_tile (GeglTileSource *self,
       entry->z = z;
       g_hash_table_insert (tile_backend_file->index, entry, entry);
     }
-  entry->rev = tile->rev;
+  entry->rev = gegl_tile_get_rev (tile);
 
   gegl_tile_backend_file_file_entry_write (tile_backend_file, entry, gegl_tile_get_data (tile));
   gegl_tile_mark_as_stored (tile);
@@ -779,6 +781,7 @@ gegl_tile_backend_file_load_index (GeglTileBackendFile *self,
   GeglTileBackend *backend;
   goffset offset = 0;
   goffset max=0;
+  gint tile_size;
 
   /* compute total from and next pre alloc by monitoring tiles as they
    * are added here
@@ -804,6 +807,7 @@ gegl_tile_backend_file_load_index (GeglTileBackendFile *self,
     }
 
 
+  tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self));
   offset      = self->header.next;
   self->tiles = gegl_buffer_read_index (self->i, &offset);
   backend     = GEGL_TILE_BACKEND (self);
@@ -815,7 +819,7 @@ gegl_tile_backend_file_load_index (GeglTileBackendFile *self,
       GeglBufferItem *existing = g_hash_table_lookup (self->index, item);
 
       if (item->tile.offset > max)
-        max = item->tile.offset + backend->tile_size;
+        max = item->tile.offset + tile_size;
 
       if (existing)
         {
@@ -830,7 +834,12 @@ gegl_tile_backend_file_load_index (GeglTileBackendFile *self,
             {
               GeglRectangle rect;
               g_hash_table_remove (self->index, existing);
-              gegl_tile_source_refetch (GEGL_TILE_SOURCE (backend->storage),
+
+              /* XXX: this refetch, depends on knowing the storage, the
+               * storage should not be public information/API to maintain
+               * proper encapsulation
+               */
+              gegl_tile_source_refetch (GEGL_TILE_SOURCE (backend->priv->storage),
                                         existing->tile.x,
                                         existing->tile.y,
                                         existing->tile.z);
@@ -843,7 +852,11 @@ gegl_tile_backend_file_load_index (GeglTileBackendFile *self,
                   rect.y = existing->tile.y * self->header.tile_height;
                 }
               g_free (existing);
-              g_signal_emit_by_name (backend->storage, "changed", &rect, NULL);
+
+              /* XXX: this emitting of changed depends on knowing the storage,
+               * which is icky..
+               */
+              g_signal_emit_by_name (backend->priv->storage, "changed", &rect, NULL);
             }
         }
       g_hash_table_insert (self->index, iter->data, iter->data);
@@ -948,12 +961,16 @@ gegl_tile_backend_file_constructor (GType                  type,
       self->header = gegl_buffer_read_header (self->i, &offset)->header;
       self->header.rev = self->header.rev -1;
 
-      /* we are overriding all of the work of the actual constructor here */
-      backend->tile_width = self->header.tile_width;
-      backend->tile_height = self->header.tile_height;
-      backend->format = babl_format (self->header.description);
-      backend->px_size = babl_format_get_bytes_per_pixel (backend->format);
-      backend->tile_size = backend->tile_width * backend->tile_height * backend->px_size;
+      /* we are overriding all of the work of the actual constructor here,
+       * a really evil hack :d
+       */
+      backend->priv->tile_width = self->header.tile_width;
+      backend->priv->tile_height = self->header.tile_height;
+      backend->priv->format = babl_format (self->header.description);
+      backend->priv->px_size = babl_format_get_bytes_per_pixel (backend->priv->format);
+      backend->priv->tile_size = backend->priv->tile_width *
+                                    backend->priv->tile_height *
+                                    backend->priv->px_size;
 
       /* insert each of the entries into the hash table */
       gegl_tile_backend_file_load_index (self, TRUE);
@@ -969,7 +986,9 @@ gegl_tile_backend_file_constructor (GType                  type,
 #endif
 
       /* to autoflush gegl_buffer_set */
-      backend->shared = TRUE;
+
+      /* XXX: poking at internals, icky */
+      backend->priv->shared = TRUE;
     }
   else
     {
@@ -980,7 +999,7 @@ gegl_tile_backend_file_constructor (GType                  type,
   g_assert (self->file);
 #endif
 
-  backend->header = &self->header;
+  backend->priv->header = &self->header;
 
   return object;
 }
@@ -1031,10 +1050,10 @@ gegl_tile_backend_file_ensure_exist (GeglTileBackendFile *self)
       g_assert(g_seekable_seek (G_SEEKABLE (self->o), 256, G_SEEK_SET, NULL, NULL));
 #endif
       gegl_buffer_header_init (&self->header,
-                               backend->tile_width,
-                               backend->tile_height,
-                               backend->px_size,
-                               backend->format
+                               backend->priv->tile_width,
+                               backend->priv->tile_height,
+                               backend->priv->px_size,
+                               backend->priv->format
                                );
       gegl_tile_backend_file_write_header (self);
 #if HAVE_GIO
diff --git a/gegl/buffer/gegl-tile-backend-ram.c b/gegl/buffer/gegl-tile-backend-ram.c
index 1e335fd..308609a 100644
--- a/gegl/buffer/gegl-tile-backend-ram.c
+++ b/gegl/buffer/gegl-tile-backend-ram.c
@@ -22,19 +22,13 @@
 
 #include <glib-object.h>
 
+#include "gegl-buffer-backend.h"
 #include "gegl-tile-backend.h"
 #include "gegl-tile-backend-ram.h"
 
-
 static void dbg_alloc (int size);
 static void dbg_dealloc (int size);
 
-/* These entries are kept in RAM for now, they should be written as an index to the
- * swap file, at a position specified by a header block, making the header grow up
- * to a multiple of the size used in this swap file is probably a good idea
- *
- * Serializing the bablformat is probably also a good idea.
- */
 typedef struct _RamEntry RamEntry;
 
 struct _RamEntry
@@ -50,7 +44,7 @@ ram_entry_read (GeglTileBackendRam *ram,
                 RamEntry           *entry,
                 guchar             *dest)
 {
-  gint tile_size = GEGL_TILE_BACKEND (ram)->tile_size;
+  gint tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (ram));
 
   memcpy (dest, entry->offset, tile_size);
 }
@@ -60,7 +54,7 @@ ram_entry_write (GeglTileBackendRam *ram,
                  RamEntry           *entry,
                  guchar             *source)
 {
-  gint tile_size = GEGL_TILE_BACKEND (ram)->tile_size;
+  gint tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (ram));
 
   memcpy (entry->offset, source, tile_size);
 }
@@ -69,9 +63,10 @@ static inline RamEntry *
 ram_entry_new (GeglTileBackendRam *ram)
 {
   RamEntry *self = g_slice_new (RamEntry);
+  gint tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (ram));
 
-  self->offset = g_malloc (GEGL_TILE_BACKEND (ram)->tile_size);
-  dbg_alloc (GEGL_TILE_BACKEND (ram)->tile_size);
+  self->offset = g_malloc (tile_size);
+  dbg_alloc (tile_size);
   return self;
 }
 
@@ -79,10 +74,11 @@ static inline void
 ram_entry_destroy (RamEntry           *entry,
                    GeglTileBackendRam *ram)
 {
+  gint tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (ram));
   g_free (entry->offset);
   g_hash_table_remove (ram->entries, entry);
 
-  dbg_dealloc (GEGL_TILE_BACKEND (ram)->tile_size);
+  dbg_dealloc (tile_size);
   g_slice_free (RamEntry, entry);
 }
 
@@ -148,6 +144,7 @@ get_tile (GeglTileSource *tile_store,
   GeglTileBackendRam     *tile_backend_ram = GEGL_TILE_BACKEND_RAM (tile_store);
   GeglTileBackend *backend  = GEGL_TILE_BACKEND (tile_store);
   GeglTile        *tile     = NULL;
+  gint tile_size = gegl_tile_backend_get_tile_size (backend);
 
   {
     RamEntry *entry = lookup_entry (tile_backend_ram, x, y, z);
@@ -155,7 +152,7 @@ get_tile (GeglTileSource *tile_store,
     if (!entry)
       return NULL;
 
-    tile = gegl_tile_new (backend->tile_size);
+    tile = gegl_tile_new (tile_size);
 
     ram_entry_read (tile_backend_ram, entry, gegl_tile_get_data (tile));
   }
diff --git a/gegl/buffer/gegl-tile-backend-tiledir.c b/gegl/buffer/gegl-tile-backend-tiledir.c
index 0046941..d05adc1 100644
--- a/gegl/buffer/gegl-tile-backend-tiledir.c
+++ b/gegl/buffer/gegl-tile-backend-tiledir.c
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <errno.h>
 
+#include "gegl-types.h"
 #include "gegl-tile-backend.h"
 #include "gegl-tile-backend-tiledir.h"
 
@@ -73,7 +74,7 @@ gio_entry_read (GeglTileBackendTileDir *gio,
                 guchar                  *dest)
 {
   GFile            *file;
-  gint              tile_size = GEGL_TILE_BACKEND (gio)->tile_size;
+  gint   tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (gio));
   GFileInputStream *i;
   gsize             bytes_read;
 
@@ -94,7 +95,7 @@ gio_entry_write (GeglTileBackendTileDir *gio,
                  GioEntry                *entry,
                  guchar                  *source)
 {
-  gint               tile_size = GEGL_TILE_BACKEND (gio)->tile_size;
+  gint   tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (gio));
   GFile             *file;
   GFileOutputStream *o;
   gsize              bytes_written;
@@ -147,12 +148,13 @@ get_tile (GeglTileSource *tile_store,
  if (exist_tile (tile_store, NULL, x, y, z))
   {
     GioEntry       entry;
+    gint   tile_size = gegl_tile_backend_get_tile_size (backend);
 
     entry.x = x;
     entry.y = y;
     entry.z = z;
 
-    tile = gegl_tile_new (backend->tile_size);
+    tile = gegl_tile_new (tile_size);
 
     gio_entry_read (tile_backend_tiledir, &entry, gegl_tile_get_data (tile));
     return tile;
diff --git a/gegl/buffer/gegl-tile-backend.c b/gegl/buffer/gegl-tile-backend.c
index 2222aae..655ac42 100644
--- a/gegl/buffer/gegl-tile-backend.c
+++ b/gegl/buffer/gegl-tile-backend.c
@@ -21,6 +21,7 @@
 #include <string.h>
 
 #include <babl/babl.h>
+#include "gegl-buffer-types.h"
 #include "gegl-tile-source.h"
 #include "gegl-tile-backend.h"
 
@@ -48,23 +49,23 @@ get_property (GObject    *gobject,
   switch (property_id)
     {
       case PROP_TILE_WIDTH:
-        g_value_set_int (value, backend->tile_width);
+        g_value_set_int (value, backend->priv->tile_width);
         break;
 
       case PROP_TILE_HEIGHT:
-        g_value_set_int (value, backend->tile_height);
+        g_value_set_int (value, backend->priv->tile_height);
         break;
 
       case PROP_TILE_SIZE:
-        g_value_set_int (value, backend->tile_size);
+        g_value_set_int (value, backend->priv->tile_size);
         break;
 
       case PROP_PX_SIZE:
-        g_value_set_int (value, backend->px_size);
+        g_value_set_int (value, backend->priv->px_size);
         break;
 
       case PROP_FORMAT:
-        g_value_set_pointer (value, backend->format);
+        g_value_set_pointer (value, backend->priv->format);
         break;
 
       default:
@@ -84,15 +85,15 @@ set_property (GObject      *gobject,
   switch (property_id)
     {
       case PROP_TILE_WIDTH:
-        backend->tile_width = g_value_get_int (value);
+        backend->priv->tile_width = g_value_get_int (value);
         return;
 
       case PROP_TILE_HEIGHT:
-        backend->tile_height = g_value_get_int (value);
+        backend->priv->tile_height = g_value_get_int (value);
         return;
 
       case PROP_FORMAT:
-        backend->format = g_value_get_pointer (value);
+        backend->priv->format = g_value_get_pointer (value);
         break;
 
       default:
@@ -112,12 +113,12 @@ constructor (GType                  type,
   object  = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
   backend = GEGL_TILE_BACKEND (object);
 
-  g_assert (backend->tile_width > 0 && backend->tile_height > 0);
-  g_assert (backend->format);
+  g_assert (backend->priv->tile_width > 0 && backend->priv->tile_height > 0);
+  g_assert (backend->priv->format);
 
 
-  backend->px_size = babl_format_get_bytes_per_pixel (backend->format);
-  backend->tile_size = backend->tile_width * backend->tile_height * backend->px_size;
+  backend->priv->px_size = babl_format_get_bytes_per_pixel (backend->priv->format);
+  backend->priv->tile_size = backend->priv->tile_width * backend->priv->tile_height * backend->priv->px_size;
 
   return object;
 }
@@ -155,10 +156,40 @@ gegl_tile_backend_class_init (GeglTileBackendClass *klass)
                                    g_param_spec_pointer ("format", "format", "babl format",
                                                          G_PARAM_READWRITE |
                                                          G_PARAM_CONSTRUCT_ONLY));
+  g_type_class_add_private (gobject_class, sizeof (GeglTileBackendPrivate));
 }
 
+#define GEGL_TILE_BACKEND_GET_PRIVATE(obj) \
+    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GEGL_TYPE_TILE_BACKEND, GeglTileBackendPrivate))
+
+
 static void
 gegl_tile_backend_init (GeglTileBackend *self)
 {
-  self->shared = FALSE;
+  self->priv = GEGL_TILE_BACKEND_GET_PRIVATE (self);
+  self->priv->shared = FALSE;
+}
+
+
+gint gegl_tile_backend_get_tile_size (GeglTileBackend *tile_backend)
+{
+  return tile_backend->priv->tile_size;
+}
+
+
+Babl *gegl_tile_backend_get_format (GeglTileBackend *tile_backend)
+{
+  return tile_backend->priv->format;
+}
+
+
+void  gegl_tile_backend_set_extent    (GeglTileBackend *tile_backend,
+                                       GeglRectangle   *rectangle)
+{
+  tile_backend->priv->extent = *rectangle;
+}
+
+GeglRectangle gegl_tile_backend_get_extent (GeglTileBackend *tile_backend)
+{
+  return tile_backend->priv->extent;
 }
diff --git a/gegl/buffer/gegl-tile-backend.h b/gegl/buffer/gegl-tile-backend.h
index d26d702..8c1ad89 100644
--- a/gegl/buffer/gegl-tile-backend.h
+++ b/gegl/buffer/gegl-tile-backend.h
@@ -32,28 +32,31 @@ G_BEGIN_DECLS
 
 struct _GeglTileBackend
 {
-  GeglTileSource  parent_instance;
-
-  gint            tile_width;
-  gint            tile_height;
-  Babl           *format;        /* defaults to the babl format "R'G'B'A u8" */
-  gint            px_size;       /* size of a single pixel in bytes */
-  gint            tile_size;     /* size of an entire tile in bytes */
-
-  /* private */
-  gpointer        header;
-  gpointer        storage;
-  gboolean        shared;
+  GeglTileSource          parent_instance;
+  GeglTileBackendPrivate *priv;
 };
 
 struct _GeglTileBackendClass
 {
   GeglTileSourceClass parent_class;
 
-  void (* create)  (GeglTileBackend *backend); 
-  void (* destroy) (GeglTileBackend *backend);
+  gpointer  padding1;
+  gpointer  padding2;
+  gpointer  padding3;
+  gpointer  padding4;
 };
 
+gint  gegl_tile_backend_get_tile_size (GeglTileBackend *tile_backend);
+Babl *gegl_tile_backend_get_format    (GeglTileBackend *tile_backend);
+
+/* specify the extent of the backend, can be used to
+ * pre-prime the backend with the width/height information when
+ * constructing proxy GeglBuffers to interact with other systems
+ */
+void  gegl_tile_backend_set_extent    (GeglTileBackend *tile_backend,
+                                       GeglRectangle   *rectangle);
+GeglRectangle gegl_tile_backend_get_extent (GeglTileBackend *tile_backend);
+
 GType gegl_tile_backend_get_type (void) G_GNUC_CONST;
 
 G_END_DECLS
diff --git a/gegl/buffer/gegl-tile-handler-chain.c b/gegl/buffer/gegl-tile-handler-chain.c
index 424eff1..ec9a43c 100644
--- a/gegl/buffer/gegl-tile-handler-chain.c
+++ b/gegl/buffer/gegl-tile-handler-chain.c
@@ -20,6 +20,8 @@
 
 #include <glib.h>
 
+#include "glib-object.h"
+#include "gegl-buffer-types.h"
 #include "gegl-tile-handler-chain.h"
 #include "gegl-tile-handler-cache.h"
 
diff --git a/gegl/buffer/gegl-tile-handler-empty.c b/gegl/buffer/gegl-tile-handler-empty.c
index de3a029..e6a775a 100644
--- a/gegl/buffer/gegl-tile-handler-empty.c
+++ b/gegl/buffer/gegl-tile-handler-empty.c
@@ -20,6 +20,10 @@
 #include <glib-object.h>
 #include <string.h>
 
+#include "gegl-types.h"
+#include "gegl-matrix.h"
+#include "gegl-buffer-types.h"
+#include "gegl-buffer-private.h"
 #include "gegl-tile-handler.h"
 #include "gegl-tile-handler-empty.h"
 #include "gegl-tile-handler-cache.h"
@@ -96,9 +100,10 @@ gegl_tile_handler_empty_new (GeglTileBackend      *backend,
                              GeglTileHandlerCache *cache)
 {
   GeglTileHandlerEmpty *empty = g_object_new (GEGL_TYPE_TILE_HANDLER_EMPTY, NULL);
+  gint tile_size = gegl_tile_backend_get_tile_size (backend);
   empty->backend = backend;
   empty->cache = cache;
-  empty->tile = gegl_tile_new (backend->tile_size);
-  memset (gegl_tile_get_data (empty->tile), 0x00, backend->tile_size);
+  empty->tile = gegl_tile_new (tile_size);
+  memset (gegl_tile_get_data (empty->tile), 0x00, tile_size);
   return (void*)empty;
 }
diff --git a/gegl/buffer/gegl-tile-handler-log.c b/gegl/buffer/gegl-tile-handler-log.c
index 936cc67..58fc1d0 100644
--- a/gegl/buffer/gegl-tile-handler-log.c
+++ b/gegl/buffer/gegl-tile-handler-log.c
@@ -20,6 +20,7 @@
 #include <glib-object.h>
 #include <string.h>
 
+#include "gegl-buffer-types.h"
 #include "gegl-tile-handler.h"
 #include "gegl-tile-handler-log.h"
 
diff --git a/gegl/buffer/gegl-tile-handler-zoom.c b/gegl/buffer/gegl-tile-handler-zoom.c
index dc2f07d..732b4fc 100644
--- a/gegl/buffer/gegl-tile-handler-zoom.c
+++ b/gegl/buffer/gegl-tile-handler-zoom.c
@@ -20,6 +20,10 @@
 #include <glib-object.h>
 #include <string.h>
 
+#include "gegl-types.h"
+#include "gegl-matrix.h"
+#include "gegl-buffer-types.h"
+#include "gegl-buffer-private.h"
 #include "gegl-tile-handler.h"
 #include "gegl-tile-handler-zoom.h"
 #include "gegl-tile-handler-cache.h"
@@ -200,7 +204,7 @@ get_tile (GeglTileSource *gegl_tile_source,
   GeglTileSource      *source = ((GeglTileHandler*)(gegl_tile_source))->source;
   GeglTileHandlerZoom *zoom   = (GeglTileHandlerZoom*)(gegl_tile_source);
   GeglTile            *tile   = NULL;
-  Babl                *format = (Babl *) (zoom->backend->format);
+  Babl                *format = gegl_tile_backend_get_format (zoom->backend);
   gint                 tile_width;
   gint                 tile_height;
   gint                 tile_size;
@@ -255,9 +259,9 @@ get_tile (GeglTileSource *gegl_tile_source,
       {
         tile = gegl_tile_new (tile_size);
 
-        tile->x          = x;
-        tile->y          = y;
-        tile->z          = z;
+        tile->x = x;
+        tile->y = y;
+        tile->z = z;
         tile->tile_storage = zoom->tile_storage;
 
         if (zoom->cache)
diff --git a/gegl/buffer/gegl-tile-handler.c b/gegl/buffer/gegl-tile-handler.c
index e2b0642..601f770 100644
--- a/gegl/buffer/gegl-tile-handler.c
+++ b/gegl/buffer/gegl-tile-handler.c
@@ -22,6 +22,7 @@
 
 #include <glib-object.h>
 
+#include "gegl-buffer-types.h"
 #include "gegl-tile-source.h"
 #include "gegl-tile-handler.h"
 #include "gegl-tile-handler-chain.h"
diff --git a/gegl/buffer/gegl-tile-source.c b/gegl/buffer/gegl-tile-source.c
index d30de3d..3f56651 100644
--- a/gegl/buffer/gegl-tile-source.c
+++ b/gegl/buffer/gegl-tile-source.c
@@ -18,6 +18,7 @@
 #include "config.h"
 #include <glib.h>
 #include <glib-object.h>
+#include "gegl-buffer-types.h"
 #include "gegl-tile-source.h"
 
 G_DEFINE_TYPE (GeglTileSource, gegl_tile_source, G_TYPE_OBJECT)
diff --git a/gegl/buffer/gegl-tile-source.h b/gegl/buffer/gegl-tile-source.h
index 85c6a5a..f5d1397 100644
--- a/gegl/buffer/gegl-tile-source.h
+++ b/gegl/buffer/gegl-tile-source.h
@@ -13,7 +13,7 @@
  * 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 <pippin gimp org>
+ * Copyright 2006-2011 �yvind Kolås <pippin gimp org>
  */
 
 #ifndef __GEGL_TILE_SOURCE_H__
@@ -21,7 +21,6 @@
 
 #include <glib-object.h>
 #include <babl/babl.h>
-#include "gegl-buffer-types.h"
 #include "gegl-tile.h"
 
 G_BEGIN_DECLS
@@ -39,16 +38,24 @@ struct _GeglTileSource
 {
   GObject   parent_instance;
   gpointer  (*command)  (GeglTileSource  *gegl_tile_source,
-                         GeglTileCommand command,
-                         gint            x,
-                         gint            y,
-                         gint            z,
-                         gpointer        data);
+                         GeglTileCommand  command,
+                         gint             x,
+                         gint             y,
+                         gint             z,
+                         gpointer         data);
+  gpointer  padding1;
+  gpointer  padding2;
+  gpointer  padding3;
+  gpointer  padding4;
 };
 
 struct _GeglTileSourceClass
 {
   GObjectClass  parent_class;
+  gpointer  padding1;
+  gpointer  padding2;
+  gpointer  padding3;
+  gpointer  padding4;
 };
 
 GType      gegl_tile_source_get_type (void) G_GNUC_CONST;
@@ -61,7 +68,7 @@ GType      gegl_tile_source_get_type (void) G_GNUC_CONST;
 enum _GeglTileCommand
 {
   GEGL_TILE_IDLE = 0,
-  GEGL_TILE_SET, 
+  GEGL_TILE_SET,
   GEGL_TILE_GET,
   GEGL_TILE_IS_CACHED,
   GEGL_TILE_EXIST,
@@ -72,6 +79,7 @@ enum _GeglTileCommand
 };
 
 #ifdef NOT_REALLY_COS_THIS_IS_MACROS
+/* The functions documented below are actually macros, all using the command vfunc */
 
 /**
  * gegl_tile_source_get_tile:
@@ -99,7 +107,7 @@ GeglTile *gegl_tile_source_get_tile  (GeglTileSource *source,
  * @z: tile zoom level
  * @tile: a #GeglTile
  *
- * Get a GeglTile *from the buffer.
+ * Set a GeglTile in *from the buffer.
  *
  * Returns: the TRUE if the set was successful.
  */
diff --git a/gegl/buffer/gegl-tile-storage.c b/gegl/buffer/gegl-tile-storage.c
index 43beda3..242c65c 100644
--- a/gegl/buffer/gegl-tile-storage.c
+++ b/gegl/buffer/gegl-tile-storage.c
@@ -21,6 +21,7 @@
 #include <glib-object.h>
 
 #include "gegl.h"
+#include "gegl-buffer-types.h"
 #include "gegl-tile-storage.h"
 #include "gegl-tile.h"
 #include "gegl-tile-backend-file.h"
@@ -66,66 +67,34 @@ tile_storage_idle (gpointer data)
 GeglTileBackend *gegl_buffer_backend (GObject *buffer);
 
 GeglTileStorage *
-gegl_tile_storage_new (gint tile_width,
-                       gint tile_height,
-                       const Babl *format,
-                       const gchar *path)
+gegl_tile_storage_new (GeglTileBackend *backend)
 {
   GeglTileStorage *tile_storage = g_object_new (GEGL_TYPE_TILE_STORAGE, NULL);
   GeglTileHandlerChain  *tile_handler_chain;
   GeglTileHandler       *handler;
-  GeglTileBackend       *backend = NULL;
   GeglTileHandler       *empty = NULL;
   GeglTileHandler       *zoom = NULL;
   GeglTileHandlerCache  *cache = NULL;
 
-  if (tile_width <= 0)
-    tile_width = 128;
-  if (tile_height <= 0)
-    tile_height = 64;
-
   tile_storage->seen_zoom = 0;
   tile_storage->mutex = g_mutex_new ();
   tile_storage->width = G_MAXINT;
   tile_storage->height = G_MAXINT;
-  tile_storage->tile_width = tile_width;
-  tile_storage->tile_height = tile_height;
-  tile_storage->format = format;
-  if (path)
-    tile_storage->path = g_strdup (path);
+
+  if (g_object_class_find_property (G_OBJECT_GET_CLASS (backend), "path"))
+    {
+      g_object_get (backend, "path", &tile_storage->path, NULL);
+    }
 
   tile_handler_chain = GEGL_TILE_HANDLER_CHAIN (tile_storage);
   handler  = GEGL_TILE_HANDLER (tile_storage);
 
-  if (tile_storage->path != NULL)
-    {
-#if 1
-      backend = g_object_new (GEGL_TYPE_TILE_BACKEND_FILE,
-                              "tile-width", tile_storage->tile_width,
-                              "tile-height", tile_storage->tile_height,
-                              "format", tile_storage->format,
-                              "path", tile_storage->path,
-                              NULL);
-#else
-      backend = g_object_new (GEGL_TYPE_TILE_BACKEND_TILEDIR,
-                              "tile-width", tile_storage->tile_width,
-                              "tile-height", tile_storage->tile_height,
-                              "format", tile_storage->format,
-                              "path", tile_storage->path,
-                              NULL);
-#endif
-    }
-  else
-    {
-      backend = g_object_new (GEGL_TYPE_TILE_BACKEND_RAM,
-                              "tile-width", tile_storage->tile_width,
-                              "tile-height", tile_storage->tile_height,
-                              "format", tile_storage->format,
-                              NULL);
-    }
+  tile_storage->tile_width  = backend->priv->tile_width;
+  tile_storage->tile_height = backend->priv->tile_height;
+  tile_storage->px_size     = backend->priv->px_size;
+  tile_storage->format      = gegl_tile_backend_get_format (backend);
+  tile_storage->tile_size   = gegl_tile_backend_get_tile_size (backend);
 
-  tile_storage->tile_size = backend->tile_size;
-  tile_storage->px_size = backend->px_size;
   gegl_tile_handler_set_source (handler, (void*)backend);
 
   { /* should perhaps be a.. method on gegl_tile_handler_chain_set_source
@@ -166,8 +135,8 @@ gegl_tile_storage_new (gint tile_width,
   tile_storage->cache = cache;
   gegl_tile_handler_chain_bind (tile_handler_chain);
 
-  ((GeglTileBackend *)gegl_buffer_backend ((void*)tile_storage))->storage = (gpointer)
-                                                                          tile_storage;
+  ((GeglTileBackend *)gegl_buffer_backend ((void*)tile_storage))->priv->storage = (gpointer)
+                                             tile_storage;
 
   tile_storage->idle_swapper = g_timeout_add_full (G_PRIORITY_LOW,
                                               250,
diff --git a/gegl/buffer/gegl-tile-storage.h b/gegl/buffer/gegl-tile-storage.h
index e4d34ae..6d48e3f 100644
--- a/gegl/buffer/gegl-tile-storage.h
+++ b/gegl/buffer/gegl-tile-storage.h
@@ -53,10 +53,8 @@ struct _GeglTileStorageClass
 };
 
 GType gegl_tile_storage_get_type (void) G_GNUC_CONST;
+
 GeglTileStorage *
-gegl_tile_storage_new (gint tile_width,
-                       gint tile_height,
-                       const Babl *format,
-                       const gchar *path);
+gegl_tile_storage_new (GeglTileBackend *backend);
 
 #endif
diff --git a/gegl/buffer/gegl-tile.c b/gegl/buffer/gegl-tile.c
index 25af601..6215025 100644
--- a/gegl/buffer/gegl-tile.c
+++ b/gegl/buffer/gegl-tile.c
@@ -24,6 +24,8 @@
 #include <unistd.h>
 #endif
 
+#define __GEGL_TILE_C
+
 #include <glib-object.h>
 
 #include "gegl-types-internal.h"
@@ -261,41 +263,6 @@ gegl_tile_void (GeglTile *tile)
     gegl_tile_void_pyramid (tile);
 }
 
-void
-gegl_tile_cpy (GeglTile *src,
-               GeglTile *dst)
-{
-  gegl_tile_lock (dst);
-
-  gegl_free (dst->data);
-  dst->data = NULL;
-
-  dst->next_shared              = src->next_shared;
-  src->next_shared              = dst;
-  dst->prev_shared              = src;
-  dst->next_shared->prev_shared = dst;
-
-  dst->data = src->data;
-
-  gegl_tile_unlock (dst);
-}
-
-void
-gegl_tile_swp (GeglTile *a,
-               GeglTile *b)
-{
-  guchar *tmp;
-
-  gegl_tile_unclone (a);
-  gegl_tile_unclone (b);
-
-  g_assert (a->size == b->size);
-
-  tmp     = a->data;
-  a->data = b->data;
-  b->data = tmp;
-}
-
 gboolean gegl_tile_store (GeglTile *tile)
 {
   if (gegl_tile_is_stored (tile))
@@ -308,3 +275,22 @@ gboolean gegl_tile_store (GeglTile *tile)
                                     tile->z,
                                     tile);
 }
+
+/* for internal use, a macro poking directly at the data will be faster 
+ */
+guchar *gegl_tile_get_data (GeglTile *tile)
+{
+  return tile->data;
+}
+
+
+void         gegl_tile_set_rev        (GeglTile *tile,
+                                       guint     rev)
+{
+  tile->rev = rev;
+}
+
+guint        gegl_tile_get_rev        (GeglTile *tile)
+{
+  return tile->rev;
+}
diff --git a/gegl/buffer/gegl-tile.h b/gegl/buffer/gegl-tile.h
index 40e6df9..05d5469 100644
--- a/gegl/buffer/gegl-tile.h
+++ b/gegl/buffer/gegl-tile.h
@@ -20,52 +20,12 @@
 #define __GEGL_TILE_H__
 
 #include <glib-object.h>
-
-#include "gegl-buffer-types.h"
-
-/* the instance size of a GeglTile is a bit large, and should if possible be
- * trimmed down
- */
-struct _GeglTile
-{
- /* GObject          parent_instance;*/
-  gint             ref_count;
-
-  guchar          *data;        /* actual pixel data for tile, a linear buffer*/
-  gint             size;        /* The size of the linear buffer */
-
-  GeglTileStorage *tile_storage; /* the buffer from which this tile was
-                                  * retrieved needed for the tile to be able to
-                                  * store itself back (for instance when it is
-                                  * unreffed for the last time)
-                                  */
-  gint             x, y, z;
-
-
-  guint            rev;         /* this tile revision */
-  guint            stored_rev;  /* what revision was we when we from tile_storage?
-                                   (currently set to 1 when loaded from disk */
-
-  gchar            lock;        /* number of times the tile is write locked
-                                 * should in theory just have the values 0/1
-                                 */
-  GMutex          *mutex;
-
-  /* the shared list is a doubly linked circular list */
-  GeglTile        *next_shared;
-  GeglTile        *prev_shared;
-
-  void (*destroy_notify) (gpointer pixels,
-                          gpointer data);
-  gpointer         destroy_notify_data;
-};
+#include "gegl-buffer-backend.h"
 
 GeglTile   * gegl_tile_new            (gint     size);
 GeglTile   * gegl_tile_new_bare       (void); /* special hack for linear bufs */
 GeglTile   * gegl_tile_ref            (GeglTile *tile);
 void         gegl_tile_unref          (GeglTile *tile);
-void       * gegl_tile_get_format     (GeglTile *tile);
-
 
 /* lock a tile for writing, this would allow writing to buffers
  * later gotten with get_data()
@@ -78,43 +38,16 @@ void         gegl_tile_lock           (GeglTile *tile);
 void         gegl_tile_unlock         (GeglTile *tile);
 
 
-
 void         gegl_tile_mark_as_stored (GeglTile *tile);
 gboolean     gegl_tile_is_stored      (GeglTile *tile);
 gboolean     gegl_tile_store          (GeglTile *tile);
 void         gegl_tile_void           (GeglTile *tile);
 GeglTile    *gegl_tile_dup            (GeglTile *tile);
 
-/* utility low-level functions used by an undo system in horizon
- * where the geglbufer originated, kept around in case they
- * become useful again
- */
-void         gegl_tile_swp            (GeglTile *a,
-                                       GeglTile *b);
-void         gegl_tile_cpy            (GeglTile *src,
-                                       GeglTile *dst);
-
-
-/* computes the positive integer remainder (also for negative dividends)
- */
-#define GEGL_REMAINDER(dividend, divisor) \
-                   (((dividend) < 0) ? \
-                    (divisor) - 1 - ((-((dividend) + 1)) % (divisor)) : \
-                    (dividend) % (divisor))
-
-/* get a pointer to the linear buffer of the tile.
- */
-#define gegl_tile_get_data(tile)  ((guchar*)((tile)->data))
-
-#define gegl_tile_offset(coordinate, stride) GEGL_REMAINDER((coordinate), (stride))
-
-/* helper function to compute tile indices and offsets for coordinates
- * based on a tile stride (tile_width or tile_height)
- */
-#define gegl_tile_indice(coordinate,stride) \
-  (((coordinate) >= 0)?\
-      (coordinate) / (stride):\
-      ((((coordinate) + 1) /(stride)) - 1))
+void         gegl_tile_set_rev        (GeglTile *tile,
+                                       guint     rev);
+guint        gegl_tile_get_rev        (GeglTile *tile);
 
+guchar      *gegl_tile_get_data       (GeglTile *tile);
 
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]