Commit 5137a134 authored by Øyvind Kolås's avatar Øyvind Kolås

added new tiled buffer implementation

parent bf123bc9
......@@ -208,6 +208,7 @@ gil/Makefile
gil/gil/Makefile
gil/tests/Makefile
gegl/Makefile
gegl/buffer/Makefile
tools/Makefile
tools/testsuite/Makefile
tests/Makefile
......
noinst_PROGRAMS =
SUBDIRS = buffer
libbuffer = $(top_builddir)/gegl/buffer/libbuffer.la
lib_LTLIBRARIES = libgegl-1.0.la
GEGL_sources = \
......@@ -36,6 +40,8 @@ GEGL_public_headers = \
libgegl_1_0_la_SOURCES = $(GEGL_sources) $(GEGL_public_headers)
libgegl_1_0_la_LIBADD = $(libbuffer)
INCLUDES = \
-I$(top_srcdir) \
@DEP_CFLAGS@
......
noinst_LTLIBRARIES = libbuffer.la
BUFFER_sources = \
gegl-buffer-allocator.c \
gegl-buffer.c \
gegl-storage.c \
gegl-tile-abyss.c \
gegl-tile-backend.c \
gegl-tile.c \
gegl-tile-cache.c \
gegl-tile-empty.c \
gegl-tile-log.c \
gegl-tile-mem.c \
gegl-tile-store.c \
gegl-tile-trait.c \
gegl-tile-traits.c
BUFFER_headers = \
gegl-buffer-allocator.h \
gegl-buffer.h \
gegl-buffer-types.h \
gegl-storage.h \
gegl-tile-abyss.h \
gegl-tile-backend.h \
gegl-tile-cache.h \
gegl-tile-empty.h \
gegl-tile.h \
gegl-tile-log.h \
gegl-tile-mem.h \
gegl-tile-store.h \
gegl-tile-trait.h \
gegl-tile-traits.h
libbuffer_la_SOURCES = $(BUFFER_sources) $(BUFFER_headers)
INCLUDES = \
-I$(top_srcdir) \
-I$(top_srcdir)/gegl \
@DEP_CFLAGS@
/* This file is part of GEGL.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Copyright 2006 Øyvind Kolås <pippin@gimp.org>
*/
#include <glib.h>
#include <glib/gprintf.h>
#include <glib/gstdio.h>
#include "gegl-buffer-types.h"
#include "gegl-storage.h"
#include "gegl-buffer-allocator.h"
G_DEFINE_TYPE(GeglBufferAllocator, gegl_buffer_allocator, GEGL_TYPE_BUFFER)
static GObjectClass *parent_class = NULL;
static void
gegl_buffer_allocator_class_init (GeglBufferAllocatorClass *class)
{
parent_class = g_type_class_peek_parent (class);
}
static void
gegl_buffer_allocator_init (GeglBufferAllocator *allocator)
{
allocator->x_used =0 ;
allocator->y_used =0 ;
}
#include "gegl-buffer.h"
static GeglBuffer *
gegl_buffer_alloc (GeglBufferAllocator *allocator,
gint x,
gint y,
gint width,
gint height)
{
GeglBuffer *buffer = GEGL_BUFFER (allocator);
GeglStorage *storage = gegl_buffer_storage (buffer);
gint tile_width = storage->tile_width;
gint tile_height = storage->tile_height;
/*gint needed_width = ((width-1)/tile_width+1)*tile_width;
* FIXME: compensating for something that probably is abyss issues
*/
gint needed_width = ((width-1)/tile_width+42)*tile_width;
gint needed_height = ((height-1)/tile_height+42)*tile_height;
gint shift_x;
gint shift_y;
g_assert (allocator);
if (needed_width > buffer->width)
{
g_warning ("requested a %i wide allocation, but storage is only %i wide",
needed_width, buffer->width);
}
if (allocator->y_used + needed_height > buffer->height)
{
g_warning ("requested allocation (%ix%i) does not fit parent buffer (%ix%i)",
width, height, buffer->width, buffer->height);
return NULL;
}
if (allocator->x_used + needed_width > buffer->width)
{
if (allocator->y_used + allocator->max_height + needed_height > buffer->height)
{
g_warning ("requested allocation (%ix%i) does not fit parent buffer (%ix%i)",
width, height, buffer->width, buffer->height);
return NULL;
}
allocator->y_used += allocator->max_height;
allocator->x_used = 0;
allocator->max_height = 0;
}
shift_x = allocator->x_used;
shift_y = allocator->y_used;
allocator->x_used += needed_width;
if (allocator->max_height < needed_height)
allocator->max_height = needed_height;
{GeglBuffer *tmp = g_object_new (GEGL_TYPE_BUFFER,
"source", allocator,
"x", x,
"y", y,
"width", width,
"height", height,
"shift-x", shift_x,
"shift-y", shift_y,
NULL);
return tmp;
}
}
static GeglBufferAllocator *a_rgba8 = NULL;
GeglBuffer *
gegl_buffer_new_from_format (void *babl_format,
gint x,
gint y,
gint width,
gint height)
{
GeglBufferAllocator *allocator = NULL;
/* aquire a GeglBufferAllocator */
/* iterate list of existing */
allocator = a_rgba8;
/* if no match, create new */
if (allocator == NULL)
{
GeglStorage *storage = g_object_new (GEGL_TYPE_STORAGE,
"format", babl_format,
NULL);
a_rgba8 = g_object_new (GEGL_TYPE_BUFFER_ALLOCATOR,
"source", storage,
NULL);
g_object_unref (storage);
allocator = a_rgba8;
}
/* check if we already have a GeglBufferAllocator for the needed tile slice */
return gegl_buffer_alloc (allocator, x, y, width, height);
}
/* This file is part of GEGL.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Copyright 2006 Øyvind Kolås <pippin@gimp.org>
*/
#include <glib.h>
#include <glib-object.h>
#include "gegl-buffer-types.h"
#ifndef _GEGL_BUFFER_ALLOCATOR_H
#define _GEGL_BUFFER_ALLOCATOR_H
#define GEGL_TYPE_BUFFER_ALLOCATOR (gegl_buffer_allocator_get_type ())
#define GEGL_BUFFER_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEGL_TYPE_BUFFER_ALLOCATOR, GeglBufferAllocator))
#define GEGL_BUFFER_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEGL_TYPE_BUFFER_ALLOCATOR, GeglBufferAllocatorClass))
#define GEGL_IS_BUFFER_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_BUFFER_ALLOCATOR))
#define GEGL_IS_BUFFER_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEGL_TYPE_BUFFER_ALLOCATOR))
#define GEGL_BUFFER_ALLOCATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEGL_TYPE_BUFFER_ALLOCATOR, GeglBufferAllocatorClass))
#include "gegl-buffer.h"
struct _GeglBufferAllocator
{
GeglBuffer parent_object;
gint x_used; /* currently used in x direction */
gint max_height; /* height of the talles allocation in this run */
gint y_used; /* the current y pos used for returns */
};
struct _GeglBufferAllocatorClass
{
GeglBufferClass parent_class;
};
#if 0
/** should be split out into a seperate subclass **/
GeglBuffer * gegl_buffer_alloc (GeglBufferAllocator *allocator,
gint x,
gint y,
gint width,
gint height,
gint shift_x);
#endif
GeglBuffer *
gegl_buffer_new_from_format (void *babl_format,
gint x,
gint y,
gint width,
gint height);
#endif
/* This file is part of GEGL.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Copyright 2006 Øyvind Kolås <pippin@gimp.org>
*/
#ifndef _GEGL_BUFFER_TYPES_H
#define _GEGL_BUFFER_TYPES_H
typedef struct _GeglTile GeglTile;
typedef struct _GeglTileClass GeglTileClass;
typedef struct _GeglTileStore GeglTileStore;
typedef struct _GeglTileStoreClass GeglTileStoreClass;
typedef struct _GeglTileBackend GeglTileBackend;
typedef struct _GeglTileBackendClass GeglTileBackendClass;
typedef struct _GeglTileTrait GeglTileTrait;
typedef struct _GeglTileTraitClass GeglTileTraitClass;
typedef struct _GeglTileTraits GeglTileTraits;
typedef struct _GeglTileTraitsClass GeglTileTraitsClass;
typedef struct _GeglStorage GeglStorage;
typedef struct _GeglStorageClass GeglStorageClass;
typedef struct _GeglBuffer GeglBuffer;
typedef struct _GeglBufferClass GeglBufferClass;
typedef struct _GeglBufferAllocator GeglBufferAllocator;
typedef struct _GeglBufferAllocatorClass GeglBufferAllocatorClass;
#endif
This diff is collapsed.
/* This file is part of GEGL.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Copyright 2006 Øyvind Kolås <pippin@gimp.org>
*/
#include <glib.h>
#include <glib-object.h>
#include "gegl-buffer-types.h"
#ifndef _GEGL_BUFFER_H
#define _GEGL_BUFFER_H
#define GEGL_TYPE_BUFFER (gegl_buffer_get_type ())
#define GEGL_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEGL_TYPE_BUFFER, GeglBuffer))
#define GEGL_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEGL_TYPE_BUFFER, GeglBufferClass))
#define GEGL_IS_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_BUFFER))
#define GEGL_IS_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEGL_TYPE_BUFFER))
#define GEGL_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEGL_TYPE_BUFFER, GeglBufferClass))
#include "gegl-tile-traits.h"
struct _GeglBuffer
{
GeglTileTraits parent_object;
gpointer format;
gint x; /* the relative position in relation to parent buffer */
gint y; /* the relative position in relation to parent buffer */
gint width;
gint height;
gint shift_x;
gint shift_y;
gint total_shift_x;
gint total_shift_y;
gint abyss_x;
gint abyss_y;
gint abyss_width;
gint abyss_height;
};
struct _GeglBufferClass
{
GeglTileTraitsClass parent_class;
};
GType gegl_buffer_get_type (void) G_GNUC_CONST;
void gegl_buffer_set (GeglBuffer *buffer,
guchar *src);
void gegl_buffer_get (GeglBuffer *buffer,
guchar *dst);
void * gegl_buffer_get_format (GeglBuffer *buffer);
gint gegl_buffer_px_size (GeglBuffer *buffer);
/***********************/
gboolean gegl_buffer_idle (GeglBuffer *gegl_buffer);
GeglStorage * gegl_buffer_storage (GeglBuffer *buffer);
/* Dirt handling */
void gegl_buffer_add_dirty (GeglBuffer *gegl_buffer,
gint x,
gint y);
void gegl_buffer_flush_dirty (GeglBuffer *buffer);
gboolean gegl_buffer_is_dirty (GeglBuffer *buffer,
gint x,
gint y);
#endif
/* This file is part of GEGL.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Copyright 2006 Øyvind Kolås <pippin@gimp.org>
*/
#include <glib.h>
#include <glib/gprintf.h>
#include <glib/gstdio.h>
#include "gegl-storage.h"
#include "gegl-tile.h"
#if 0
#include "gegl-tile-disk.h"
#endif
#include "gegl-tile-empty.h"
#include "gegl-tile-mem.h"
#include "gegl-tile-cache.h"
#include "gegl-tile-log.h"
G_DEFINE_TYPE(GeglStorage, gegl_storage, GEGL_TYPE_TILE_TRAITS)
#define TILE_SIZE 128
static GObjectClass *parent_class = NULL;
enum {
PROP_0,
PROP_WIDTH,
PROP_HEIGHT,
PROP_TILE_WIDTH,
PROP_TILE_HEIGHT,
PROP_TILE_SIZE,
PROP_FORMAT,
PROP_PX_SIZE,
PROP_PATH
};
static void
get_property (GObject *gobject,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GeglStorage *buffer = GEGL_STORAGE (gobject);
switch(property_id)
{
case PROP_WIDTH:
g_value_set_int (value, buffer->width);
break;
case PROP_HEIGHT:
g_value_set_int (value, buffer->height);
break;
case PROP_TILE_WIDTH:
g_value_set_int (value, buffer->tile_width);
break;
case PROP_TILE_HEIGHT:
g_value_set_int (value, buffer->tile_height);
break;
case PROP_TILE_SIZE:
g_value_set_int (value, buffer->tile_size);
break;
case PROP_PX_SIZE:
g_value_set_int (value, buffer->px_size);
break;
case PROP_PATH:
if (buffer->path != NULL)
g_value_set_string (value, buffer->path);
break;
case PROP_FORMAT:
g_value_set_pointer (value, buffer->format);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
break;
}
}
static void
set_property (GObject *gobject,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GeglStorage *buffer= GEGL_STORAGE (gobject);
switch(property_id)
{
case PROP_WIDTH:
buffer->width = g_value_get_int (value);
return;
case PROP_HEIGHT:
buffer->height = g_value_get_int (value);
return;
case PROP_TILE_WIDTH:
buffer->tile_width= g_value_get_int (value);
break;
case PROP_TILE_HEIGHT:
buffer->tile_height = g_value_get_int (value);
break;
case PROP_TILE_SIZE:
buffer->tile_size = g_value_get_int (value);
break;
case PROP_PX_SIZE:
buffer->px_size = g_value_get_int (value);
break;
case PROP_PATH:
if (buffer->path)
g_free (buffer->path);
buffer->path = g_strdup (g_value_get_string (value));
break;
case PROP_FORMAT:
buffer->format = g_value_get_pointer (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
break;
}
}
static void
gegl_storage_dispose (GObject *object)
{
GeglStorage *buffer;
GeglTileTrait *trait;
buffer = (GeglStorage*) object;
trait = GEGL_TILE_TRAIT (object);
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
static GObject *
gegl_storage_constructor (GType type,
guint n_params,
GObjectConstructParam *params)
{
GObject *object;
GeglStorage *storage;
GeglTileTraits *traits;
GeglTileTrait *trait;
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
storage = GEGL_STORAGE (object);
traits = GEGL_TILE_TRAITS (storage);
trait = GEGL_TILE_TRAIT (storage);
if(storage->path != NULL && 0)
{
#if 0
g_object_set (storage,
"source", g_object_new (GEGL_TYPE_TILE_DISK_STORE,
"tile-width", storage->tile_width,
"tile-height", storage->tile_height,
"path", storage->path,
NULL),
NULL);
#endif
}
else
{
g_object_set (storage,
"source", g_object_new (GEGL_TYPE_TILE_MEM_STORE,
"tile-width", storage->tile_width,
"tile-height", storage->tile_height,
NULL),
NULL);
}
{
gint tile_size;
gint px_size;
g_object_get (trait->source,
"tile-size", &tile_size,
"px-size", &px_size,
NULL);
g_object_set (object,
"tile-size", tile_size,
"px-size", px_size,
NULL);
}
if(0)gegl_tile_traits_add (traits, g_object_new (GEGL_TYPE_TILE_LOG,
NULL));
/* moved here to allow sharing between buffers (speeds up, but only
* allows nulled (transparent) blank tiles,..
*/
if(1)gegl_tile_traits_add (traits, g_object_new (GEGL_TYPE_TILE_EMPTY,
"backend", trait->source,
NULL));
if(1)gegl_tile_traits_add (traits, g_object_new (GEGL_TYPE_TILE_CACHE,
"size", 128,
NULL));
return object;
}
static void
gegl_storage_class_init (GeglStorageClass *class)
{
GObjectClass *gobject_class;
GeglTileStoreClass *tile_store_class;
gobject_class = (GObjectClass*) class;
tile_store_class = (GeglTileStoreClass*) class;
parent_class = g_type_class_peek_parent (class);
gobject_class->dispose = gegl_storage_dispose;
gobject_class->constructor = gegl_storage_constructor;
gobject_class->set_property = set_property;
gobject_class->get_property = get_property;
g_object_class_install_property (gobject_class, PROP_TILE_WIDTH,
g_param_spec_int ("tile-width", "tile-width", "width of a tile in pixels",
0, G_MAXINT, TILE_SIZE,
G_PARAM_READWRITE|
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class, PROP_TILE_HEIGHT,
g_param_spec_int ("tile-height", "tile-height", "height of a tile in pixels",
0, G_MAXINT, TILE_SIZE,
G_PARAM_READWRITE|
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class, PROP_TILE_SIZE,
g_param_spec_int ("tile-size", "tile-size", "size of a tile in bytes",
0, G_MAXINT, 0,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_PX_SIZE,
g_param_spec_int ("px-size", "px-size", "size of a a pixel in bytes",
0, G_MAXINT, 0,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_WIDTH,
g_param_spec_int ("width", "width", "pixel width of buffer",
0, G_MAXINT, G_MAXINT,
G_PARAM_READWRITE|
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class, PROP_HEIGHT,
g_param_spec_int ("height", "height", "pixel height of buffer",
0, G_MAXINT, G_MAXINT,
G_PARAM_READWRITE|
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class, PROP_PATH,
g_param_spec_string ("path",
"path",
"The filesystem directory with swap for this sparse tile store, NULL to make this be a heap storage.",
NULL,
G_PARAM_CONSTRUCT|G_PARAM_READWRITE));