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 = \ ...@@ -36,6 +36,10 @@ GEGL_public_HEADERS = \
gegl-version.h \ gegl-version.h \
buffer/gegl-buffer.h \ buffer/gegl-buffer.h \
buffer/gegl-buffer-iterator.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-paramspecs.h \
property-types/gegl-color.h \ property-types/gegl-color.h \
property-types/gegl-path.h \ property-types/gegl-path.h \
......
...@@ -303,12 +303,14 @@ gegl_buffer_flush (GeglBuffer *buffer) ...@@ -303,12 +303,14 @@ gegl_buffer_flush (GeglBuffer *buffer)
gegl_tile_unref (buffer->hot_tile); gegl_tile_unref (buffer->hot_tile);
buffer->hot_tile = NULL; buffer->hot_tile = NULL;
} }
if ((GeglBufferHeader*)(backend->header))
if ((GeglBufferHeader*)(backend->priv->header))
{ {
((GeglBufferHeader*)(backend->header))->x =buffer->extent.x; GeglBufferHeader* header = backend->priv->header;
((GeglBufferHeader*)(backend->header))->y =buffer->extent.y; header->x = buffer->extent.x;
((GeglBufferHeader*)(backend->header))->width =buffer->extent.width; header->y = buffer->extent.y;
((GeglBufferHeader*)(backend->header))->height =buffer->extent.height; header->width =buffer->extent.width;
header->height =buffer->extent.height;
} }
gegl_tile_source_command (GEGL_TILE_SOURCE (buffer), gegl_tile_source_command (GEGL_TILE_SOURCE (buffer),
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#ifndef __GEGL_BUFFER_PRIVATE_H__ #ifndef __GEGL_BUFFER_PRIVATE_H__
#define __GEGL_BUFFER_PRIVATE_H__ #define __GEGL_BUFFER_PRIVATE_H__
#include "gegl-buffer-types.h"
#include "gegl-buffer.h" #include "gegl-buffer.h"
#include "gegl-sampler.h" #include "gegl-sampler.h"
#include "gegl-tile-handler.h" #include "gegl-tile-handler.h"
...@@ -71,6 +72,8 @@ struct _GeglBuffer ...@@ -71,6 +72,8 @@ struct _GeglBuffer
gchar *alloc_stack_trace; /* Stack trace for allocation, gchar *alloc_stack_trace; /* Stack trace for allocation,
useful for debugging */ useful for debugging */
gpointer backend;
}; };
struct _GeglBufferClass struct _GeglBufferClass
...@@ -130,4 +133,65 @@ void gegl_buffer_sampler (GeglBuffer *buffer, ...@@ -130,4 +133,65 @@ void gegl_buffer_sampler (GeglBuffer *buffer,
gpointer sampler); 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 #endif
...@@ -19,16 +19,33 @@ ...@@ -19,16 +19,33 @@
#ifndef __GEGL_BUFFER_TYPES_H__ #ifndef __GEGL_BUFFER_TYPES_H__
#define __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; /* gegl-buffer-types.h is not installed, thus all of this is private to
typedef struct _GeglTileSourceClass GeglTileSourceClass; * 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 _GeglTileHandler GeglTileHandler;
typedef struct _GeglTileHandlerClass GeglTileHandlerClass; typedef struct _GeglTileHandlerClass GeglTileHandlerClass;
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include "gegl-tile-storage.h" #include "gegl-tile-storage.h"
#include "gegl-tile-backend.h" #include "gegl-tile-backend.h"
#include "gegl-tile-backend-file.h" #include "gegl-tile-backend-file.h"
#include "gegl-tile-backend-ram.h"
#include "gegl-tile.h" #include "gegl-tile.h"
#include "gegl-tile-handler-cache.h" #include "gegl-tile-handler-cache.h"
#include "gegl-tile-handler-log.h" #include "gegl-tile-handler-log.h"
...@@ -107,7 +108,8 @@ enum ...@@ -107,7 +108,8 @@ enum
PROP_FORMAT, PROP_FORMAT,
PROP_PX_SIZE, PROP_PX_SIZE,
PROP_PIXELS, PROP_PIXELS,
PROP_PATH PROP_PATH,
PROP_BACKEND
}; };
enum { enum {
...@@ -199,6 +201,10 @@ gegl_buffer_get_property (GObject *gobject, ...@@ -199,6 +201,10 @@ gegl_buffer_get_property (GObject *gobject,
g_value_set_pointer (value, (void*)buffer->format); /* Eeeek? */ g_value_set_pointer (value, (void*)buffer->format); /* Eeeek? */
break; break;
case PROP_BACKEND:
g_value_set_pointer (value, buffer->backend);
break;
case PROP_X: case PROP_X:
g_value_set_int (value, buffer->extent.x); g_value_set_int (value, buffer->extent.x);
break; break;
...@@ -293,6 +299,10 @@ gegl_buffer_set_property (GObject *gobject, ...@@ -293,6 +299,10 @@ gegl_buffer_set_property (GObject *gobject,
if (g_value_get_pointer (value)) if (g_value_get_pointer (value))
buffer->format = g_value_get_pointer (value); buffer->format = g_value_get_pointer (value);
break; break;
case PROP_BACKEND:
if (g_value_get_pointer (value))
buffer->backend = g_value_get_pointer (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
...@@ -317,9 +327,10 @@ gegl_buffer_set_extent (GeglBuffer *buffer, ...@@ -317,9 +327,10 @@ gegl_buffer_set_extent (GeglBuffer *buffer,
g_return_val_if_fail(GEGL_IS_BUFFER(buffer), FALSE); g_return_val_if_fail(GEGL_IS_BUFFER(buffer), FALSE);
(*(GeglRectangle*)gegl_buffer_get_extent (buffer))=*extent; (*(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->x = buffer->extent.x;
header->y = buffer->extent.y; header->y = buffer->extent.y;
header->width = buffer->extent.width; header->width = buffer->extent.width;
...@@ -488,7 +499,26 @@ gegl_buffer_constructor (GType type, ...@@ -488,7 +499,26 @@ gegl_buffer_constructor (GType type,
* source (this adds a redirection buffer in between for * source (this adds a redirection buffer in between for
* all "allocated from format", type buffers. * 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, source = GEGL_TILE_SOURCE (gegl_buffer_new_from_format (buffer->format,
buffer->extent.x, buffer->extent.x,
...@@ -512,10 +542,13 @@ gegl_buffer_constructor (GType type, ...@@ -512,10 +542,13 @@ gegl_buffer_constructor (GType type,
GeglBufferHeader *header; GeglBufferHeader *header;
void *storage; void *storage;
if (buffer->format) backend = g_object_new (GEGL_TYPE_TILE_BACKEND_FILE,
storage = gegl_tile_storage_new (-1, -1, buffer->format, buffer->path); "tile-width", 128,
else "tile-height", 64,
storage = gegl_tile_storage_new (-1, -1, babl_format ("RGBA float"), buffer->path); "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); source = g_object_new (GEGL_TYPE_BUFFER, "source", storage, NULL);
...@@ -531,12 +564,12 @@ gegl_buffer_constructor (GType type, ...@@ -531,12 +564,12 @@ gegl_buffer_constructor (GType type,
g_assert (source); g_assert (source);
backend = gegl_buffer_backend (GEGL_BUFFER (source)); backend = gegl_buffer_backend (GEGL_BUFFER (source));
g_assert (backend); g_assert (backend);
header = backend->header; header = backend->priv->header;
buffer->extent.x = header->x; buffer->extent.x = header->x;
buffer->extent.y = header->y; buffer->extent.y = header->y;
buffer->extent.width = header->width; buffer->extent.width = header->width;
buffer->extent.height = header->height; buffer->extent.height = header->height;
buffer->format = backend->format; buffer->format = gegl_tile_backend_get_format (backend);
} }
else if (buffer->format) else if (buffer->format)
{ {
...@@ -578,8 +611,8 @@ gegl_buffer_constructor (GType type, ...@@ -578,8 +611,8 @@ gegl_buffer_constructor (GType type,
g_assert (backend); g_assert (backend);
tile_width = backend->tile_width; tile_width = backend->priv->tile_width;
tile_height = backend->tile_height; tile_height = backend->priv->tile_height;
if (buffer->extent.width == -1 && if (buffer->extent.width == -1 &&
buffer->extent.height == -1) /* no specified extents, buffer->extent.height == -1) /* no specified extents,
...@@ -642,7 +675,7 @@ gegl_buffer_constructor (GType type, ...@@ -642,7 +675,7 @@ gegl_buffer_constructor (GType type,
parent.y = GEGL_BUFFER (source)->abyss.y - buffer->shift_y; parent.y = GEGL_BUFFER (source)->abyss.y - buffer->shift_y;
parent.width = GEGL_BUFFER (source)->abyss.width; parent.width = GEGL_BUFFER (source)->abyss.width;
parent.height = GEGL_BUFFER (source)->abyss.height; parent.height = GEGL_BUFFER (source)->abyss.height;
request.x = buffer->abyss.x; request.x = buffer->abyss.x;
request.y = buffer->abyss.y; request.y = buffer->abyss.y;
request.width = buffer->abyss.width; request.width = buffer->abyss.width;
...@@ -821,6 +854,11 @@ gegl_buffer_class_init (GeglBufferClass *class) ...@@ -821,6 +854,11 @@ gegl_buffer_class_init (GeglBufferClass *class)
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_CONSTRUCT)); 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_object_class_install_property (gobject_class, PROP_TILE_HEIGHT,
g_param_spec_int ("tile-height", "tile-height", "height of a tile", g_param_spec_int ("tile-height", "tile-height", "height of a tile",
-1, G_MAXINT, gegl_config()->tile_height, -1, G_MAXINT, gegl_config()->tile_height,
...@@ -988,6 +1026,36 @@ gegl_buffer_new (const GeglRectangle *extent, ...@@ -988,6 +1026,36 @@ gegl_buffer_new (const GeglRectangle *extent,
NULL); 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 /* FIXME: this function needs optimizing, perhaps keep a pool
* of GeglBuffer shells that can be adapted to the needs * 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, ...@@ -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") ||
g_str_equal (gegl_config()->swap, "ram")) g_str_equal (gegl_config()->swap, "ram"))
{ {
GeglTileBackend *backend;
item->ram = TRUE; 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 else
{ {
static gint no = 1; static gint no = 1;
GeglTileBackend *backend;
gchar *filename; gchar *filename;
gchar *path; gchar *path;
...@@ -1133,7 +1208,13 @@ gegl_tile_storage_new_cached (gint tile_width, gint tile_height, ...@@ -1133,7 +1208,13 @@ gegl_tile_storage_new_cached (gint tile_width, gint tile_height,
path = g_build_filename (gegl_config()->swap, filename, NULL); path = g_build_filename (gegl_config()->swap, filename, NULL);
g_free (filename); 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); g_free (path);
} }
item->storage = storage; item->storage = storage;
...@@ -1180,7 +1261,7 @@ static const void *gegl_buffer_internal_get_format (GeglBuffer *buffer) ...@@ -1180,7 +1261,7 @@ static const void *gegl_buffer_internal_get_format (GeglBuffer *buffer)
g_assert (buffer); g_assert (buffer);
if (buffer->format != NULL) if (buffer->format != NULL)
return buffer->format; return buffer->format;
return gegl_buffer_backend (buffer)->format; return gegl_tile_backend_get_format (gegl_buffer_backend (buffer));
} }
static void static void
...@@ -1248,7 +1329,7 @@ const Babl *gegl_buffer_get_format (GeglBuffer *buffer) ...@@ -1248,7 +1329,7 @@ const Babl *gegl_buffer_get_format (GeglBuffer *buffer)
gboolean gegl_buffer_is_shared (GeglBuffer *buffer) gboolean gegl_buffer_is_shared (GeglBuffer *buffer)
{ {
GeglTileBackend *backend = gegl_buffer_backend (buffer); GeglTileBackend *backend = gegl_buffer_backend (buffer);
return backend->shared; return backend->priv->shared;
} }
gboolean gegl_buffer_try_lock (GeglBuffer *buffer) gboolean gegl_buffer_try_lock (GeglBuffer *buffer)
......
...@@ -58,6 +58,21 @@ GeglBuffer* gegl_buffer_new (const GeglRectangle *extent, ...@@ -58,6 +58,21 @@ GeglBuffer* gegl_buffer_new (const GeglRectangle *extent,
const Babl *format); 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: * gegl_buffer_open:
* @path: the path to a gegl buffer on disk. * @path: the path to a gegl buffer on disk.
......
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
#include "gegl-tile-backend.h" #include "gegl-tile-backend.h"
#include "gegl-tile-backend-file.h" #include "gegl-tile-backend-file.h"
#include "gegl-buffer-index.h" #include "gegl-buffer-index.h"
#include "gegl-buffer-types.h"
#include "gegl-debug.h" #include "gegl-debug.h"
#include "gegl-types-internal.h" //#include "gegl-types-internal.h"
struct _GeglTileBackendFile struct _GeglTileBackendFile
...@@ -134,7 +135,7 @@ gegl_tile_backend_file_file_entry_read (GeglTileBackendFile *self, ...@@ -134,7 +135,7 @@ gegl_tile_backend_file_file_entry_read (GeglTileBackendFile *self,
{ {
gint to_be_read; gint to_be_read;
gboolean success; 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; goffset offset = entry->offset;
gegl_tile_backend_file_ensure_exist (self); gegl_tile_backend_file_ensure_exist (self);
...@@ -185,7 +186,7 @@ gegl_tile_backend_file_file_entry_write (GeglTileBackendFile *self, ...@@ -185,7 +186,7 @@ gegl_tile_backend_file_file_entry_write (GeglTileBackendFile *self,
{ {
gint to_be_written; gint to_be_written;
gboolean success; 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; goffset offset = entry->offset;
gegl_tile_backend_file_ensure_exist (self); gegl_tile_backend_file_ensure_exist (self);
...@@ -248,7 +249,7 @@ gegl_tile_backend_file_file_entry_new (GeglTileBackendFile *self) ...@@ -248,7 +249,7 @@ gegl_tile_backend_file_file_entry_new (GeglTileBackendFile *self)
} }
else 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; entry->offset = self->next_pre_alloc;
GEGL_NOTE (GEGL_DEBUG_TILE_BACKEND, " set offset %i (next allocation)", (gint)entry->offset); 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) ...@@ -268,7 +269,7 @@ gegl_tile_backend_file_file_entry_new (GeglTileBackendFile *self)
#endif #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; return entry;
} }
...@@ -282,7 +283,7 @@ gegl_tile_backend_file_file_entry_destroy (GeglBufferTile *entry, ...@@ -282,7 +283,7 @@ gegl_tile_backend_file_file_entry_destroy (GeglBufferTile *entry,
GUINT_TO_POINTER (offset)); GUINT_TO_POINTER (offset));
g_hash_table_remove (self->index, entry); 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); g_free (entry);
} }
...@@ -449,11 +450,11 @@ gegl_tile_backend_file_get_tile (GeglTileSource *self, ...@@ -449,11 +450,11 @@ gegl_tile_backend_file_get_tile (GeglTileSource *self,
gint y, gint y,
gint z) gint z)
{ {
GeglTileBackend *backend; GeglTileBackend *backend;
GeglTileBackendFile *tile_backend_file; GeglTileBackendFile *tile_backend_file;
GeglBufferTile *entry; GeglBufferTile *entry;
GeglTile *tile = NULL; GeglTile *tile = NULL;
gint tile_size;
backend = GEGL_TILE_BACKEND (self); backend = GEGL_TILE_BACKEND (self);
tile_backend_file = GEGL_TILE_BACKEND_FILE (backend); tile_backend_file = GEGL_TILE_BACKEND_FILE (backend);
...@@ -462,8 +463,9 @@ gegl_tile_backend_file_get_tile (GeglTileSource *self, ...@@ -462,8 +463,9 @@ gegl_tile_backend_file_get_tile (GeglTileSource *self,
if (!entry) if (!entry)
return NULL; return NULL;
tile = gegl_tile_new (backend->tile_size); tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self));
tile->rev = entry->rev; tile = gegl_tile_new (tile_size);
gegl_tile_set_rev (tile, entry->rev);
gegl_tile_mark_as_stored (tile); gegl_tile_mark_as_stored (tile);
gegl_tile_backend_file_file_entry_read (tile_backend_file, entry, gegl_tile_get_data (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, ...@@ -493,7 +495,7 @@ gegl_tile_backend_file_set_tile (GeglTileSource *self,
entry->z = z; entry->z = z;
g_hash_table_insert (tile_backend_file->index, entry, entry); 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_backend_file_file_entry_write (tile_backend_file, entry, gegl_tile_get_data (tile));
gegl_tile_mark_as_stored (tile); gegl_tile_mark_as_stored (tile);
...@@ -779,6 +781,7 @@ gegl_tile_backend_file_load_index (GeglTileBackendFile *self, ...@@ -779,6 +781,7 @@ gegl_tile_backend_file_load_index (GeglTileBackendFile *self,
GeglTileBackend *backend; GeglTileBackend *backend;
goffset offset = 0; goffset offset = 0;
goffset max=0; goffset max=0;
gint tile_size;
/* compute total from and next pre alloc by monitoring tiles as they /* compute total from and next pre alloc by monitoring tiles as they
* are added here * are added here
...@@ -804,6 +807,7 @@ gegl_tile_backend_file_load_index (GeglTileBackendFile *self, ...@@ -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; offset = self->header.next;
self->tiles = gegl_buffer_read_index (self->i, &offset); self->tiles = gegl_buffer_read_index (self->i, &offset);
backend = GEGL_TILE_BACKEND (self); backend = GEGL_TILE_BACKEND (self);
...@@ -815,7 +819,7 @@ gegl_tile_backend_file_load_index (GeglTileBackendFile *self, ...@@ -815,7 +819,7 @@ gegl_tile_backend_file_load_index (GeglTileBackendFile *self,
GeglBufferItem *existing = g_hash_table_lookup (self->index, item);