From 53624480440835c95ad55a23e449dd9420890f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Tue, 13 Mar 2012 03:17:33 +0000 Subject: [PATCH] GimpTileBackendTileManager: make it work remove dead code, simplify existing code and make full width tiles be 0-copy. --- app/gegl/gimptilebackendtilemanager.c | 283 ++++++-------------------- 1 file changed, 62 insertions(+), 221 deletions(-) diff --git a/app/gegl/gimptilebackendtilemanager.c b/app/gegl/gimptilebackendtilemanager.c index 46dab386c6..b55a27c32d 100644 --- a/app/gegl/gimptilebackendtilemanager.c +++ b/app/gegl/gimptilebackendtilemanager.c @@ -39,31 +39,13 @@ struct _GimpTileBackendTileManagerPrivate { - GHashTable *entries; TileManager *tile_manager; }; -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 void gimp_tile_backend_tile_manager_finalize (GObject *object); +static void gimp_tile_backend_tile_manager_dispose (GObject *object); static gpointer gimp_tile_backend_tile_manager_command (GeglTileSource *tile_store, GeglTileCommand command, gint x, @@ -71,21 +53,11 @@ static gpointer gimp_tile_backend_tile_manager_command (GeglTileSource *ti gint z, gpointer data); -static void dbg_alloc (int size); -static void dbg_dealloc (int size); -static RamEntry * lookup_entry (GimpTileBackendTileManager *self, +static void gimp_tile_write (GimpTileBackendTileManager *ram, gint x, gint y, - gint z); -static guint hash_func (gconstpointer key); -static gboolean equal_func (gconstpointer a, - gconstpointer b); -static void ram_entry_write (GimpTileBackendTileManager *ram, - RamEntry *entry, + gint z, 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, @@ -100,8 +72,7 @@ gimp_tile_backend_tile_manager_class_init (GimpTileBackendTileManagerClass *klas 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; + object_class->dispose = gimp_tile_backend_tile_manager_dispose; g_type_class_add_private (klass, sizeof (GimpTileBackendTileManagerPrivate)); } @@ -115,46 +86,32 @@ gimp_tile_backend_tile_manager_init (GimpTileBackendTileManager *backend) GIMP_TYPE_TILE_BACKEND_TILE_MANAGER, GimpTileBackendTileManagerPrivate); source->command = gimp_tile_backend_tile_manager_command; +} - backend->priv->entries = g_hash_table_new (hash_func, equal_func); +static void +gimp_tile_backend_tile_manager_dispose (GObject *object) +{ + GimpTileBackendTileManager *backend = GIMP_TILE_BACKEND_TILE_MANAGER (object); + g_warning ("gimp tile backend is dying!!!!!! %p\n", backend); + if (backend->priv->tile_manager) + { + tile_manager_unref (backend->priv->tile_manager); + backend->priv->tile_manager = NULL; + } + G_OBJECT_CLASS (parent_class)->dispose (object); } static void gimp_tile_backend_tile_manager_finalize (GObject *object) { GimpTileBackendTileManager *backend = GIMP_TILE_BACKEND_TILE_MANAGER (object); - - g_hash_table_unref (backend->priv->entries); - + g_warning ("gimp tile backend is dying!!!!!! %p\n", backend); 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) +static void tile_done (Tile *tile, void *data) { - 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; - } + tile_release (data, FALSE); } static gpointer @@ -184,20 +141,32 @@ gimp_tile_backend_tile_manager_command (GeglTileSource *tile_store, gimp_tile = tile_manager_get_at (backend_tm->priv->tile_manager, x, y, TRUE, FALSE); - + if (!gimp_tile) + return NULL; g_return_val_if_fail (gimp_tile != NULL, NULL); tile_size = gegl_tile_backend_get_tile_size (backend); tile_stride = TILE_WIDTH * tile_bpp (gimp_tile); gimp_tile_stride = tile_ewidth (gimp_tile) * tile_bpp (gimp_tile); - /* XXX: Point to Tile data directly instead of using memcpy */ - tile = gegl_tile_new (tile_size); - for (row = 0; row < tile_eheight (gimp_tile); row++) + if (tile_stride == gimp_tile_stride) { - memcpy (gegl_tile_get_data (tile) + row * tile_stride, - tile_data_pointer (gimp_tile, 0, row), - gimp_tile_stride); + /* use the GimpTile directly as GEGL tile */ + tile = gegl_tile_new_bare (); + gegl_tile_set_data_full (tile, tile_data_pointer (gimp_tile, 0, 0), + tile_size, tile_done, gimp_tile); + } + else + { + /* create a copy of the tile */ + tile = gegl_tile_new (tile_size); + for (row = 0; row < tile_eheight (gimp_tile); row++) + { + memcpy (gegl_tile_get_data (tile) + row * tile_stride, + tile_data_pointer (gimp_tile, 0, row), + gimp_tile_stride); + } + tile_release (gimp_tile, FALSE); } return tile; @@ -206,169 +175,49 @@ gimp_tile_backend_tile_manager_command (GeglTileSource *tile_store, 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->priv->entries, entry, entry); - } - - ram_entry_write (backend_tm, entry, gegl_tile_get_data (tile)); - + gimp_tile_write (backend_tm, x, y, z, 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 GINT_TO_POINTER (entry != NULL); - } - + return 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->priv->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 void -ram_entry_write (GimpTileBackendTileManager *ram, - RamEntry *entry, +gimp_tile_write (GimpTileBackendTileManager *backend_tm, + gint x, + gint y, + gint z, guchar *source) { - g_printerr ("WRITE %i %i %i\n", entry->x, entry->y, entry->z); - //memcpy (entry->offset, source, tile_size); -} + Tile *gimp_tile; + gint tile_stride; + gint gimp_tile_stride; + int row; -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); + gimp_tile = tile_manager_get_at (backend_tm->priv->tile_manager, + x, y, TRUE, TRUE); - self->offset = g_malloc (tile_size); - dbg_alloc (tile_size); + if (!gimp_tile) + return; - return self; -} + tile_stride = TILE_WIDTH * tile_bpp (gimp_tile); + gimp_tile_stride = tile_ewidth (gimp_tile) * tile_bpp (gimp_tile); -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->priv->entries, entry); - - dbg_dealloc (tile_size); - g_slice_free (RamEntry, entry); + for (row = 0; row < tile_eheight (gimp_tile); row++) + { + memcpy (tile_data_pointer (gimp_tile, 0, row), + source + row * tile_stride, + gimp_tile_stride); + } + tile_release (gimp_tile, FALSE); } GeglTileBackend * @@ -392,11 +241,3 @@ gimp_tile_backend_tile_manager_new (TileManager *tm) return 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); -}