GitLab repository storage has been migrated to hashed layout. Please contact Infrastructure team if you notice any issues with repositories or hooks.

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.
parent dac21927
......@@ -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 \
......
......@@ -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),
......
......@@ -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
......@@ -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;
......
......@@ -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)
......
......@@ -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.
......
......@@ -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
......
......@@ -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));
}
......
......@@ -23,6 +23,7 @@
#include <string.h>
#include <errno.h>