libgimp: remove GimpDrawable and GimpTile

The GimpDrawable abstraction is completely gone, GimpTile is now a
small struct in gimptilebackendplugin.c.

All tile handling code is now in GimpTileBackendPlugin, the backend
functions are simply calling gimp_tile_get() and gimp_tile_put()
directly.
This commit is contained in:
Michael Natterer 2019-07-20 01:02:24 +02:00
parent 6a59ccf840
commit aafb55fa02
9 changed files with 283 additions and 560 deletions

View file

@ -236,8 +236,6 @@ libgimp_sources = \
gimpprogress.h \
gimpselection.c \
gimpselection.h \
gimptile.c \
gimptile.h \
gimptilebackendplugin.c \
gimptilebackendplugin.h \
gimpunitcache.c \

View file

@ -191,7 +191,6 @@ EXPORTS
gimp_drawable_curves_explicit
gimp_drawable_curves_spline
gimp_drawable_desaturate
gimp_drawable_detach
gimp_drawable_edit_bucket_fill
gimp_drawable_edit_clear
gimp_drawable_edit_fill
@ -200,10 +199,8 @@ EXPORTS
gimp_drawable_edit_stroke_selection
gimp_drawable_equalize
gimp_drawable_fill
gimp_drawable_flush
gimp_drawable_foreground_extract
gimp_drawable_free_shadow
gimp_drawable_get
gimp_drawable_get_buffer
gimp_drawable_get_format
gimp_drawable_get_pixel
@ -213,7 +210,6 @@ EXPORTS
gimp_drawable_get_thumbnail
gimp_drawable_get_thumbnail_data
gimp_drawable_get_thumbnail_format
gimp_drawable_get_tile
gimp_drawable_has_alpha
gimp_drawable_height
gimp_drawable_histogram

View file

@ -23,150 +23,10 @@
#define GIMP_DISABLE_DEPRECATION_WARNINGS
#include "gimp.h"
#include "gimptile.h"
#include "gimptilebackendplugin.h"
#define TILE_WIDTH gimp_tile_width()
#define TILE_HEIGHT gimp_tile_height()
/**
* gimp_drawable_get:
* @drawable_ID: the ID of the drawable
*
* This function creates a #GimpDrawable structure for the core
* drawable identified by @drawable_ID. The returned structure
* contains some basic information about the drawable and can also
* hold tile data for transfer to and from the core.
*
* Note that the name of this function is somewhat misleading, because
* it suggests that it simply returns a handle. This is not the case:
* if the function is called multiple times, it creates separate tile
* lists each time, which will usually produce undesired results.
*
* When a plug-in has finished working with a drawable, before exiting
* it should call gimp_drawable_detach() to make sure that all tile data is
* transferred back to the core.
*
* Return value: a new #GimpDrawable wrapper
**/
GimpDrawable *
gimp_drawable_get (gint32 drawable_ID)
{
GimpDrawable *drawable;
gint width;
gint height;
gint bpp;
width = gimp_drawable_width (drawable_ID);
height = gimp_drawable_height (drawable_ID);
bpp = gimp_drawable_bpp (drawable_ID);
g_return_val_if_fail (width > 0 && height > 0 && bpp > 0, NULL);
drawable = g_slice_new0 (GimpDrawable);
drawable->drawable_id = drawable_ID;
drawable->width = width;
drawable->height = height;
drawable->bpp = bpp;
drawable->ntile_rows = (height + TILE_HEIGHT - 1) / TILE_HEIGHT;
drawable->ntile_cols = (width + TILE_WIDTH - 1) / TILE_WIDTH;
return drawable;
}
/**
* gimp_drawable_detach:
* @drawable: The #GimpDrawable to detach from the core
*
* This function is called when a plug-in is finished working
* with a drawable. It forces all tile data held in the tile
* list of the #GimpDrawable to be transferred to the core, and
* then frees all associated memory. You must not access the
* @drawable after having called gimp_drawable_detach().
**/
void
gimp_drawable_detach (GimpDrawable *drawable)
{
g_return_if_fail (drawable != NULL);
if (drawable->tiles)
g_free (drawable->tiles);
if (drawable->shadow_tiles)
g_free (drawable->shadow_tiles);
g_slice_free (GimpDrawable, drawable);
}
GimpTile *
gimp_drawable_get_tile (GimpDrawable *drawable,
gboolean shadow,
gint row,
gint col)
{
GimpTile *tiles;
guint right_tile;
guint bottom_tile;
gint n_tiles;
gint tile_num;
gint i, j, k;
g_return_val_if_fail (drawable != NULL, NULL);
if (shadow)
tiles = drawable->shadow_tiles;
else
tiles = drawable->tiles;
if (! tiles)
{
n_tiles = drawable->ntile_rows * drawable->ntile_cols;
tiles = g_new (GimpTile, n_tiles);
right_tile = (drawable->width -
((drawable->ntile_cols - 1) * TILE_WIDTH));
bottom_tile = (drawable->height -
((drawable->ntile_rows - 1) * TILE_HEIGHT));
for (i = 0, k = 0; i < drawable->ntile_rows; i++)
{
for (j = 0; j < drawable->ntile_cols; j++, k++)
{
tiles[k].bpp = drawable->bpp;
tiles[k].tile_num = k;
tiles[k].ref_count = 0;
tiles[k].dirty = FALSE;
tiles[k].shadow = shadow;
tiles[k].data = NULL;
tiles[k].drawable = drawable;
if (j == (drawable->ntile_cols - 1))
tiles[k].ewidth = right_tile;
else
tiles[k].ewidth = TILE_WIDTH;
if (i == (drawable->ntile_rows - 1))
tiles[k].eheight = bottom_tile;
else
tiles[k].eheight = TILE_HEIGHT;
}
}
if (shadow)
drawable->shadow_tiles = tiles;
else
drawable->tiles = tiles;
}
tile_num = row * drawable->ntile_cols + col;
return &tiles[tile_num];
}
guchar *
gimp_drawable_get_thumbnail_data (gint32 drawable_ID,
gint *width,
@ -246,23 +106,16 @@ gimp_drawable_get_buffer (gint32 drawable_ID)
gimp_plugin_enable_precision ();
if (gimp_item_is_valid (drawable_ID))
{
GimpDrawable *drawable;
drawable = gimp_drawable_get (drawable_ID);
if (drawable)
{
GeglTileBackend *backend;
GeglBuffer *buffer;
backend = _gimp_tile_backend_plugin_new (drawable, FALSE);
backend = _gimp_tile_backend_plugin_new (drawable_ID, FALSE);
buffer = gegl_buffer_new_for_backend (NULL, backend);
g_object_unref (backend);
return buffer;
}
}
return NULL;
}
@ -285,18 +138,14 @@ gimp_drawable_get_buffer (gint32 drawable_ID)
GeglBuffer *
gimp_drawable_get_shadow_buffer (gint32 drawable_ID)
{
GimpDrawable *drawable;
gimp_plugin_enable_precision ();
drawable = gimp_drawable_get (drawable_ID);
if (drawable)
if (gimp_item_is_valid (drawable_ID))
{
GeglTileBackend *backend;
GeglBuffer *buffer;
backend = _gimp_tile_backend_plugin_new (drawable, TRUE);
backend = _gimp_tile_backend_plugin_new (drawable_ID, TRUE);
buffer = gegl_buffer_new_for_backend (NULL, backend);
g_object_unref (backend);

View file

@ -29,18 +29,6 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
struct _GimpDrawable
{
gint32 drawable_id; /* drawable ID */
guint width; /* width of drawble */
guint height; /* height of drawble */
guint bpp; /* bytes per pixel of drawable */
guint ntile_rows; /* # of tile rows */
guint ntile_cols; /* # of tile columns */
GimpTile *tiles; /* the normal tiles */
GimpTile *shadow_tiles; /* the shadow tiles */
};
GeglBuffer * gimp_drawable_get_buffer (gint32 drawable_ID);
GeglBuffer * gimp_drawable_get_shadow_buffer (gint32 drawable_ID);
@ -48,16 +36,6 @@ GeglBuffer * gimp_drawable_get_shadow_buffer (gint32 drawable_ID)
const Babl * gimp_drawable_get_format (gint32 drawable_ID);
const Babl * gimp_drawable_get_thumbnail_format (gint32 drawable_ID);
GIMP_DEPRECATED_FOR(gimp_drawable_get_buffer)
GimpDrawable * gimp_drawable_get (gint32 drawable_ID);
GIMP_DEPRECATED
void gimp_drawable_detach (GimpDrawable *drawable);
GIMP_DEPRECATED_FOR(gimp_drawable_get_buffer)
GimpTile * gimp_drawable_get_tile (GimpDrawable *drawable,
gboolean shadow,
gint row,
gint col);
guchar * gimp_drawable_get_thumbnail_data (gint32 drawable_ID,
gint *width,
gint *height,

View file

@ -1,215 +0,0 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimptile.c
*
* 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 3 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
* Library 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, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gio/gio.h>
#define GIMP_DISABLE_DEPRECATION_WARNINGS
#include "libgimpbase/gimpbase.h"
#include "libgimpbase/gimpprotocol.h"
#include "libgimpbase/gimpwire.h"
#include "gimp.h"
#include "gimptile.h"
/**
* SECTION: gimptile
* @title: gimptile
* @short_description: Functions for working with tiles.
*
* Functions for working with tiles.
**/
/* This is the percentage of the maximum cache size that
* should be cleared from the cache when an eviction is
* necessary.
*/
#define FREE_QUANTUM 0.1
void gimp_read_expect_msg (GimpWireMessage *msg,
gint type);
static void gimp_tile_get (GimpTile *tile);
static void gimp_tile_put (GimpTile *tile);
/* public functions */
void
_gimp_tile_ref_nocache (GimpTile *tile,
gboolean init)
{
g_return_if_fail (tile != NULL);
tile->ref_count++;
if (tile->ref_count == 1)
{
if (init)
{
gimp_tile_get (tile);
tile->dirty = FALSE;
}
else
{
tile->data = g_new (guchar, tile->ewidth * tile->eheight * tile->bpp);
}
}
}
void
_gimp_tile_unref (GimpTile *tile,
gboolean dirty)
{
g_return_if_fail (tile != NULL);
g_return_if_fail (tile->ref_count > 0);
tile->ref_count--;
tile->dirty |= dirty;
if (tile->ref_count == 0)
{
_gimp_tile_flush (tile);
g_free (tile->data);
tile->data = NULL;
}
}
void
_gimp_tile_flush (GimpTile *tile)
{
g_return_if_fail (tile != NULL);
if (tile->data && tile->dirty)
{
gimp_tile_put (tile);
tile->dirty = FALSE;
}
}
/* private functions */
static void
gimp_tile_get (GimpTile *tile)
{
extern GIOChannel *_writechannel;
GPTileReq tile_req;
GPTileData *tile_data;
GimpWireMessage msg;
tile_req.drawable_ID = tile->drawable->drawable_id;
tile_req.tile_num = tile->tile_num;
tile_req.shadow = tile->shadow;
gp_lock ();
if (! gp_tile_req_write (_writechannel, &tile_req, NULL))
gimp_quit ();
gimp_read_expect_msg (&msg, GP_TILE_DATA);
tile_data = msg.data;
if (tile_data->drawable_ID != tile->drawable->drawable_id ||
tile_data->tile_num != tile->tile_num ||
tile_data->shadow != tile->shadow ||
tile_data->width != tile->ewidth ||
tile_data->height != tile->eheight ||
tile_data->bpp != tile->bpp)
{
g_message ("received tile info did not match computed tile info");
gimp_quit ();
}
if (tile_data->use_shm)
{
tile->data = g_memdup (gimp_shm_addr (),
tile->ewidth * tile->eheight * tile->bpp);
}
else
{
tile->data = tile_data->data;
tile_data->data = NULL;
}
if (! gp_tile_ack_write (_writechannel, NULL))
gimp_quit ();
gp_unlock ();
gimp_wire_destroy (&msg);
}
static void
gimp_tile_put (GimpTile *tile)
{
extern GIOChannel *_writechannel;
GPTileReq tile_req;
GPTileData tile_data;
GPTileData *tile_info;
GimpWireMessage msg;
tile_req.drawable_ID = -1;
tile_req.tile_num = 0;
tile_req.shadow = 0;
gp_lock ();
if (! gp_tile_req_write (_writechannel, &tile_req, NULL))
gimp_quit ();
gimp_read_expect_msg (&msg, GP_TILE_DATA);
tile_info = msg.data;
tile_data.drawable_ID = tile->drawable->drawable_id;
tile_data.tile_num = tile->tile_num;
tile_data.shadow = tile->shadow;
tile_data.bpp = tile->bpp;
tile_data.width = tile->ewidth;
tile_data.height = tile->eheight;
tile_data.use_shm = tile_info->use_shm;
tile_data.data = NULL;
if (tile_info->use_shm)
memcpy (gimp_shm_addr (),
tile->data,
tile->ewidth * tile->eheight * tile->bpp);
else
tile_data.data = tile->data;
if (! gp_tile_data_write (_writechannel, &tile_data, NULL))
gimp_quit ();
if (! tile_info->use_shm)
tile_data.data = NULL;
gimp_wire_destroy (&msg);
gimp_read_expect_msg (&msg, GP_TILE_ACK);
gp_unlock ();
gimp_wire_destroy (&msg);
}

View file

@ -1,59 +0,0 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* gimptile.h
*
* 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 3 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, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
#error "Only <libgimp/gimp.h> can be included directly."
#endif
#ifndef __GIMP_TILE_H__
#define __GIMP_TILE_H__
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
struct _GimpTile
{
guint ewidth; /* the effective width of the tile */
guint eheight; /* the effective height of the tile */
guint bpp; /* the bytes per pixel (1, 2, 3 or 4 ) */
guint tile_num; /* the number of this tile within the drawable */
guint16 ref_count; /* reference count for the tile */
guint dirty : 1; /* is the tile dirty? has it been modified? */
guint shadow: 1; /* is this a shadow tile */
guchar *data; /* the pixel data for the tile */
GimpDrawable *drawable; /* the drawable this tile came from */
};
/* private function */
G_GNUC_INTERNAL void _gimp_tile_unref (GimpTile *tile,
gboolean dirty);
G_GNUC_INTERNAL void _gimp_tile_ref_nocache (GimpTile *tile,
gboolean init);
G_GNUC_INTERNAL void _gimp_tile_flush (GimpTile *tile);
G_END_DECLS
#endif /* __GIMP_TILE_H__ */

View file

@ -20,12 +20,14 @@
#include <stdlib.h>
#include <string.h>
#include <gio/gio.h>
#include <gegl.h>
#define GIMP_DISABLE_DEPRECATION_WARNINGS
#include "libgimpbase/gimpbase.h"
#include "libgimpbase/gimpprotocol.h"
#include "libgimpbase/gimpwire.h"
#include "gimp.h"
#include "gimptile.h"
#include "gimptilebackendplugin.h"
@ -33,35 +35,32 @@
#define TILE_HEIGHT gimp_tile_height()
typedef struct _GimpTile GimpTile;
struct _GimpTile
{
guint tile_num; /* the number of this tile within the drawable */
guint ewidth; /* the effective width of the tile */
guint eheight; /* the effective height of the tile */
guchar *data; /* the pixel data for the tile */
};
struct _GimpTileBackendPluginPrivate
{
GimpDrawable *drawable;
gint32 drawable_id;
gboolean shadow;
gint width;
gint height;
gint bpp;
gint ntile_rows;
gint ntile_cols;
gint mul;
};
static gint
gimp_gegl_tile_mul (void)
{
static gint mul = 1;
static gboolean inited = FALSE;
if (G_LIKELY (inited))
return mul;
inited = TRUE;
if (g_getenv ("GIMP_GEGL_TILE_MUL"))
mul = atoi (g_getenv ("GIMP_GEGL_TILE_MUL"));
if (mul < 1)
mul = 1;
return mul;
}
static void gimp_tile_backend_plugin_finalize (GObject *object);
static gpointer gimp_tile_backend_plugin_command (GeglTileSource *tile_store,
GeglTileCommand command,
gint x,
@ -73,11 +72,26 @@ static void gimp_tile_write_mul (GimpTileBackendPlugin *backend_plugin,
gint x,
gint y,
guchar *source);
static GeglTile * gimp_tile_read_mul (GimpTileBackendPlugin *backend_plugin,
gint x,
gint y);
static gint gimp_tile_mul (void);
static void gimp_tile_init (GimpTileBackendPlugin *backend_plugin,
GimpTile *tile,
gint row,
gint col);
static void gimp_tile_unset (GimpTileBackendPlugin *backend_plugin,
GimpTile *tile);
static void gimp_tile_get (GimpTileBackendPlugin *backend_plugin,
GimpTile *tile);
static void gimp_tile_put (GimpTileBackendPlugin *backend_plugin,
GimpTile *tile);
/* EEK */
void gimp_read_expect_msg (GimpWireMessage *msg,
gint type);
G_DEFINE_TYPE_WITH_PRIVATE (GimpTileBackendPlugin, _gimp_tile_backend_plugin,
GEGL_TYPE_TILE_BACKEND)
@ -91,9 +105,6 @@ static GMutex backend_plugin_mutex;
static void
_gimp_tile_backend_plugin_class_init (GimpTileBackendPluginClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gimp_tile_backend_plugin_finalize;
}
static void
@ -106,17 +117,6 @@ _gimp_tile_backend_plugin_init (GimpTileBackendPlugin *backend)
source->command = gimp_tile_backend_plugin_command;
}
static void
gimp_tile_backend_plugin_finalize (GObject *object)
{
GimpTileBackendPlugin *backend = GIMP_TILE_BACKEND_PLUGIN (object);
if (backend->priv->drawable) /* This also causes a flush */
gimp_drawable_detach (backend->priv->drawable);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gpointer
gimp_tile_backend_plugin_command (GeglTileSource *tile_store,
GeglTileCommand command,
@ -170,6 +170,66 @@ gimp_tile_backend_plugin_command (GeglTileSource *tile_store,
return result;
}
/* public functions */
GeglTileBackend *
_gimp_tile_backend_plugin_new (gint32 drawable_id,
gint shadow)
{
GeglTileBackend *backend;
GimpTileBackendPlugin *backend_plugin;
const Babl *format = gimp_drawable_get_format (drawable_id);
gint width = gimp_drawable_width (drawable_id);
gint height = gimp_drawable_height (drawable_id);
gint mul = gimp_tile_mul ();
backend = g_object_new (GIMP_TYPE_TILE_BACKEND_PLUGIN,
"tile-width", TILE_WIDTH * mul,
"tile-height", TILE_HEIGHT * mul,
"format", format,
NULL);
backend_plugin = GIMP_TILE_BACKEND_PLUGIN (backend);
backend_plugin->priv->drawable_id = drawable_id;
backend_plugin->priv->shadow = shadow;
backend_plugin->priv->width = width;
backend_plugin->priv->height = height;
backend_plugin->priv->bpp = gimp_drawable_bpp (drawable_id);
backend_plugin->priv->ntile_rows = (height + TILE_HEIGHT - 1) / TILE_HEIGHT;
backend_plugin->priv->ntile_cols = (width + TILE_WIDTH - 1) / TILE_WIDTH;
backend_plugin->priv->mul = mul;
gegl_tile_backend_set_extent (backend,
GEGL_RECTANGLE (0, 0, width, height));
return backend;
}
/* private functions */
static gint
gimp_tile_mul (void)
{
static gint mul = 1;
static gboolean inited = FALSE;
if (G_LIKELY (inited))
return mul;
inited = TRUE;
if (g_getenv ("GIMP_GEGL_TILE_MUL"))
mul = atoi (g_getenv ("GIMP_GEGL_TILE_MUL"));
if (mul < 1)
mul = 1;
return mul;
}
static GeglTile *
gimp_tile_read_mul (GimpTileBackendPlugin *backend_plugin,
gint x,
@ -194,21 +254,19 @@ gimp_tile_read_mul (GimpTileBackendPlugin *backend_plugin,
{
for (v = 0; v < mul; v++)
{
GimpTile *gimp_tile;
GimpTile gimp_tile = { 0, };
if (x + u >= priv->drawable->ntile_cols ||
y + v >= priv->drawable->ntile_rows)
if (x + u >= priv->ntile_cols ||
y + v >= priv->ntile_rows)
continue;
gimp_tile = gimp_drawable_get_tile (priv->drawable,
priv->shadow,
y + v, x + u);
_gimp_tile_ref_nocache (gimp_tile, TRUE);
gimp_tile_init (backend_plugin, &gimp_tile, y + v, x + u);
gimp_tile_get (backend_plugin, &gimp_tile);
{
gint ewidth = gimp_tile->ewidth;
gint eheight = gimp_tile->eheight;
gint bpp = gimp_tile->bpp;
gint ewidth = gimp_tile.ewidth;
gint eheight = gimp_tile.eheight;
gint bpp = priv->bpp;
gint tile_stride = mul * TILE_WIDTH * bpp;
gint gimp_tile_stride = ewidth * bpp;
gint row;
@ -217,12 +275,12 @@ gimp_tile_read_mul (GimpTileBackendPlugin *backend_plugin,
{
memcpy (tile_data + (row + TILE_HEIGHT * v) *
tile_stride + u * TILE_WIDTH * bpp,
((gchar *) gimp_tile->data) + row * gimp_tile_stride,
((gchar *) gimp_tile.data) + row * gimp_tile_stride,
gimp_tile_stride);
}
}
_gimp_tile_unref (gimp_tile, FALSE);
gimp_tile_unset (backend_plugin, &gimp_tile);
}
}
@ -246,64 +304,184 @@ gimp_tile_write_mul (GimpTileBackendPlugin *backend_plugin,
{
for (u = 0; u < mul; u++)
{
GimpTile *gimp_tile;
GimpTile gimp_tile = { 0, };
if (x + u >= priv->drawable->ntile_cols ||
y + v >= priv->drawable->ntile_rows)
if (x + u >= priv->ntile_cols ||
y + v >= priv->ntile_rows)
continue;
gimp_tile = gimp_drawable_get_tile (priv->drawable,
priv->shadow,
y+v, x+u);
_gimp_tile_ref_nocache (gimp_tile, FALSE);
gimp_tile_init (backend_plugin, &gimp_tile, y + v, x + u);
gimp_tile.data = g_new (guchar,
gimp_tile.ewidth * gimp_tile.eheight *
priv->bpp);
{
gint ewidth = gimp_tile->ewidth;
gint eheight = gimp_tile->eheight;
gint bpp = gimp_tile->bpp;
gint ewidth = gimp_tile.ewidth;
gint eheight = gimp_tile.eheight;
gint bpp = priv->bpp;
gint tile_stride = mul * TILE_WIDTH * bpp;
gint gimp_tile_stride = ewidth * bpp;
gint row;
for (row = 0; row < eheight; row++)
memcpy (((gchar *)gimp_tile->data) + row * gimp_tile_stride,
memcpy (((gchar *) gimp_tile.data) + row * gimp_tile_stride,
source + (row + v * TILE_HEIGHT) *
tile_stride + u * TILE_WIDTH * bpp,
gimp_tile_stride);
}
_gimp_tile_unref (gimp_tile, TRUE);
gimp_tile_put (backend_plugin, &gimp_tile);
gimp_tile_unset (backend_plugin, &gimp_tile);
}
}
}
GeglTileBackend *
_gimp_tile_backend_plugin_new (GimpDrawable *drawable,
gint shadow)
static void
gimp_tile_init (GimpTileBackendPlugin *backend_plugin,
GimpTile *tile,
gint row,
gint col)
{
GeglTileBackend *backend;
GimpTileBackendPlugin *backend_plugin;
const Babl *format;
gint width = gimp_drawable_width (drawable->drawable_id);
gint height = gimp_drawable_height (drawable->drawable_id);
gint mul = gimp_gegl_tile_mul ();
GimpTileBackendPluginPrivate *priv = backend_plugin->priv;
format = gimp_drawable_get_format (drawable->drawable_id);
tile->tile_num = row * priv->ntile_cols + col;
backend = g_object_new (GIMP_TYPE_TILE_BACKEND_PLUGIN,
"tile-width", TILE_WIDTH * mul,
"tile-height", TILE_HEIGHT * mul,
"format", format,
NULL);
if (col == (priv->ntile_cols - 1))
tile->ewidth = priv->width - ((priv->ntile_cols - 1) * TILE_WIDTH);
else
tile->ewidth = TILE_WIDTH;
backend_plugin = GIMP_TILE_BACKEND_PLUGIN (backend);
if (row == (priv->ntile_rows - 1))
tile->eheight = priv->height - ((priv->ntile_rows - 1) * TILE_HEIGHT);
else
tile->eheight = TILE_HEIGHT;
backend_plugin->priv->drawable = drawable;
backend_plugin->priv->mul = mul;
backend_plugin->priv->shadow = shadow;
gegl_tile_backend_set_extent (backend,
GEGL_RECTANGLE (0, 0, width, height));
return backend;
tile->data = NULL;
}
static void
gimp_tile_unset (GimpTileBackendPlugin *backend_plugin,
GimpTile *tile)
{
g_clear_pointer (&tile->data, g_free);
}
static void
gimp_tile_get (GimpTileBackendPlugin *backend_plugin,
GimpTile *tile)
{
extern GIOChannel *_writechannel;
GimpTileBackendPluginPrivate *priv = backend_plugin->priv;
GPTileReq tile_req;
GPTileData *tile_data;
GimpWireMessage msg;
tile_req.drawable_ID = priv->drawable_id;
tile_req.tile_num = tile->tile_num;
tile_req.shadow = priv->shadow;
gp_lock ();
if (! gp_tile_req_write (_writechannel, &tile_req, NULL))
gimp_quit ();
gimp_read_expect_msg (&msg, GP_TILE_DATA);
tile_data = msg.data;
if (tile_data->drawable_ID != priv->drawable_id ||
tile_data->tile_num != tile->tile_num ||
tile_data->shadow != priv->shadow ||
tile_data->width != tile->ewidth ||
tile_data->height != tile->eheight ||
tile_data->bpp != priv->bpp)
{
#if 0
g_printerr ("tile_data: %d %d %d %d %d %d\n"
"tile: %d %d %d %d %d %d\n",
tile_data->drawable_ID,
tile_data->tile_num,
tile_data->shadow,
tile_data->width,
tile_data->height,
tile_data->bpp,
priv->drawable_id,
tile->tile_num,
priv->shadow,
tile->ewidth,
tile->eheight,
priv->bpp);
#endif
g_printerr ("received tile info did not match computed tile info");
gimp_quit ();
}
if (tile_data->use_shm)
{
tile->data = g_memdup (gimp_shm_addr (),
tile->ewidth * tile->eheight * priv->bpp);
}
else
{
tile->data = tile_data->data;
tile_data->data = NULL;
}
if (! gp_tile_ack_write (_writechannel, NULL))
gimp_quit ();
gp_unlock ();
gimp_wire_destroy (&msg);
}
static void
gimp_tile_put (GimpTileBackendPlugin *backend_plugin,
GimpTile *tile)
{
extern GIOChannel *_writechannel;
GimpTileBackendPluginPrivate *priv = backend_plugin->priv;
GPTileReq tile_req;
GPTileData tile_data;
GPTileData *tile_info;
GimpWireMessage msg;
tile_req.drawable_ID = -1;
tile_req.tile_num = 0;
tile_req.shadow = 0;
gp_lock ();
if (! gp_tile_req_write (_writechannel, &tile_req, NULL))
gimp_quit ();
gimp_read_expect_msg (&msg, GP_TILE_DATA);
tile_info = msg.data;
tile_data.drawable_ID = priv->drawable_id;
tile_data.tile_num = tile->tile_num;
tile_data.shadow = priv->shadow;
tile_data.bpp = priv->bpp;
tile_data.width = tile->ewidth;
tile_data.height = tile->eheight;
tile_data.use_shm = tile_info->use_shm;
tile_data.data = NULL;
if (tile_info->use_shm)
memcpy (gimp_shm_addr (),
tile->data,
tile->ewidth * tile->eheight * priv->bpp);
else
tile_data.data = tile->data;
if (! gp_tile_data_write (_writechannel, &tile_data, NULL))
gimp_quit ();
if (! tile_info->use_shm)
tile_data.data = NULL;
gimp_wire_destroy (&msg);
gimp_read_expect_msg (&msg, GP_TILE_ACK);
gp_unlock ();
gimp_wire_destroy (&msg);
}

View file

@ -51,7 +51,7 @@ struct _GimpTileBackendPluginClass
GType _gimp_tile_backend_plugin_get_type (void) G_GNUC_CONST;
GeglTileBackend * _gimp_tile_backend_plugin_new (GimpDrawable *drawable,
GeglTileBackend * _gimp_tile_backend_plugin_new (gint32 drawable_id,
gint shadow);
G_END_DECLS

View file

@ -29,8 +29,6 @@ G_BEGIN_DECLS
typedef struct _GimpPlugInInfo GimpPlugInInfo;
typedef struct _GimpTile GimpTile;
typedef struct _GimpDrawable GimpDrawable;
typedef struct _GimpParamDef GimpParamDef;
typedef struct _GimpParamRegion GimpParamRegion;
typedef union _GimpParamData GimpParamData;