[gegl/pluggable-buffer] Make it possible to provide external tile backends



commit 3d2ca13d5a8b453dc3bc9ae896fc4f7748e9c029
Author: �yvind Kolås <pippin gimp org>
Date:   Sat Nov 6 23:42:53 2010 +0000

    Make it possible to provide external tile backends
    
    Added construction function gegl_buffer_new_custom and install the headers
    required to implement out of tree tile backends for GeglBuffer. Also refactored
    some of the internals to permit such pluggable back-ends.

 gegl/Makefile.am                    |    5 ++
 gegl/buffer/gegl-buffer-private.h   |    2 +
 gegl/buffer/gegl-buffer-types.h     |    2 -
 gegl/buffer/gegl-buffer.c           |   91 +++++++++++++++++++++++++++++++---
 gegl/buffer/gegl-buffer.h           |   11 ++++
 gegl/buffer/gegl-tile-backend-ram.c |    6 --
 gegl/buffer/gegl-tile-backend.h     |    2 -
 gegl/buffer/gegl-tile-storage.c     |   52 ++++----------------
 gegl/buffer/gegl-tile-storage.h     |    6 +--
 9 files changed, 113 insertions(+), 64 deletions(-)
---
diff --git a/gegl/Makefile.am b/gegl/Makefile.am
index b4b2c43..d031e71 100644
--- a/gegl/Makefile.am
+++ b/gegl/Makefile.am
@@ -37,6 +37,11 @@ GEGL_public_HEADERS =	\
     gegl-version.h			\
     buffer/gegl-buffer.h		\
     buffer/gegl-buffer-iterator.h	\
+    buffer/gegl-buffer-backend.h	\
+    buffer/gegl-tile-backend.h		\
+    buffer/gegl-tile-source.h		\
+    buffer/gegl-tile.h			\
+    buffer/gegl-buffer-types.h		\
     property-types/gegl-paramspecs.h	\
     property-types/gegl-color.h		\
     property-types/gegl-path.h		\
diff --git a/gegl/buffer/gegl-buffer-private.h b/gegl/buffer/gegl-buffer-private.h
index 33a14e9..286035e 100644
--- a/gegl/buffer/gegl-buffer-private.h
+++ b/gegl/buffer/gegl-buffer-private.h
@@ -71,6 +71,8 @@ struct _GeglBuffer
 
   gchar            *alloc_stack_trace; /* Stack trace for allocation,
                                           useful for debugging */
+
+  gpointer          backend;
 };
 
 struct _GeglBufferClass
diff --git a/gegl/buffer/gegl-buffer-types.h b/gegl/buffer/gegl-buffer-types.h
index 3e6d48f..d94c8b8 100644
--- a/gegl/buffer/gegl-buffer-types.h
+++ b/gegl/buffer/gegl-buffer-types.h
@@ -19,8 +19,6 @@
 #ifndef __GEGL_BUFFER_TYPES_H__
 #define __GEGL_BUFFER_TYPES_H__
 
-
-
 typedef struct _GeglTile                  GeglTile;
 typedef struct _GeglTileClass             GeglTileClass;
 
diff --git a/gegl/buffer/gegl-buffer.c b/gegl/buffer/gegl-buffer.c
index f249077..6f00355 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);
@@ -488,7 +498,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 +541,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);
 
@@ -821,6 +853,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,
@@ -986,6 +1023,29 @@ gegl_buffer_new (const GeglRectangle *extent,
                        NULL);
 }
 
+GeglBuffer *
+gegl_buffer_new_for_backend (const GeglRectangle *extent,
+                             const Babl          *format,
+                             gpointer             backend)
+{
+  GeglRectangle empty={0,0,0,0};
+
+  if (extent==NULL)
+    extent = &empty;
+
+  if (format==NULL)
+    format = babl_format ("RGBA float");
+
+  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
@@ -1056,11 +1116,18 @@ gegl_buffer_new_from_format (const void *babl_fmt,
       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);
+      GeglTileBackend *backend;
+      backend = g_object_new (GEGL_TYPE_TILE_BACKEND_RAM,
+                              "tile-width", tile_width,
+                              "tile-height", tile_height,
+                              "format", babl_fmt,
+                              NULL);
+      tile_storage = gegl_tile_storage_new (backend);
     }
   else
     {
       static gint no = 1;
+      GeglTileBackend *backend;
 
       gchar *filename;
       gchar *path;
@@ -1072,12 +1139,20 @@ gegl_buffer_new_from_format (const void *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);
+      backend = g_object_new (GEGL_TYPE_TILE_BACKEND_FILE,
+                              "tile-width", tile_width,
+                              "tile-height", tile_height,
+                              "format", babl_fmt,
+                              "path", path,
+                              NULL);
+
+      tile_storage = gegl_tile_storage_new (backend);
       g_free (path);
     }
 
diff --git a/gegl/buffer/gegl-buffer.h b/gegl/buffer/gegl-buffer.h
index bee1c98..f15f926 100644
--- a/gegl/buffer/gegl-buffer.h
+++ b/gegl/buffer/gegl-buffer.h
@@ -57,6 +57,17 @@ GType           gegl_buffer_get_type          (void) G_GNUC_CONST;
 GeglBuffer*     gegl_buffer_new               (const GeglRectangle *extent,
                                                const Babl          *format);
 
+GeglBuffer *
+gegl_buffer_new_custom  (const GeglRectangle *extent,
+                         const Babl          *format,
+                         GType                backend,
+                         gpointer             backend_data);
+
+
+GeglBuffer *
+gegl_buffer_new_for_backend (const GeglRectangle *extent,
+                             const Babl          *format,
+                             gpointer             backend);
 
 /**
  * gegl_buffer_open:
diff --git a/gegl/buffer/gegl-tile-backend-ram.c b/gegl/buffer/gegl-tile-backend-ram.c
index 1e335fd..8213bff 100644
--- a/gegl/buffer/gegl-tile-backend-ram.c
+++ b/gegl/buffer/gegl-tile-backend-ram.c
@@ -29,12 +29,6 @@
 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
diff --git a/gegl/buffer/gegl-tile-backend.h b/gegl/buffer/gegl-tile-backend.h
index d26d702..467a0f8 100644
--- a/gegl/buffer/gegl-tile-backend.h
+++ b/gegl/buffer/gegl-tile-backend.h
@@ -50,8 +50,6 @@ struct _GeglTileBackendClass
 {
   GeglTileSourceClass parent_class;
 
-  void (* create)  (GeglTileBackend *backend); 
-  void (* destroy) (GeglTileBackend *backend);
 };
 
 GType gegl_tile_backend_get_type (void) G_GNUC_CONST;
diff --git a/gegl/buffer/gegl-tile-storage.c b/gegl/buffer/gegl-tile-storage.c
index 43beda3..b86df67 100644
--- a/gegl/buffer/gegl-tile-storage.c
+++ b/gegl/buffer/gegl-tile-storage.c
@@ -66,66 +66,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);
-
-  tile_handler_chain = GEGL_TILE_HANDLER_CHAIN (tile_storage);
-  handler  = GEGL_TILE_HANDLER (tile_storage);
 
-  if (tile_storage->path != NULL)
+  if (g_object_class_find_property (G_OBJECT_GET_CLASS (backend), "path"))
     {
-#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);
+      g_object_get (backend, "path", &tile_storage->path, NULL);
     }
 
+  tile_handler_chain = GEGL_TILE_HANDLER_CHAIN (tile_storage);
+  handler  = GEGL_TILE_HANDLER (tile_storage);
+
+  tile_storage->tile_width = backend->tile_width;
+  tile_storage->tile_height = backend->tile_height;
+  tile_storage->format = backend->format;
   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
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



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