[gimp] app: add GimpTileBackendTileManager which does nothing so far



commit 14536326789b9615378a086a9768227af4bf5f09
Author: Michael Natterer <mitch gimp org>
Date:   Sun Feb 13 22:48:00 2011 +0100

    app: add GimpTileBackendTileManager which does nothing so far
    
    but will help GEGL migration a lot.

 app/gegl/Makefile.am                  |    2 +
 app/gegl/gimptilebackendtilemanager.c |  431 +++++++++++++++++++++++++++++++++
 app/gegl/gimptilebackendtilemanager.h |   58 +++++
 3 files changed, 491 insertions(+), 0 deletions(-)
---
diff --git a/app/gegl/Makefile.am b/app/gegl/Makefile.am
index 38b4c42..33a7677 100644
--- a/app/gegl/Makefile.am
+++ b/app/gegl/Makefile.am
@@ -21,6 +21,8 @@ libappgegl_a_sources = \
 	gimp-gegl.h			\
 	gimp-gegl-utils.c		\
 	gimp-gegl-utils.h		\
+	gimptilebackendtilemanager.c	\
+	gimptilebackendtilemanager.h	\
 	\
 	gimpbrightnesscontrastconfig.c	\
 	gimpbrightnesscontrastconfig.h	\
diff --git a/app/gegl/gimptilebackendtilemanager.c b/app/gegl/gimptilebackendtilemanager.c
new file mode 100644
index 0000000..788fb17
--- /dev/null
+++ b/app/gegl/gimptilebackendtilemanager.c
@@ -0,0 +1,431 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimptilebackendtilemanager.c
+ * Copyright (C) 2011 �yvind Kolås <pippin gimp org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gegl.h>
+#include <gegl-buffer.h>
+
+#include "libgimpmath/gimpmath.h"
+
+#include "gimp-gegl-types.h"
+
+#include "base/tile.h"
+
+#include "gimptilebackendtilemanager.h"
+
+
+typedef struct _RamEntry RamEntry;
+
+struct _RamEntry
+{
+  gint    x;
+  gint    y;
+  gint    z;
+  guchar *offset;
+};
+
+
+static void     gimp_tile_backend_tile_manager_finalize     (GObject         *object);
+static void     gimp_tile_backend_tile_manager_set_property (GObject         *object,
+                                                             guint            property_id,
+                                                             const GValue    *value,
+                                                             GParamSpec      *pspec);
+static void     gimp_tile_backend_tile_manager_get_property (GObject         *object,
+                                                             guint            property_id,
+                                                             GValue          *value,
+                                                             GParamSpec      *pspec);
+static gpointer gimp_tile_backend_tile_manager_command      (GeglTileSource  *tile_store,
+                                                             GeglTileCommand  command,
+                                                             gint             x,
+                                                             gint             y,
+                                                             gint             z,
+                                                             gpointer         data);
+
+static void       dbg_alloc         (int                         size);
+static void       dbg_dealloc       (int                         size);
+static RamEntry * lookup_entry      (GimpTileBackendTileManager *self,
+                                     gint                        x,
+                                     gint                        y,
+                                     gint                        z);
+static guint      hash_func         (gconstpointer               key);
+static gboolean   equal_func        (gconstpointer               a,
+                                     gconstpointer               b);
+static void       ram_entry_read    (GimpTileBackendTileManager *ram,
+                                     gint                        x,
+                                     gint                        y,
+                                     gint                        z,
+                                     gfloat                      w,
+                                     gfloat                      h,
+                                     guchar                     *dest);
+static void       ram_entry_write   (GimpTileBackendTileManager *ram,
+                                     RamEntry                   *entry,
+                                     guchar                     *source);
+static RamEntry * ram_entry_new     (GimpTileBackendTileManager *ram);
+static void       ram_entry_destroy (RamEntry                   *entry,
+                                     GimpTileBackendTileManager *ram);
+
+
+G_DEFINE_TYPE (GimpTileBackendTileManager, gimp_tile_backend_tile_manager,
+               GEGL_TYPE_TILE_BACKEND)
+
+#define parent_class gimp_tile_backend_tile_manager_parent_class
+
+
+static void
+gimp_tile_backend_tile_manager_class_init (GimpTileBackendTileManagerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize     = gimp_tile_backend_tile_manager_finalize;
+  object_class->get_property = gimp_tile_backend_tile_manager_get_property;
+  object_class->set_property = gimp_tile_backend_tile_manager_set_property;
+}
+
+static void
+gimp_tile_backend_tile_manager_init (GimpTileBackendTileManager *backend)
+{
+  GeglTileSource *source = GEGL_TILE_SOURCE (backend);
+
+  source->command  = gimp_tile_backend_tile_manager_command;
+
+  backend->entries = g_hash_table_new (hash_func, equal_func);
+}
+
+static void
+gimp_tile_backend_tile_manager_finalize (GObject *object)
+{
+  GimpTileBackendTileManager *backend = GIMP_TILE_BACKEND_TILE_MANAGER (object);
+
+  g_hash_table_unref (backend->entries);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_tile_backend_tile_manager_set_property (GObject       *object,
+                                             guint          property_id,
+                                             const GValue *value,
+                                             GParamSpec    *pspec)
+{
+  switch (property_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_tile_backend_tile_manager_get_property (GObject    *object,
+                                             guint       property_id,
+                                             GValue     *value,
+                                             GParamSpec *pspec)
+{
+  switch (property_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static gpointer
+gimp_tile_backend_tile_manager_command (GeglTileSource  *tile_store,
+                                        GeglTileCommand  command,
+                                        gint             x,
+                                        gint             y,
+                                        gint             z,
+                                        gpointer         data)
+{
+  GimpTileBackendTileManager *backend_tm;
+  GeglTileBackend            *backend;
+
+  backend_tm = GIMP_TILE_BACKEND_TILE_MANAGER (tile_store);
+  backend    = GEGL_TILE_BACKEND (tile_store);
+
+  switch (command)
+    {
+    case GEGL_TILE_GET:
+      {
+        GeglTile *tile;
+        gint      tile_size = gegl_tile_backend_get_tile_size (backend);
+
+        tile = gegl_tile_new (tile_size);
+
+        ram_entry_read (backend_tm, x, y, z, TILE_WIDTH, TILE_HEIGHT,
+                        gegl_tile_get_data (tile));
+
+        return tile;
+      }
+
+    case GEGL_TILE_SET:
+      {
+        GeglTile *tile  = data;
+        RamEntry *entry = lookup_entry (backend_tm, x, y, z);
+
+        if (! entry)
+          {
+            entry    = ram_entry_new (backend_tm);
+            entry->x = x;
+            entry->y = y;
+            entry->z = z;
+
+            g_hash_table_insert (backend_tm->entries, entry, entry);
+          }
+
+        ram_entry_write (backend_tm, entry, gegl_tile_get_data (tile));
+
+        gegl_tile_mark_as_stored (tile);
+
+        return NULL;
+      }
+
+    case GEGL_TILE_IDLE:
+      return NULL;
+
+    case GEGL_TILE_VOID:
+      {
+        RamEntry *entry = lookup_entry (backend_tm, x, y, z);
+
+        if (entry)
+          ram_entry_destroy (entry, backend_tm);
+
+        return NULL;
+      }
+
+    case GEGL_TILE_EXIST:
+      {
+        RamEntry *entry = lookup_entry (backend_tm, x, y, z);
+
+        return (gpointer) (entry != NULL);
+      }
+
+    default:
+      g_assert (command < GEGL_TILE_LAST_COMMAND && command >= 0);
+    }
+
+  return NULL;
+}
+
+static gint allocs                 = 0;
+static gint ram_size               = 0;
+static gint peak_allocs            = 0;
+static gint peak_tile_manager_size = 0;
+
+static void
+dbg_alloc (gint size)
+{
+  allocs++;
+  ram_size += size;
+  if (allocs > peak_allocs)
+    peak_allocs = allocs;
+  if (ram_size > peak_tile_manager_size)
+    peak_tile_manager_size = ram_size;
+}
+
+static void
+dbg_dealloc (gint size)
+{
+  allocs--;
+  ram_size -= size;
+}
+
+static RamEntry *
+lookup_entry (GimpTileBackendTileManager *self,
+              gint                        x,
+              gint                        y,
+              gint                        z)
+{
+  RamEntry key;
+
+  key.x      = x;
+  key.y      = y;
+  key.z      = z;
+  key.offset = 0;
+
+  return g_hash_table_lookup (self->entries, &key);
+}
+
+static guint
+hash_func (gconstpointer key)
+{
+  const RamEntry *e = key;
+  guint           hash;
+  gint            srcA = e->x;
+  gint            srcB = e->y;
+  gint            srcC = e->z;
+  gint            i;
+
+  /* interleave the 10 least significant bits of all coordinates,
+   * this gives us Z-order / morton order of the space and should
+   * work well as a hash
+   */
+  hash = 0;
+
+#define ADD_BIT(bit)    do { hash |= (((bit) != 0) ? 1 : 0); hash <<= 1; \
+      }                                                                 \
+      while (0)
+
+  for (i = 9; i >= 0; i--)
+    {
+      ADD_BIT (srcA & (1 << i));
+      ADD_BIT (srcB & (1 << i));
+      ADD_BIT (srcC & (1 << i));
+    }
+
+#undef ADD_BIT
+
+  return hash;
+}
+
+static gboolean
+equal_func (gconstpointer a,
+            gconstpointer b)
+{
+  const RamEntry *ea = a;
+  const RamEntry *eb = b;
+
+  if (ea->x == eb->x &&
+      ea->y == eb->y &&
+      ea->z == eb->z)
+    return TRUE;
+
+  return FALSE;
+}
+
+static gfloat
+mandel_calc (gfloat x,
+             gfloat y)
+{
+  gfloat fCReal = x;
+  gfloat fCImg  = y;
+  gfloat fZReal = fCReal;
+  gfloat fZImg  = fCImg;
+#define MAX_ITER 100
+
+  gint n;
+
+  for (n=0; n< MAX_ITER; n++)
+    {
+      gfloat fZRealSquared = fZReal * fZReal;
+      gfloat fZImgSquared = fZImg * fZImg;
+
+      if (fZRealSquared + fZImgSquared > 4)
+        return 1.0*n/(MAX_ITER);
+
+/*              -- z = z^2 + c*/
+      fZImg = 2 * fZReal * fZImg + fCImg;
+      fZReal = fZRealSquared - fZImgSquared + fCReal;
+    }
+  return 1.0;
+}
+
+static void
+ram_entry_read (GimpTileBackendTileManager *ram,
+                gint                        x,
+                gint                        y,
+                gint                        z,
+                gfloat                      w,
+                gfloat                      h,
+                guchar                     *dest)
+{
+  GeglTileBackend *backend = GEGL_TILE_BACKEND (ram);
+  Babl            *format  = gegl_tile_backend_get_format (backend);
+  gint             u, v;
+  gint             i = 0;
+
+  g_printerr ("%s\n", babl_get_name (format));
+  g_printerr ("READ %i %i %i\n", x, y, z);
+
+  for (v = 0; v < h; v++)
+    for (u = 0; u < w; u++)
+      {
+        float a   = ((u + x * w) * powf (2,z) - 2 * w);
+        float b   = ((v + y * h) * powf (2,z) - 1 * h);
+        float val =
+          mandel_calc (a / w,
+                       b / h);
+        dest[i*4+0] = val * 255;
+        dest[i*4+1] = val * 255;
+        dest[i*4+2] = val * 255;
+        dest[i*4+3] = 255;
+        i++;
+      }
+}
+
+static void
+ram_entry_write (GimpTileBackendTileManager *ram,
+                 RamEntry                   *entry,
+                 guchar                     *source)
+{
+  g_printerr ("WRITE %i %i %i\n", entry->x, entry->y, entry->z);
+  //memcpy (entry->offset, source, tile_size);
+}
+
+static RamEntry *
+ram_entry_new (GimpTileBackendTileManager *ram)
+{
+  gint tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (ram));
+  RamEntry *self = g_slice_new (RamEntry);
+
+  self->offset = g_malloc (tile_size);
+  dbg_alloc (tile_size);
+
+  return self;
+}
+
+static void
+ram_entry_destroy (RamEntry           *entry,
+                   GimpTileBackendTileManager *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 (tile_size);
+  g_slice_free (RamEntry, entry);
+}
+
+GeglTileBackend *
+gimp_tile_backend_tile_manager_new (void)
+{
+  GimpTileBackendTileManager *ret =
+    g_object_new (GIMP_TYPE_TILE_BACKEND_TILE_MANAGER,
+                  "tile-width",  TILE_WIDTH,
+                  "tile-height", TILE_HEIGHT,
+                  "format", babl_format ("RGBA u8"),
+                  NULL);
+  GeglRectangle rect = { 100,100, 200, 200 };
+
+  gegl_tile_backend_set_extent (GEGL_TILE_BACKEND (ret), &rect);
+
+  return GEGL_TILE_BACKEND (ret);
+}
+
+void
+gimp_tile_backend_tile_manager_stats (void)
+{
+  g_warning ("leaked: %i chunks (%f mb)  peak: %i (%i bytes %fmb))",
+             allocs, ram_size / 1024 / 1024.0, peak_allocs,
+             peak_tile_manager_size, peak_tile_manager_size / 1024 / 1024.0);
+}
diff --git a/app/gegl/gimptilebackendtilemanager.h b/app/gegl/gimptilebackendtilemanager.h
new file mode 100644
index 0000000..1aff9c5
--- /dev/null
+++ b/app/gegl/gimptilebackendtilemanager.h
@@ -0,0 +1,58 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimptilebackendtilemanager.h
+ * Copyright (C) 2011 �yvind Kolås <pippin gimp org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_TILE_BACKEND_TILE_MANAGER_H__
+#define __GIMP_TILE_BACKEND_TILE_MANAGER_H__
+
+#include "gegl-buffer-backend.h"
+
+G_BEGIN_DECLS
+
+#define GIMP_TYPE_TILE_BACKEND_TILE_MANAGER            (gimp_tile_backend_tile_manager_get_type ())
+#define GIMP_TILE_BACKEND_TILE_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_TILE_BACKEND_TILE_MANAGER, GimpTileBackendTileManager))
+#define GIMP_TILE_BACKEND_TILE_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GIMP_TYPE_TILE_BACKEND_TILE_MANAGER, GimpTileBackendTileManagerClass))
+#define GIMP_IS_TILE_BACKEND_TILE_MANAGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_TILE_BACKEND_TILE_MANAGER))
+#define GIMP_IS_TILE_BACKEND_TILE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GIMP_TYPE_TILE_BACKEND_TILE_MANAGER))
+#define GIMP_TILE_BACKEND_TILE_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GIMP_TYPE_TILE_BACKEND_TILE_MANAGER, GimpTileBackendTileManagerClass))
+
+typedef struct _GimpTileBackendTileManager      GimpTileBackendTileManager;
+typedef struct _GimpTileBackendTileManagerClass GimpTileBackendTileManagerClass;
+
+struct _GimpTileBackendTileManager
+{
+  GeglTileBackend  parent_instance;
+
+  GHashTable      *entries;
+};
+
+struct _GimpTileBackendTileManagerClass
+{
+  GeglTileBackendClass parent_class;
+};
+
+GType             gimp_tile_backend_tile_manager_get_type (void) G_GNUC_CONST;
+
+GeglTileBackend * gimp_tile_backend_tile_manager_new      (void);
+
+void              gimp_tile_backend_tile_manager_stats    (void);
+
+G_END_DECLS
+
+#endif /* __GIMP_TILE_BACKEND_TILE_MANAGER_H__ */



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