diff --git a/libgimp/Makefile.am b/libgimp/Makefile.am index a0c984d0a4..5446d911f3 100644 --- a/libgimp/Makefile.am +++ b/libgimp/Makefile.am @@ -236,8 +236,6 @@ libgimp_sources = \ gimpprogress.h \ gimpselection.c \ gimpselection.h \ - gimptile.c \ - gimptile.h \ gimptilebackendplugin.c \ gimptilebackendplugin.h \ gimpunitcache.c \ diff --git a/libgimp/gimp.def b/libgimp/gimp.def index 7bd79ab887..86072aeb57 100644 --- a/libgimp/gimp.def +++ b/libgimp/gimp.def @@ -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 diff --git a/libgimp/gimpdrawable.c b/libgimp/gimpdrawable.c index d2bfccb771..a2223cfc1c 100644 --- a/libgimp/gimpdrawable.c +++ b/libgimp/gimpdrawable.c @@ -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, @@ -247,21 +107,14 @@ gimp_drawable_get_buffer (gint32 drawable_ID) if (gimp_item_is_valid (drawable_ID)) { - GimpDrawable *drawable; + GeglTileBackend *backend; + GeglBuffer *buffer; - drawable = gimp_drawable_get (drawable_ID); + backend = _gimp_tile_backend_plugin_new (drawable_ID, FALSE); + buffer = gegl_buffer_new_for_backend (NULL, backend); + g_object_unref (backend); - if (drawable) - { - GeglTileBackend *backend; - GeglBuffer *buffer; - - backend = _gimp_tile_backend_plugin_new (drawable, FALSE); - buffer = gegl_buffer_new_for_backend (NULL, backend); - g_object_unref (backend); - - return buffer; - } + 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); diff --git a/libgimp/gimpdrawable.h b/libgimp/gimpdrawable.h index 038ed5238f..d2675791cf 100644 --- a/libgimp/gimpdrawable.h +++ b/libgimp/gimpdrawable.h @@ -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, diff --git a/libgimp/gimptile.c b/libgimp/gimptile.c deleted file mode 100644 index 68e8fe9958..0000000000 --- a/libgimp/gimptile.c +++ /dev/null @@ -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 - * . - */ - -#include "config.h" - -#include - -#include - -#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); -} diff --git a/libgimp/gimptile.h b/libgimp/gimptile.h deleted file mode 100644 index e41c703b46..0000000000 --- a/libgimp/gimptile.h +++ /dev/null @@ -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 - * . - */ - -#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION) -#error "Only 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__ */ diff --git a/libgimp/gimptilebackendplugin.c b/libgimp/gimptilebackendplugin.c index 929b68a138..a38fa1845b 100644 --- a/libgimp/gimptilebackendplugin.c +++ b/libgimp/gimptilebackendplugin.c @@ -20,12 +20,14 @@ #include #include +#include #include -#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,50 +35,62 @@ #define TILE_HEIGHT gimp_tile_height() -struct _GimpTileBackendPluginPrivate +typedef struct _GimpTile GimpTile; + +struct _GimpTile { - GimpDrawable *drawable; - gboolean shadow; - gint mul; + 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 */ }; -static gint -gimp_gegl_tile_mul (void) +struct _GimpTileBackendPluginPrivate { - static gint mul = 1; - static gboolean inited = FALSE; + gint32 drawable_id; + gboolean shadow; + gint width; + gint height; + gint bpp; + gint ntile_rows; + gint ntile_cols; + gint mul; +}; - 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, - gint y, - gint z, - gpointer data); +static gpointer gimp_tile_backend_plugin_command (GeglTileSource *tile_store, + GeglTileCommand command, + gint x, + gint y, + gint z, + gpointer data); 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 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, @@ -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); } diff --git a/libgimp/gimptilebackendplugin.h b/libgimp/gimptilebackendplugin.h index f536c5f279..fb885b460e 100644 --- a/libgimp/gimptilebackendplugin.h +++ b/libgimp/gimptilebackendplugin.h @@ -51,8 +51,8 @@ struct _GimpTileBackendPluginClass GType _gimp_tile_backend_plugin_get_type (void) G_GNUC_CONST; -GeglTileBackend * _gimp_tile_backend_plugin_new (GimpDrawable *drawable, - gint shadow); +GeglTileBackend * _gimp_tile_backend_plugin_new (gint32 drawable_id, + gint shadow); G_END_DECLS diff --git a/libgimp/gimptypes.h b/libgimp/gimptypes.h index 42b3627136..bf5993957a 100644 --- a/libgimp/gimptypes.h +++ b/libgimp/gimptypes.h @@ -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;