|
Packit Service |
2781ba |
/* This file is part of GEGL.
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* This library is free software; you can redistribute it and/or
|
|
Packit Service |
2781ba |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
2781ba |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
2781ba |
* version 3 of the License, or (at your option) any later version.
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* This library is distributed in the hope that it will be useful,
|
|
Packit Service |
2781ba |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
2781ba |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
2781ba |
* Lesser General Public License for more details.
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
2781ba |
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* Copyright 2006-2008 Øyvind Kolås <pippin@gimp.org>
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include "config.h"
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include <math.h>
|
|
Packit Service |
2781ba |
#include <string.h>
|
|
Packit Service |
2781ba |
#include <errno.h>
|
|
Packit Service |
2781ba |
#include <stdlib.h>
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include <sys/types.h>
|
|
Packit Service |
2781ba |
#ifdef HAVE_UNISTD_H
|
|
Packit Service |
2781ba |
#include <unistd.h>
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
#include <errno.h>
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include <sys/types.h>
|
|
Packit Service |
2781ba |
#ifdef HAVE_UNISTD_H
|
|
Packit Service |
2781ba |
#include <unistd.h>
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#ifdef G_OS_WIN32
|
|
Packit Service |
2781ba |
#include <process.h>
|
|
Packit Service |
2781ba |
#define getpid() _getpid()
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include <glib-object.h>
|
|
Packit Service |
2781ba |
#include <glib/gstdio.h>
|
|
Packit Service |
2781ba |
#include <glib/gprintf.h>
|
|
Packit Service |
2781ba |
#include <gio/gio.h>
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include "gegl.h"
|
|
Packit Service |
2781ba |
#include "gegl-types-internal.h"
|
|
Packit Service |
2781ba |
#include "gegl-buffer-types.h"
|
|
Packit Service |
2781ba |
#include "gegl-buffer.h"
|
|
Packit Service |
2781ba |
#include "gegl-buffer-private.h"
|
|
Packit Service |
2781ba |
#include "gegl-tile-handler.h"
|
|
Packit Service |
2781ba |
#include "gegl-tile-storage.h"
|
|
Packit Service |
2781ba |
#include "gegl-tile-backend.h"
|
|
Packit Service |
2781ba |
#include "gegl-tile-backend-file.h"
|
|
Packit Service |
2781ba |
#include "gegl-tile-backend-tiledir.h"
|
|
Packit Service |
2781ba |
#include "gegl-tile-backend-ram.h"
|
|
Packit Service |
2781ba |
#include "gegl-tile.h"
|
|
Packit Service |
2781ba |
#include "gegl-tile-handler-cache.h"
|
|
Packit Service |
2781ba |
#include "gegl-tile-handler-log.h"
|
|
Packit Service |
2781ba |
#include "gegl-tile-handler-empty.h"
|
|
Packit Service |
2781ba |
#include "gegl-sampler-nearest.h"
|
|
Packit Service |
2781ba |
#include "gegl-sampler-linear.h"
|
|
Packit Service |
2781ba |
#include "gegl-sampler-cubic.h"
|
|
Packit Service |
2781ba |
#include "gegl-sampler-lohalo.h"
|
|
Packit Service |
2781ba |
#include "gegl-types-internal.h"
|
|
Packit Service |
2781ba |
#include "gegl-utils.h"
|
|
Packit Service |
2781ba |
#include "gegl-id-pool.h"
|
|
Packit Service |
2781ba |
#include "gegl-buffer-index.h"
|
|
Packit Service |
2781ba |
#include "gegl-config.h"
|
|
Packit Service |
2781ba |
#include "gegl-buffer-cl-cache.h"
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* #define GEGL_BUFFER_DEBUG_ALLOCATIONS */
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* #define GEGL_BUFFER_DEBUG_ALLOCATIONS to print allocation stack
|
|
Packit Service |
2781ba |
* traces for leaked GeglBuffers using GNU C libs backtrace_symbols()
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
#ifdef HAVE_EXECINFO_H
|
|
Packit Service |
2781ba |
#include <execinfo.h>
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
G_DEFINE_TYPE (GeglBuffer, gegl_buffer, GEGL_TYPE_TILE_HANDLER)
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static GObjectClass * parent_class = NULL;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
enum
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
PROP_0,
|
|
Packit Service |
2781ba |
PROP_X,
|
|
Packit Service |
2781ba |
PROP_Y,
|
|
Packit Service |
2781ba |
PROP_WIDTH,
|
|
Packit Service |
2781ba |
PROP_HEIGHT,
|
|
Packit Service |
2781ba |
PROP_SHIFT_X,
|
|
Packit Service |
2781ba |
PROP_SHIFT_Y,
|
|
Packit Service |
2781ba |
PROP_ABYSS_X,
|
|
Packit Service |
2781ba |
PROP_ABYSS_Y,
|
|
Packit Service |
2781ba |
PROP_ABYSS_WIDTH,
|
|
Packit Service |
2781ba |
PROP_ABYSS_HEIGHT,
|
|
Packit Service |
2781ba |
PROP_TILE_WIDTH,
|
|
Packit Service |
2781ba |
PROP_TILE_HEIGHT,
|
|
Packit Service |
2781ba |
PROP_FORMAT,
|
|
Packit Service |
2781ba |
PROP_PX_SIZE,
|
|
Packit Service |
2781ba |
PROP_PIXELS,
|
|
Packit Service |
2781ba |
PROP_PATH,
|
|
Packit Service |
2781ba |
PROP_BACKEND
|
|
Packit Service |
2781ba |
};
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
enum {
|
|
Packit Service |
2781ba |
CHANGED,
|
|
Packit Service |
2781ba |
LAST_SIGNAL
|
|
Packit Service |
2781ba |
};
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static GeglBuffer *gegl_buffer_new_from_format (const void *babl_fmt,
|
|
Packit Service |
2781ba |
gint x,
|
|
Packit Service |
2781ba |
gint y,
|
|
Packit Service |
2781ba |
gint width,
|
|
Packit Service |
2781ba |
gint height,
|
|
Packit Service |
2781ba |
gint tile_width,
|
|
Packit Service |
2781ba |
gint tile_height,
|
|
Packit Service |
2781ba |
gboolean use_ram);
|
|
Packit Service |
2781ba |
static const void *gegl_buffer_internal_get_format (GeglBuffer *buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
guint gegl_buffer_signals[LAST_SIGNAL] = { 0 };
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static inline gint gegl_buffer_needed_tiles (gint w,
|
|
Packit Service |
2781ba |
gint stride)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
return ((w - 1) / stride) + 1;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static inline gint gegl_buffer_needed_width (gint w,
|
|
Packit Service |
2781ba |
gint stride)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
return gegl_buffer_needed_tiles (w, stride) * stride;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static void
|
|
Packit Service |
2781ba |
gegl_buffer_get_property (GObject *gobject,
|
|
Packit Service |
2781ba |
guint property_id,
|
|
Packit Service |
2781ba |
GValue *value,
|
|
Packit Service |
2781ba |
GParamSpec *pspec)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglBuffer *buffer = GEGL_BUFFER (gobject);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
switch (property_id)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
case PROP_WIDTH:
|
|
Packit Service |
2781ba |
g_value_set_int (value, buffer->extent.width);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_HEIGHT:
|
|
Packit Service |
2781ba |
g_value_set_int (value, buffer->extent.height);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
case PROP_TILE_WIDTH:
|
|
Packit Service |
2781ba |
g_value_set_int (value, buffer->tile_width);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_TILE_HEIGHT:
|
|
Packit Service |
2781ba |
g_value_set_int (value, buffer->tile_height);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_PATH:
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglTileBackend *backend = gegl_buffer_backend (buffer);
|
|
Packit Service |
2781ba |
if (GEGL_IS_TILE_BACKEND_FILE(backend))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (buffer->path)
|
|
Packit Service |
2781ba |
g_free (buffer->path);
|
|
Packit Service |
2781ba |
buffer->path = NULL;
|
|
Packit Service |
2781ba |
g_object_get (backend, "path", &buffer->path, NULL);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
g_value_set_string (value, buffer->path);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
case PROP_PIXELS:
|
|
Packit Service |
2781ba |
g_value_set_int (value, buffer->extent.width * buffer->extent.height);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_PX_SIZE:
|
|
Packit Service |
2781ba |
g_value_set_int (value, buffer->tile_storage->px_size);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_FORMAT:
|
|
Packit Service |
2781ba |
/* might already be set the first time, if it was set during
|
|
Packit Service |
2781ba |
* construction, we're caching the value in the buffer itself,
|
|
Packit Service |
2781ba |
* since it will never change.
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
const Babl *format;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
format = buffer->soft_format;
|
|
Packit Service |
2781ba |
if (format == NULL)
|
|
Packit Service |
2781ba |
format = buffer->format;
|
|
Packit Service |
2781ba |
if (format == NULL)
|
|
Packit Service |
2781ba |
format = gegl_buffer_internal_get_format (buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_value_set_pointer (value, (void*)format);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_BACKEND:
|
|
Packit Service |
2781ba |
g_value_set_pointer (value, buffer->backend);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_X:
|
|
Packit Service |
2781ba |
g_value_set_int (value, buffer->extent.x);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_Y:
|
|
Packit Service |
2781ba |
g_value_set_int (value, buffer->extent.y);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_SHIFT_X:
|
|
Packit Service |
2781ba |
g_value_set_int (value, buffer->shift_x);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_SHIFT_Y:
|
|
Packit Service |
2781ba |
g_value_set_int (value, buffer->shift_y);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
default:
|
|
Packit Service |
2781ba |
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static void
|
|
Packit Service |
2781ba |
gegl_buffer_set_property (GObject *gobject,
|
|
Packit Service |
2781ba |
guint property_id,
|
|
Packit Service |
2781ba |
const GValue *value,
|
|
Packit Service |
2781ba |
GParamSpec *pspec)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglBuffer *buffer = GEGL_BUFFER (gobject);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
switch (property_id)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
case PROP_X:
|
|
Packit Service |
2781ba |
buffer->extent.x = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_Y:
|
|
Packit Service |
2781ba |
buffer->extent.y = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_WIDTH:
|
|
Packit Service |
2781ba |
buffer->extent.width = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_HEIGHT:
|
|
Packit Service |
2781ba |
buffer->extent.height = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_TILE_HEIGHT:
|
|
Packit Service |
2781ba |
buffer->tile_height = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_TILE_WIDTH:
|
|
Packit Service |
2781ba |
buffer->tile_width = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_PATH:
|
|
Packit Service |
2781ba |
if (buffer->path)
|
|
Packit Service |
2781ba |
g_free (buffer->path);
|
|
Packit Service |
2781ba |
buffer->path = g_value_dup_string (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_SHIFT_X:
|
|
Packit Service |
2781ba |
buffer->shift_x = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_SHIFT_Y:
|
|
Packit Service |
2781ba |
buffer->shift_y = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_ABYSS_X:
|
|
Packit Service |
2781ba |
buffer->abyss.x = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_ABYSS_Y:
|
|
Packit Service |
2781ba |
buffer->abyss.y = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_ABYSS_WIDTH:
|
|
Packit Service |
2781ba |
buffer->abyss.width = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_ABYSS_HEIGHT:
|
|
Packit Service |
2781ba |
buffer->abyss.height = g_value_get_int (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
case PROP_FORMAT:
|
|
Packit Service |
2781ba |
/* Do not set to NULL even if asked to do so by a non-overriden
|
|
Packit Service |
2781ba |
* value, this is needed since a default value can not be specified
|
|
Packit Service |
2781ba |
* for a gpointer paramspec
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
if (g_value_get_pointer (value))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
const Babl *format = g_value_get_pointer (value);
|
|
Packit Service |
2781ba |
/* XXX: need to check if the internal format matches, should
|
|
Packit Service |
2781ba |
* perhaps do different things here depending on whether
|
|
Packit Service |
2781ba |
* we are during construction or not
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
if (buffer->soft_format)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
gegl_buffer_set_format (buffer, format);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
buffer->format = format;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
case PROP_BACKEND:
|
|
Packit Service |
2781ba |
if (g_value_get_pointer (value))
|
|
Packit Service |
2781ba |
buffer->backend = g_value_get_pointer (value);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
default:
|
|
Packit Service |
2781ba |
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#ifdef GEGL_BUFFER_DEBUG_ALLOCATIONS
|
|
Packit Service |
2781ba |
static GList *allocated_buffers_list = NULL;
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
static gint allocated_buffers = 0;
|
|
Packit Service |
2781ba |
static gint de_allocated_buffers = 0;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* this should only be possible if this buffer matches all the buffers down to
|
|
Packit Service |
2781ba |
* storage, all of those parent buffers would change size as well, no tiles
|
|
Packit Service |
2781ba |
* would be voided as a result of changing the extent.
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
gboolean
|
|
Packit Service |
2781ba |
gegl_buffer_set_extent (GeglBuffer *buffer,
|
|
Packit Service |
2781ba |
const GeglRectangle *extent)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_return_val_if_fail(GEGL_IS_BUFFER(buffer), FALSE);
|
|
Packit Service |
2781ba |
(*(GeglRectangle*)gegl_buffer_get_extent (buffer))=*extent;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if ((GeglBufferHeader*)(gegl_buffer_backend (buffer)->priv->header))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglBufferHeader *header =
|
|
Packit Service |
2781ba |
((GeglBufferHeader*)(gegl_buffer_backend (buffer)->priv->header));
|
|
Packit Service |
2781ba |
header->x = buffer->extent.x;
|
|
Packit Service |
2781ba |
header->y = buffer->extent.y;
|
|
Packit Service |
2781ba |
header->width = buffer->extent.width;
|
|
Packit Service |
2781ba |
header->height = buffer->extent.height;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return TRUE;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
void gegl_buffer_stats (void)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_warning ("Buffer statistics: allocated:%i deallocated:%i balance:%i",
|
|
Packit Service |
2781ba |
allocated_buffers, de_allocated_buffers, allocated_buffers - de_allocated_buffers);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gint gegl_buffer_leaks (void)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
#ifdef GEGL_BUFFER_DEBUG_ALLOCATIONS
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GList *leaked_buffer = NULL;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
for (leaked_buffer = allocated_buffers_list;
|
|
Packit Service |
2781ba |
leaked_buffer != NULL;
|
|
Packit Service |
2781ba |
leaked_buffer = leaked_buffer->next)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglBuffer *buffer = GEGL_BUFFER (leaked_buffer->data);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_printerr ("\n"
|
|
Packit Service |
2781ba |
"Leaked buffer allocation stack trace:\n");
|
|
Packit Service |
2781ba |
g_printerr ("%s\n", buffer->alloc_stack_trace);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
g_list_free (allocated_buffers_list);
|
|
Packit Service |
2781ba |
allocated_buffers_list = NULL;
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return allocated_buffers - de_allocated_buffers;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
void
|
|
Packit Service |
2781ba |
_gegl_buffer_drop_hot_tile (GeglBuffer *buffer)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglTileStorage *storage = buffer->tile_storage;
|
|
Packit Service |
2781ba |
if (storage->hot_tile)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
gegl_tile_unref (storage->hot_tile);
|
|
Packit Service |
2781ba |
storage->hot_tile = NULL;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static void
|
|
Packit Service |
2781ba |
gegl_buffer_dispose (GObject *object)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglBuffer *buffer = GEGL_BUFFER (object);
|
|
Packit Service |
2781ba |
GeglTileHandler *handler = GEGL_TILE_HANDLER (object);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gegl_buffer_sample_cleanup (buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (gegl_cl_is_accelerated ())
|
|
Packit Service |
2781ba |
gegl_buffer_cl_cache_invalidate (GEGL_BUFFER (object), NULL);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (handler->source &&
|
|
Packit Service |
2781ba |
GEGL_IS_TILE_STORAGE (handler->source))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglTileBackend *backend = gegl_buffer_backend (buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* only flush non-internal backends,. */
|
|
Packit Service |
2781ba |
if (!(GEGL_IS_TILE_BACKEND_FILE (backend) ||
|
|
Packit Service |
2781ba |
GEGL_IS_TILE_BACKEND_RAM (backend) ||
|
|
Packit Service |
2781ba |
GEGL_IS_TILE_BACKEND_TILE_DIR (backend)))
|
|
Packit Service |
2781ba |
gegl_buffer_flush (buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gegl_tile_source_reinit (GEGL_TILE_SOURCE (handler->source));
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#if 0
|
|
Packit Service |
2781ba |
g_object_unref (handler->source);
|
|
Packit Service |
2781ba |
handler->source = NULL; /* this might be a dangerous way of marking that we have already voided */
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
_gegl_buffer_drop_hot_tile (buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
G_OBJECT_CLASS (parent_class)->dispose (object);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static void
|
|
Packit Service |
2781ba |
gegl_buffer_finalize (GObject *object)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
#ifdef GEGL_BUFFER_DEBUG_ALLOCATIONS
|
|
Packit Service |
2781ba |
g_free (GEGL_BUFFER (object)->alloc_stack_trace);
|
|
Packit Service |
2781ba |
allocated_buffers_list = g_list_remove (allocated_buffers_list, object);
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_free (GEGL_BUFFER (object)->path);
|
|
Packit Service |
2781ba |
de_allocated_buffers++;
|
|
Packit Service |
2781ba |
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
GeglTileBackend *
|
|
Packit Service |
2781ba |
gegl_buffer_backend (GeglBuffer *buffer)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglTileSource *tmp = GEGL_TILE_SOURCE (buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (!tmp)
|
|
Packit Service |
2781ba |
return NULL;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
do
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
tmp = GEGL_TILE_HANDLER (tmp)->source;
|
|
Packit Service |
2781ba |
} while (tmp &&
|
|
Packit Service |
2781ba |
/*GEGL_IS_TILE_TRAIT (tmp) &&*/
|
|
Packit Service |
2781ba |
!GEGL_IS_TILE_BACKEND (tmp));
|
|
Packit Service |
2781ba |
if (!tmp &&
|
|
Packit Service |
2781ba |
!GEGL_IS_TILE_BACKEND (tmp))
|
|
Packit Service |
2781ba |
return NULL;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return (GeglTileBackend *) tmp;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static GeglTileStorage *
|
|
Packit Service |
2781ba |
gegl_buffer_tile_storage (GeglBuffer *buffer)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglTileSource *tmp = GEGL_TILE_SOURCE (buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
do
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
tmp = ((GeglTileHandler *) (tmp))->source;
|
|
Packit Service |
2781ba |
} while (!GEGL_IS_TILE_STORAGE (tmp));
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_assert (tmp);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return (GeglTileStorage *) tmp;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
void babl_backtrack (void);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static void gegl_buffer_storage_changed (GeglTileStorage *storage,
|
|
Packit Service |
2781ba |
const GeglRectangle *rect,
|
|
Packit Service |
2781ba |
gpointer userdata)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_signal_emit_by_name (GEGL_BUFFER (userdata), "changed", rect, NULL);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static GObject *
|
|
Packit Service |
2781ba |
gegl_buffer_constructor (GType type,
|
|
Packit Service |
2781ba |
guint n_params,
|
|
Packit Service |
2781ba |
GObjectConstructParam *params)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GObject *object;
|
|
Packit Service |
2781ba |
GeglBuffer *buffer;
|
|
Packit Service |
2781ba |
GeglTileBackend *backend;
|
|
Packit Service |
2781ba |
GeglTileHandler *handler;
|
|
Packit Service |
2781ba |
GeglTileSource *source;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gint width;
|
|
Packit Service |
2781ba |
gint height;
|
|
Packit Service |
2781ba |
gint x;
|
|
Packit Service |
2781ba |
gint y;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
buffer = GEGL_BUFFER (object);
|
|
Packit Service |
2781ba |
handler = GEGL_TILE_HANDLER (object);
|
|
Packit Service |
2781ba |
source = handler->source;
|
|
Packit Service |
2781ba |
backend = gegl_buffer_backend (buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
x=buffer->extent.x;
|
|
Packit Service |
2781ba |
y=buffer->extent.y;
|
|
Packit Service |
2781ba |
width=buffer->extent.width;
|
|
Packit Service |
2781ba |
height=buffer->extent.height;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (source)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (GEGL_IS_TILE_STORAGE (source))
|
|
Packit Service |
2781ba |
buffer->format = GEGL_TILE_STORAGE (source)->format;
|
|
Packit Service |
2781ba |
else if (GEGL_IS_BUFFER (source))
|
|
Packit Service |
2781ba |
buffer->format = GEGL_BUFFER (source)->format;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
/* if no source is specified if a format is specified, we
|
|
Packit Service |
2781ba |
* we need to create our own
|
|
Packit Service |
2781ba |
* source (this adds a redirection buffer in between for
|
|
Packit Service |
2781ba |
* all "allocated from format", type buffers.
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
if (buffer->backend)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
void *storage;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
storage = gegl_tile_storage_new (buffer->backend);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
source = g_object_new (GEGL_TYPE_BUFFER, "source", storage, NULL);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_object_unref (storage);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gegl_tile_handler_set_source ((GeglTileHandler*)(buffer), source);
|
|
Packit Service |
2781ba |
g_object_unref (source);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_signal_connect (storage, "changed",
|
|
Packit Service |
2781ba |
G_CALLBACK(gegl_buffer_storage_changed), buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_assert (source);
|
|
Packit Service |
2781ba |
backend = gegl_buffer_backend (GEGL_BUFFER (source));
|
|
Packit Service |
2781ba |
g_assert (backend);
|
|
Packit Service |
2781ba |
g_assert (backend == buffer->backend);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else if (buffer->path && g_str_equal (buffer->path, "RAM"))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
source = GEGL_TILE_SOURCE (gegl_buffer_new_from_format (buffer->format,
|
|
Packit Service |
2781ba |
buffer->extent.x,
|
|
Packit Service |
2781ba |
buffer->extent.y,
|
|
Packit Service |
2781ba |
buffer->extent.width,
|
|
Packit Service |
2781ba |
buffer->extent.height,
|
|
Packit Service |
2781ba |
buffer->tile_width,
|
|
Packit Service |
2781ba |
buffer->tile_height, TRUE));
|
|
Packit Service |
2781ba |
/* after construction,. x and y should be set to reflect
|
|
Packit Service |
2781ba |
* the top level behavior exhibited by this buffer object.
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
gegl_tile_handler_set_source ((GeglTileHandler*)(buffer), source);
|
|
Packit Service |
2781ba |
g_object_unref (source);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_assert (source);
|
|
Packit Service |
2781ba |
backend = gegl_buffer_backend (GEGL_BUFFER (source));
|
|
Packit Service |
2781ba |
g_assert (backend);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else if (buffer->path)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglBufferHeader *header;
|
|
Packit Service |
2781ba |
void *storage;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
backend = g_object_new (GEGL_TYPE_TILE_BACKEND_FILE,
|
|
Packit Service |
2781ba |
"tile-width", 128,
|
|
Packit Service |
2781ba |
"tile-height", 64,
|
|
Packit Service |
2781ba |
"format", buffer->format?buffer->format:babl_format ("RGBA float"),
|
|
Packit Service |
2781ba |
"path", buffer->path,
|
|
Packit Service |
2781ba |
NULL);
|
|
Packit Service |
2781ba |
storage = gegl_tile_storage_new (backend);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
source = g_object_new (GEGL_TYPE_BUFFER, "source", storage, NULL);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* after construction,. x and y should be set to reflect
|
|
Packit Service |
2781ba |
* the top level behavior exhibited by this buffer object.
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
gegl_tile_handler_set_source ((GeglTileHandler*)(buffer), source);
|
|
Packit Service |
2781ba |
g_object_unref (source);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_signal_connect (storage, "changed",
|
|
Packit Service |
2781ba |
G_CALLBACK(gegl_buffer_storage_changed), buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_assert (source);
|
|
Packit Service |
2781ba |
backend = gegl_buffer_backend (GEGL_BUFFER (source));
|
|
Packit Service |
2781ba |
g_assert (backend);
|
|
Packit Service |
2781ba |
header = backend->priv->header;
|
|
Packit Service |
2781ba |
buffer->extent.x = header->x;
|
|
Packit Service |
2781ba |
buffer->extent.y = header->y;
|
|
Packit Service |
2781ba |
buffer->extent.width = header->width;
|
|
Packit Service |
2781ba |
buffer->extent.height = header->height;
|
|
Packit Service |
2781ba |
buffer->format = gegl_tile_backend_get_format (backend);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else if (buffer->format)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
source = GEGL_TILE_SOURCE (gegl_buffer_new_from_format (buffer->format,
|
|
Packit Service |
2781ba |
buffer->extent.x,
|
|
Packit Service |
2781ba |
buffer->extent.y,
|
|
Packit Service |
2781ba |
buffer->extent.width,
|
|
Packit Service |
2781ba |
buffer->extent.height,
|
|
Packit Service |
2781ba |
buffer->tile_width,
|
|
Packit Service |
2781ba |
buffer->tile_height, FALSE));
|
|
Packit Service |
2781ba |
/* after construction,. x and y should be set to reflect
|
|
Packit Service |
2781ba |
* the top level behavior exhibited by this buffer object.
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
gegl_tile_handler_set_source ((GeglTileHandler*)(buffer), source);
|
|
Packit Service |
2781ba |
g_object_unref (source);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_assert (source);
|
|
Packit Service |
2781ba |
backend = gegl_buffer_backend (GEGL_BUFFER (source));
|
|
Packit Service |
2781ba |
g_assert (backend);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_warning ("not enough data to have a tile source for our buffer");
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
/* we reset the size if it seems to have been set to 0 during a on
|
|
Packit Service |
2781ba |
* disk buffer creation, nasty but it does the job.
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (buffer->extent.width == 0)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
buffer->extent.width = width;
|
|
Packit Service |
2781ba |
buffer->extent.height = height;
|
|
Packit Service |
2781ba |
buffer->extent.x = x;
|
|
Packit Service |
2781ba |
buffer->extent.y = y;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_assert (backend);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (buffer->extent.width == -1 &&
|
|
Packit Service |
2781ba |
buffer->extent.height == -1) /* no specified extents,
|
|
Packit Service |
2781ba |
inheriting from source */
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (GEGL_IS_BUFFER (source))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
buffer->extent.x = GEGL_BUFFER (source)->extent.x;
|
|
Packit Service |
2781ba |
buffer->extent.y = GEGL_BUFFER (source)->extent.y;
|
|
Packit Service |
2781ba |
buffer->extent.width = GEGL_BUFFER (source)->extent.width;
|
|
Packit Service |
2781ba |
buffer->extent.height = GEGL_BUFFER (source)->extent.height;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else if (GEGL_IS_TILE_STORAGE (source))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
buffer->extent.x = 0;
|
|
Packit Service |
2781ba |
buffer->extent.y = 0;
|
|
Packit Service |
2781ba |
buffer->extent.width = GEGL_TILE_STORAGE (source)->width;
|
|
Packit Service |
2781ba |
buffer->extent.height = GEGL_TILE_STORAGE (source)->height;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (buffer->abyss.width == 0 &&
|
|
Packit Service |
2781ba |
buffer->abyss.height == 0 &&
|
|
Packit Service |
2781ba |
buffer->abyss.x == 0 &&
|
|
Packit Service |
2781ba |
buffer->abyss.y == 0) /* 0 sized extent == inherit buffer extent
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
buffer->abyss.x = buffer->extent.x;
|
|
Packit Service |
2781ba |
buffer->abyss.y = buffer->extent.y;
|
|
Packit Service |
2781ba |
buffer->abyss.width = buffer->extent.width;
|
|
Packit Service |
2781ba |
buffer->abyss.height = buffer->extent.height;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else if (buffer->abyss.width == 0 &&
|
|
Packit Service |
2781ba |
buffer->abyss.height == 0)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_warning ("peculiar abyss dimensions: %i,%i %ix%i",
|
|
Packit Service |
2781ba |
buffer->abyss.x,
|
|
Packit Service |
2781ba |
buffer->abyss.y,
|
|
Packit Service |
2781ba |
buffer->abyss.width,
|
|
Packit Service |
2781ba |
buffer->abyss.height);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else if (buffer->abyss.width == -1 ||
|
|
Packit Service |
2781ba |
buffer->abyss.height == -1)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
buffer->abyss.x = GEGL_BUFFER (source)->abyss.x - buffer->shift_x;
|
|
Packit Service |
2781ba |
buffer->abyss.y = GEGL_BUFFER (source)->abyss.y - buffer->shift_y;
|
|
Packit Service |
2781ba |
buffer->abyss.width = GEGL_BUFFER (source)->abyss.width;
|
|
Packit Service |
2781ba |
buffer->abyss.height = GEGL_BUFFER (source)->abyss.height;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* intersect our own abyss with parent's abyss if it exists
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
if (GEGL_IS_BUFFER (source))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglRectangle parent;
|
|
Packit Service |
2781ba |
GeglRectangle request;
|
|
Packit Service |
2781ba |
GeglRectangle self;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
parent.x = GEGL_BUFFER (source)->abyss.x - buffer->shift_x;
|
|
Packit Service |
2781ba |
parent.y = GEGL_BUFFER (source)->abyss.y - buffer->shift_y;
|
|
Packit Service |
2781ba |
parent.width = GEGL_BUFFER (source)->abyss.width;
|
|
Packit Service |
2781ba |
parent.height = GEGL_BUFFER (source)->abyss.height;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
request.x = buffer->abyss.x;
|
|
Packit Service |
2781ba |
request.y = buffer->abyss.y;
|
|
Packit Service |
2781ba |
request.width = buffer->abyss.width;
|
|
Packit Service |
2781ba |
request.height = buffer->abyss.height;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gegl_rectangle_intersect (&self, &parent, &request);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
buffer->abyss.x = self.x;
|
|
Packit Service |
2781ba |
buffer->abyss.y = self.y;
|
|
Packit Service |
2781ba |
buffer->abyss.width = self.width;
|
|
Packit Service |
2781ba |
buffer->abyss.height = self.height;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* compute our own total shift <- this should probably happen
|
|
Packit Service |
2781ba |
* approximatly first */
|
|
Packit Service |
2781ba |
if (GEGL_IS_BUFFER (source))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglBuffer *source_buf;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
source_buf = GEGL_BUFFER (source);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
buffer->shift_x += source_buf->shift_x;
|
|
Packit Service |
2781ba |
buffer->shift_y += source_buf->shift_y;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
buffer->tile_storage = gegl_buffer_tile_storage (buffer);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* intialize the soft format to be equivalent to the actual
|
|
Packit Service |
2781ba |
* format
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
buffer->soft_format = buffer->format;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return object;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static GeglTile *
|
|
Packit Service |
2781ba |
gegl_buffer_get_tile (GeglTileSource *source,
|
|
Packit Service |
2781ba |
gint x,
|
|
Packit Service |
2781ba |
gint y,
|
|
Packit Service |
2781ba |
gint z)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglTileHandler *handler = GEGL_TILE_HANDLER (source);
|
|
Packit Service |
2781ba |
GeglTile *tile = NULL;
|
|
Packit Service |
2781ba |
source = handler->source;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (source)
|
|
Packit Service |
2781ba |
tile = gegl_tile_source_get_tile (source, x, y, z);
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
g_assert (0);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (tile)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglBuffer *buffer = GEGL_BUFFER (handler);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* storing information in tile, to enable the dispose function of the
|
|
Packit Service |
2781ba |
* tile instance to "hook" back to the storage with correct
|
|
Packit Service |
2781ba |
* coordinates.
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (!tile->tile_storage)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
gegl_tile_lock (tile);
|
|
Packit Service |
2781ba |
tile->tile_storage = buffer->tile_storage;
|
|
Packit Service |
2781ba |
gegl_tile_unlock (tile);
|
|
Packit Service |
2781ba |
tile->rev--;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
tile->x = x;
|
|
Packit Service |
2781ba |
tile->y = y;
|
|
Packit Service |
2781ba |
tile->z = z;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return tile;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static gpointer
|
|
Packit Service |
2781ba |
gegl_buffer_command (GeglTileSource *source,
|
|
Packit Service |
2781ba |
GeglTileCommand command,
|
|
Packit Service |
2781ba |
gint x,
|
|
Packit Service |
2781ba |
gint y,
|
|
Packit Service |
2781ba |
gint z,
|
|
Packit Service |
2781ba |
gpointer data)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglTileHandler *handler = GEGL_TILE_HANDLER (source);
|
|
Packit Service |
2781ba |
switch (command)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
case GEGL_TILE_GET:
|
|
Packit Service |
2781ba |
return gegl_buffer_get_tile (source, x, y, z);
|
|
Packit Service |
2781ba |
default:
|
|
Packit Service |
2781ba |
return gegl_tile_handler_source_command (handler, command, x, y, z, data);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static void
|
|
Packit Service |
2781ba |
gegl_buffer_class_init (GeglBufferClass *class)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
|
Packit Service |
2781ba |
parent_class = g_type_class_peek_parent (class);
|
|
Packit Service |
2781ba |
gobject_class->dispose = gegl_buffer_dispose;
|
|
Packit Service |
2781ba |
gobject_class->finalize = gegl_buffer_finalize;
|
|
Packit Service |
2781ba |
gobject_class->constructor = gegl_buffer_constructor;
|
|
Packit Service |
2781ba |
gobject_class->set_property = gegl_buffer_set_property;
|
|
Packit Service |
2781ba |
gobject_class->get_property = gegl_buffer_get_property;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_PX_SIZE,
|
|
Packit Service |
2781ba |
g_param_spec_int ("px-size", "pixel-size", "size of a single pixel in bytes.",
|
|
Packit Service |
2781ba |
0, G_MAXINT, 0,
|
|
Packit Service |
2781ba |
G_PARAM_READABLE));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_PIXELS,
|
|
Packit Service |
2781ba |
g_param_spec_int ("pixels", "pixels", "total amount of pixels in image (width x height)",
|
|
Packit Service |
2781ba |
0, G_MAXINT, 0,
|
|
Packit Service |
2781ba |
G_PARAM_READABLE));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_WIDTH,
|
|
Packit Service |
2781ba |
g_param_spec_int ("width", "width", "pixel width of buffer",
|
|
Packit Service |
2781ba |
-1, G_MAXINT, -1,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_HEIGHT,
|
|
Packit Service |
2781ba |
g_param_spec_int ("height", "height", "pixel height of buffer",
|
|
Packit Service |
2781ba |
-1, G_MAXINT, -1,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_X,
|
|
Packit Service |
2781ba |
g_param_spec_int ("x", "x", "local origin's offset relative to source origin",
|
|
Packit Service |
2781ba |
G_MININT / 2, G_MAXINT / 2, 0,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_Y,
|
|
Packit Service |
2781ba |
g_param_spec_int ("y", "y", "local origin's offset relative to source origin",
|
|
Packit Service |
2781ba |
G_MININT / 2, G_MAXINT / 2, 0,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_ABYSS_WIDTH,
|
|
Packit Service |
2781ba |
g_param_spec_int ("abyss-width", "abyss-width", "pixel width of abyss",
|
|
Packit Service |
2781ba |
-1, G_MAXINT, 0,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT_ONLY));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_ABYSS_HEIGHT,
|
|
Packit Service |
2781ba |
g_param_spec_int ("abyss-height", "abyss-height", "pixel height of abyss",
|
|
Packit Service |
2781ba |
-1, G_MAXINT, 0,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT_ONLY));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_ABYSS_X,
|
|
Packit Service |
2781ba |
g_param_spec_int ("abyss-x", "abyss-x", "",
|
|
Packit Service |
2781ba |
G_MININT / 2, G_MAXINT / 2, 0,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT_ONLY));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_ABYSS_Y,
|
|
Packit Service |
2781ba |
g_param_spec_int ("abyss-y", "abyss-y", "",
|
|
Packit Service |
2781ba |
G_MININT / 2, G_MAXINT / 2, 0,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT_ONLY));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_SHIFT_X,
|
|
Packit Service |
2781ba |
g_param_spec_int ("shift-x", "shift-x", "",
|
|
Packit Service |
2781ba |
G_MININT / 2, G_MAXINT / 2, 0,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT_ONLY));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_SHIFT_Y,
|
|
Packit Service |
2781ba |
g_param_spec_int ("shift-y", "shift-y", "",
|
|
Packit Service |
2781ba |
G_MININT / 2, G_MAXINT / 2, 0,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT_ONLY));
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_FORMAT,
|
|
Packit Service |
2781ba |
g_param_spec_pointer ("format", "format", "babl format",
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT));
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_BACKEND,
|
|
Packit Service |
2781ba |
g_param_spec_pointer ("backend", "backend", "A custom tile-backend instance to use",
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT));
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_TILE_HEIGHT,
|
|
Packit Service |
2781ba |
g_param_spec_int ("tile-height", "tile-height", "height of a tile",
|
|
Packit Service |
2781ba |
-1, G_MAXINT, gegl_config()->tile_height,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT_ONLY));
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_TILE_WIDTH,
|
|
Packit Service |
2781ba |
g_param_spec_int ("tile-width", "tile-width", "width of a tile",
|
|
Packit Service |
2781ba |
-1, G_MAXINT, gegl_config()->tile_width,
|
|
Packit Service |
2781ba |
G_PARAM_READWRITE |
|
|
Packit Service |
2781ba |
G_PARAM_CONSTRUCT_ONLY));
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_object_class_install_property (gobject_class, PROP_PATH,
|
|
Packit Service |
2781ba |
g_param_spec_string ("path", "Path",
|
|
Packit Service |
2781ba |
"URI to where the buffer is stored",
|
|
Packit Service |
2781ba |
NULL, G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gegl_buffer_signals[CHANGED] =
|
|
Packit Service |
2781ba |
g_signal_new ("changed",
|
|
Packit Service |
2781ba |
G_TYPE_FROM_CLASS (gobject_class),
|
|
Packit Service |
2781ba |
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
|
|
Packit Service |
2781ba |
0,
|
|
Packit Service |
2781ba |
NULL, NULL,
|
|
Packit Service |
2781ba |
g_cclosure_marshal_VOID__BOXED,
|
|
Packit Service |
2781ba |
G_TYPE_NONE, 1,
|
|
Packit Service |
2781ba |
GEGL_TYPE_RECTANGLE);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#ifdef GEGL_BUFFER_DEBUG_ALLOCATIONS
|
|
Packit Service |
2781ba |
#define MAX_N_FUNCTIONS 100
|
|
Packit Service |
2781ba |
static gchar *
|
|
Packit Service |
2781ba |
gegl_buffer_get_alloc_stack (void)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
char *result = NULL;
|
|
Packit Service |
2781ba |
#ifndef HAVE_EXECINFO_H
|
|
Packit Service |
2781ba |
result = g_strdup ("backtrace() not available for this platform\n");
|
|
Packit Service |
2781ba |
#else
|
|
Packit Service |
2781ba |
void *functions[MAX_N_FUNCTIONS];
|
|
Packit Service |
2781ba |
int n_functions = 0;
|
|
Packit Service |
2781ba |
char **function_names = NULL;
|
|
Packit Service |
2781ba |
int i = 0;
|
|
Packit Service |
2781ba |
int result_size = 0;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
n_functions = backtrace (functions, MAX_N_FUNCTIONS);
|
|
Packit Service |
2781ba |
function_names = backtrace_symbols (functions, n_functions);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
for (i = 0; i < n_functions; i++)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
result_size += strlen (function_names[i]);
|
|
Packit Service |
2781ba |
result_size += 1; /* for '\n' */
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
result = g_new (gchar, result_size + 1);
|
|
Packit Service |
2781ba |
result[0] = '\0';
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
for (i = 0; i < n_functions; i++)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
strcat (result, function_names[i]);
|
|
Packit Service |
2781ba |
strcat (result, "\n");
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
free (function_names);
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return result;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
void gegl_bt (void);
|
|
Packit Service |
2781ba |
void gegl_bt (void)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
#ifdef GEGL_BUFFER_DEBUG_ALLOCATIONS
|
|
Packit Service |
2781ba |
g_print ("%s\n", gegl_buffer_get_alloc_stack ());
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static void
|
|
Packit Service |
2781ba |
gegl_buffer_init (GeglBuffer *buffer)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
buffer->tile_width = 128;
|
|
Packit Service |
2781ba |
buffer->tile_height = 64;
|
|
Packit Service |
2781ba |
((GeglTileSource*)buffer)->command = gegl_buffer_command;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
allocated_buffers++;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#ifdef GEGL_BUFFER_DEBUG_ALLOCATIONS
|
|
Packit Service |
2781ba |
buffer->alloc_stack_trace = gegl_buffer_get_alloc_stack ();
|
|
Packit Service |
2781ba |
allocated_buffers_list = g_list_prepend (allocated_buffers_list, buffer);
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
const GeglRectangle *
|
|
Packit Service |
2781ba |
gegl_buffer_get_extent (GeglBuffer *buffer)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return &(buffer->extent);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
GeglBuffer *
|
|
Packit Service |
2781ba |
gegl_buffer_new_ram (const GeglRectangle *extent,
|
|
Packit Service |
2781ba |
const Babl *format)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglRectangle empty={0,0,0,0};
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (extent==NULL)
|
|
Packit Service |
2781ba |
extent = ∅
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (format==NULL)
|
|
Packit Service |
2781ba |
format = babl_format ("RGBA float");
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return g_object_new (GEGL_TYPE_BUFFER,
|
|
Packit Service |
2781ba |
"x", extent->x,
|
|
Packit Service |
2781ba |
"y", extent->y,
|
|
Packit Service |
2781ba |
"width", extent->width,
|
|
Packit Service |
2781ba |
"height", extent->height,
|
|
Packit Service |
2781ba |
"format", format,
|
|
Packit Service |
2781ba |
"path", "RAM",
|
|
Packit Service |
2781ba |
NULL);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
GeglBuffer *
|
|
Packit Service |
2781ba |
gegl_buffer_new (const GeglRectangle *extent,
|
|
Packit Service |
2781ba |
const Babl *format)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglRectangle empty={0,0,0,0};
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (extent==NULL)
|
|
Packit Service |
2781ba |
extent = ∅
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (format==NULL)
|
|
Packit Service |
2781ba |
format = babl_format ("RGBA float");
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return g_object_new (GEGL_TYPE_BUFFER,
|
|
Packit Service |
2781ba |
"x", extent->x,
|
|
Packit Service |
2781ba |
"y", extent->y,
|
|
Packit Service |
2781ba |
"width", extent->width,
|
|
Packit Service |
2781ba |
"height", extent->height,
|
|
Packit Service |
2781ba |
"format", format,
|
|
Packit Service |
2781ba |
NULL);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
GeglBuffer *
|
|
Packit Service |
2781ba |
gegl_buffer_new_for_backend (const GeglRectangle *extent,
|
|
Packit Service |
2781ba |
void *backend)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglRectangle rect={0,0,0,0};
|
|
Packit Service |
2781ba |
const Babl *format;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* if no extent is passed in inherit from backend */
|
|
Packit Service |
2781ba |
if (extent==NULL)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
extent = ▭
|
|
Packit Service |
2781ba |
rect = gegl_tile_backend_get_extent (backend);
|
|
Packit Service |
2781ba |
/* if backend didnt have a rect, make it an infinite plane */
|
|
Packit Service |
2781ba |
if (gegl_rectangle_is_empty (extent))
|
|
Packit Service |
2781ba |
rect = gegl_rectangle_infinite_plane ();
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* use the format of the backend */
|
|
Packit Service |
2781ba |
format = gegl_tile_backend_get_format (backend);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return g_object_new (GEGL_TYPE_BUFFER,
|
|
Packit Service |
2781ba |
"x", extent->x,
|
|
Packit Service |
2781ba |
"y", extent->y,
|
|
Packit Service |
2781ba |
"width", extent->width,
|
|
Packit Service |
2781ba |
"height", extent->height,
|
|
Packit Service |
2781ba |
"format", format,
|
|
Packit Service |
2781ba |
"backend", backend,
|
|
Packit Service |
2781ba |
NULL);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* FIXME: this function needs optimizing, perhaps keep a pool
|
|
Packit Service |
2781ba |
* of GeglBuffer shells that can be adapted to the needs
|
|
Packit Service |
2781ba |
* on runtime, and recycling them through a hashtable?
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
GeglBuffer*
|
|
Packit Service |
2781ba |
gegl_buffer_create_sub_buffer (GeglBuffer *buffer,
|
|
Packit Service |
2781ba |
const GeglRectangle *extent)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#if 1
|
|
Packit Service |
2781ba |
if (extent == NULL || gegl_rectangle_equal (extent, &buffer->extent))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_object_ref (buffer);
|
|
Packit Service |
2781ba |
return buffer;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
#else
|
|
Packit Service |
2781ba |
if (extent == NULL)
|
|
Packit Service |
2781ba |
extent = gegl_buffer_get_extent (buffer);
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (extent->width < 0 || extent->height < 0)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_warning ("avoiding creating buffer of size: %ix%i returning an empty buffer instead.\n", extent->width, extent->height);
|
|
Packit Service |
2781ba |
return g_object_new (GEGL_TYPE_BUFFER,
|
|
Packit Service |
2781ba |
"source", buffer,
|
|
Packit Service |
2781ba |
"x", extent->x,
|
|
Packit Service |
2781ba |
"y", extent->y,
|
|
Packit Service |
2781ba |
"width", 0,
|
|
Packit Service |
2781ba |
"height", 0,
|
|
Packit Service |
2781ba |
NULL);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
return g_object_new (GEGL_TYPE_BUFFER,
|
|
Packit Service |
2781ba |
"source", buffer,
|
|
Packit Service |
2781ba |
"x", extent->x,
|
|
Packit Service |
2781ba |
"y", extent->y,
|
|
Packit Service |
2781ba |
"width", extent->width,
|
|
Packit Service |
2781ba |
"height", extent->height,
|
|
Packit Service |
2781ba |
NULL);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
typedef struct TileStorageCacheItem {
|
|
Packit Service |
2781ba |
GeglTileStorage *storage;
|
|
Packit Service |
2781ba |
gboolean ram;
|
|
Packit Service |
2781ba |
gint tile_width;
|
|
Packit Service |
2781ba |
gint tile_height;
|
|
Packit Service |
2781ba |
const void *babl_fmt;
|
|
Packit Service |
2781ba |
} TileStorageCacheItem;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static GStaticMutex storage_cache_mutex = G_STATIC_MUTEX_INIT;
|
|
Packit Service |
2781ba |
static GSList *storage_cache = NULL;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* returns TRUE if it could be done */
|
|
Packit Service |
2781ba |
gboolean gegl_tile_storage_cached_release (GeglTileStorage *storage);
|
|
Packit Service |
2781ba |
gboolean gegl_tile_storage_cached_release (GeglTileStorage *storage)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
TileStorageCacheItem *item = g_object_get_data (G_OBJECT (storage), "storage-cache-item");
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (!item)
|
|
Packit Service |
2781ba |
return FALSE;
|
|
Packit Service |
2781ba |
g_static_mutex_lock (&storage_cache_mutex);
|
|
Packit Service |
2781ba |
storage_cache = g_slist_prepend (storage_cache, item);
|
|
Packit Service |
2781ba |
g_static_mutex_unlock (&storage_cache_mutex);
|
|
Packit Service |
2781ba |
return TRUE;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
void gegl_tile_storage_cache_cleanup (void);
|
|
Packit Service |
2781ba |
void gegl_tile_storage_cache_cleanup (void)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_static_mutex_lock (&storage_cache_mutex);
|
|
Packit Service |
2781ba |
for (;storage_cache; storage_cache = g_slist_remove (storage_cache, storage_cache->data))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
TileStorageCacheItem *item = storage_cache->data;
|
|
Packit Service |
2781ba |
g_object_unref (item->storage);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
g_static_mutex_unlock (&storage_cache_mutex);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static GeglTileStorage *
|
|
Packit Service |
2781ba |
gegl_tile_storage_new_cached (gint tile_width, gint tile_height,
|
|
Packit Service |
2781ba |
const void *babl_fmt, gboolean use_ram)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglTileStorage *storage = NULL;
|
|
Packit Service |
2781ba |
GSList *iter;
|
|
Packit Service |
2781ba |
g_static_mutex_lock (&storage_cache_mutex);
|
|
Packit Service |
2781ba |
for (iter = storage_cache; iter; iter = iter->next)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
TileStorageCacheItem *item = iter->data;
|
|
Packit Service |
2781ba |
if (item->babl_fmt == babl_fmt &&
|
|
Packit Service |
2781ba |
item->tile_width == tile_width &&
|
|
Packit Service |
2781ba |
item->tile_height == tile_height &&
|
|
Packit Service |
2781ba |
item->ram == item->ram)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
storage = item->storage;
|
|
Packit Service |
2781ba |
storage_cache = g_slist_remove (storage_cache, item);
|
|
Packit Service |
2781ba |
break;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (!storage)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
TileStorageCacheItem *item = g_new0 (TileStorageCacheItem, 1);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
item->tile_width = tile_width;
|
|
Packit Service |
2781ba |
item->tile_height = tile_height;
|
|
Packit Service |
2781ba |
item->babl_fmt = babl_fmt;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (use_ram ||
|
|
Packit Service |
2781ba |
!gegl_config()->swap ||
|
|
Packit Service |
2781ba |
g_str_equal (gegl_config()->swap, "RAM") ||
|
|
Packit Service |
2781ba |
g_str_equal (gegl_config()->swap, "ram"))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglTileBackend *backend;
|
|
Packit Service |
2781ba |
item->ram = TRUE;
|
|
Packit Service |
2781ba |
backend = g_object_new (GEGL_TYPE_TILE_BACKEND_RAM,
|
|
Packit Service |
2781ba |
"tile-width", tile_width,
|
|
Packit Service |
2781ba |
"tile-height", tile_height,
|
|
Packit Service |
2781ba |
"format", babl_fmt,
|
|
Packit Service |
2781ba |
NULL);
|
|
Packit Service |
2781ba |
storage = gegl_tile_storage_new (backend);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
static gint no = 1;
|
|
Packit Service |
2781ba |
GeglTileBackend *backend;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gchar *filename;
|
|
Packit Service |
2781ba |
gchar *path;
|
|
Packit Service |
2781ba |
item->ram = FALSE;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#if 0
|
|
Packit Service |
2781ba |
filename = g_strdup_printf ("GEGL-%i-%s-%i.swap",
|
|
Packit Service |
2781ba |
getpid (),
|
|
Packit Service |
2781ba |
babl_name ((Babl *) babl_fmt),
|
|
Packit Service |
2781ba |
no++);
|
|
Packit Service |
2781ba |
#endif
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
filename = g_strdup_printf ("%i-%i", getpid(), no);
|
|
Packit Service |
2781ba |
g_atomic_int_inc (&no);
|
|
Packit Service |
2781ba |
path = g_build_filename (gegl_config()->swap, filename, NULL);
|
|
Packit Service |
2781ba |
g_free (filename);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
backend = g_object_new (GEGL_TYPE_TILE_BACKEND_FILE,
|
|
Packit Service |
2781ba |
"tile-width", tile_width,
|
|
Packit Service |
2781ba |
"tile-height", tile_height,
|
|
Packit Service |
2781ba |
"format", babl_fmt,
|
|
Packit Service |
2781ba |
"path", path,
|
|
Packit Service |
2781ba |
NULL);
|
|
Packit Service |
2781ba |
storage = gegl_tile_storage_new (backend);
|
|
Packit Service |
2781ba |
g_free (path);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
item->storage = storage;
|
|
Packit Service |
2781ba |
g_object_set_data_full (G_OBJECT (storage), "storage-cache-item", item, g_free);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_static_mutex_unlock (&storage_cache_mutex);
|
|
Packit Service |
2781ba |
return storage;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static GeglBuffer *
|
|
Packit Service |
2781ba |
gegl_buffer_new_from_format (const void *babl_fmt,
|
|
Packit Service |
2781ba |
gint x,
|
|
Packit Service |
2781ba |
gint y,
|
|
Packit Service |
2781ba |
gint width,
|
|
Packit Service |
2781ba |
gint height,
|
|
Packit Service |
2781ba |
gint tile_width,
|
|
Packit Service |
2781ba |
gint tile_height,
|
|
Packit Service |
2781ba |
gboolean use_ram)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglTileStorage *tile_storage;
|
|
Packit Service |
2781ba |
GeglBuffer *buffer;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
tile_storage = gegl_tile_storage_new_cached (tile_width, tile_height, babl_fmt, use_ram);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
buffer = g_object_new (GEGL_TYPE_BUFFER,
|
|
Packit Service |
2781ba |
"source", tile_storage,
|
|
Packit Service |
2781ba |
"x", x,
|
|
Packit Service |
2781ba |
"y", y,
|
|
Packit Service |
2781ba |
"width", width,
|
|
Packit Service |
2781ba |
"height", height,
|
|
Packit Service |
2781ba |
"tile-width", tile_width,
|
|
Packit Service |
2781ba |
"tile-height", tile_height,
|
|
Packit Service |
2781ba |
NULL);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
g_object_unref (tile_storage);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return buffer;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static const void *gegl_buffer_internal_get_format (GeglBuffer *buffer)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_assert (buffer);
|
|
Packit Service |
2781ba |
if (buffer->format != NULL)
|
|
Packit Service |
2781ba |
return buffer->format;
|
|
Packit Service |
2781ba |
return gegl_tile_backend_get_format (gegl_buffer_backend (buffer));
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
const Babl *
|
|
Packit Service |
2781ba |
gegl_buffer_get_format (GeglBuffer *buffer)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
return buffer?buffer->format:NULL;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
const Babl *
|
|
Packit Service |
2781ba |
gegl_buffer_set_format (GeglBuffer *buffer,
|
|
Packit Service |
2781ba |
const Babl *format)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (format == NULL)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
buffer->soft_format = buffer->format;
|
|
Packit Service |
2781ba |
return buffer->soft_format;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
if (babl_format_get_bytes_per_pixel (format) ==
|
|
Packit Service |
2781ba |
babl_format_get_bytes_per_pixel (buffer->format))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
buffer->soft_format = format;
|
|
Packit Service |
2781ba |
return buffer->soft_format;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
g_warning ("tried to set format of different bpp on buffer\n");
|
|
Packit Service |
2781ba |
return NULL;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gboolean gegl_buffer_is_shared (GeglBuffer *buffer)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglTileBackend *backend = gegl_buffer_backend (buffer);
|
|
Packit Service |
2781ba |
return backend->priv->shared;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gboolean gegl_buffer_try_lock (GeglBuffer *buffer)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
gboolean ret;
|
|
Packit Service |
2781ba |
GeglTileBackend *backend = gegl_buffer_backend (buffer);
|
|
Packit Service |
2781ba |
g_mutex_lock (buffer->tile_storage->mutex);
|
|
Packit Service |
2781ba |
if (buffer->lock_count>0)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
buffer->lock_count++;
|
|
Packit Service |
2781ba |
g_mutex_unlock (buffer->tile_storage->mutex);
|
|
Packit Service |
2781ba |
return TRUE;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
if (gegl_buffer_is_shared(buffer))
|
|
Packit Service |
2781ba |
ret =gegl_tile_backend_file_try_lock (GEGL_TILE_BACKEND_FILE (backend));
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
ret = TRUE;
|
|
Packit Service |
2781ba |
if (ret)
|
|
Packit Service |
2781ba |
buffer->lock_count++;
|
|
Packit Service |
2781ba |
g_mutex_unlock (buffer->tile_storage->mutex);
|
|
Packit Service |
2781ba |
return TRUE;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* this locking is for synchronising shared buffers */
|
|
Packit Service |
2781ba |
gboolean gegl_buffer_lock (GeglBuffer *buffer)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
while (gegl_buffer_try_lock (buffer)==FALSE)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_print ("waiting to aquire buffer..");
|
|
Packit Service |
2781ba |
g_usleep (100000);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
return TRUE;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gboolean gegl_buffer_unlock (GeglBuffer *buffer)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
gboolean ret = TRUE;
|
|
Packit Service |
2781ba |
GeglTileBackend *backend = gegl_buffer_backend (buffer);
|
|
Packit Service |
2781ba |
g_mutex_lock (buffer->tile_storage->mutex);
|
|
Packit Service |
2781ba |
g_assert (buffer->lock_count >=0);
|
|
Packit Service |
2781ba |
buffer->lock_count--;
|
|
Packit Service |
2781ba |
g_assert (buffer->lock_count >=0);
|
|
Packit Service |
2781ba |
if (buffer->lock_count == 0 && gegl_buffer_is_shared (buffer))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
ret = gegl_tile_backend_file_unlock (GEGL_TILE_BACKEND_FILE (backend));
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
g_mutex_unlock (buffer->tile_storage->mutex);
|
|
Packit Service |
2781ba |
return ret;
|
|
Packit Service |
2781ba |
}
|