From 021a49ce7346707984bbfb4808b02b55f1dac567 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Fri, 19 Mar 2010 19:16:31 +0100 Subject: [PATCH] Add tile_manager_duplicate() which does quick tile-by-tile COW copy and use it instead of duplicating the same code twice less efficiently. --- app/base/tile-manager.c | 27 ++++++++++ app/base/tile-manager.h | 4 ++ app/core/gimpbuffer.c | 17 +------ app/core/gimpdrawablemodundo.c | 91 +++++++++++++++------------------- 4 files changed, 72 insertions(+), 67 deletions(-) diff --git a/app/base/tile-manager.c b/app/base/tile-manager.c index 556498ca3b..2f29c32df6 100644 --- a/app/base/tile-manager.c +++ b/app/base/tile-manager.c @@ -158,6 +158,33 @@ tile_manager_unref (TileManager *tm) } } +TileManager * +tile_manager_duplicate (TileManager *tm) +{ + TileManager *copy; + gint n_tiles; + gint i; + + g_return_val_if_fail (tm != NULL, NULL); + + copy = tile_manager_new (tm->width, tm->height, tm->bpp); + + tile_manager_allocate_tiles (copy); + + n_tiles = tm->ntile_rows * tm->ntile_cols; + + for (i = 0; i < n_tiles; i++) + { + Tile *tile; + + tile = tile_manager_get (tm, i, TRUE, FALSE); + tile_manager_map (copy, i, tile); + tile_release (tile, FALSE); + } + + return copy; +} + void tile_manager_set_validate_proc (TileManager *tm, TileValidateProc proc, diff --git a/app/base/tile-manager.h b/app/base/tile-manager.h index 40b5045244..336c9cd835 100644 --- a/app/base/tile-manager.h +++ b/app/base/tile-manager.h @@ -38,6 +38,10 @@ TileManager * tile_manager_new (gint width, TileManager * tile_manager_ref (TileManager *tm); void tile_manager_unref (TileManager *tm); +/* Make a copy of the tile manager. + */ +TileManager * tile_manager_duplicate (TileManager *tm); + /* Set the validate procedure for the tile manager. The validate * procedure is called when an invalid tile is referenced. If the * procedure is NULL, then the tile is set to valid and its memory is diff --git a/app/core/gimpbuffer.c b/app/core/gimpbuffer.c index fea787dfbe..8e69658dea 100644 --- a/app/core/gimpbuffer.c +++ b/app/core/gimpbuffer.c @@ -28,8 +28,6 @@ #include "base/tile-manager-preview.h" #include "base/temp-buf.h" -#include "paint-funcs/paint-funcs.h" - #include "gimpbuffer.h" @@ -234,20 +232,9 @@ gimp_buffer_new (TileManager *tiles, NULL); if (copy_pixels) - { - PixelRegion srcPR, destPR; - - buffer->tiles = tile_manager_new (width, height, - tile_manager_bpp (tiles)); - - pixel_region_init (&srcPR, tiles, 0, 0, width, height, FALSE); - pixel_region_init (&destPR, buffer->tiles, 0, 0, width, height, TRUE); - copy_region (&srcPR, &destPR); - } + buffer->tiles = tile_manager_duplicate (tiles); else - { - buffer->tiles = tile_manager_ref (tiles); - } + buffer->tiles = tile_manager_ref (tiles); return buffer; } diff --git a/app/core/gimpdrawablemodundo.c b/app/core/gimpdrawablemodundo.c index a416790f3c..12b24fb0ba 100644 --- a/app/core/gimpdrawablemodundo.c +++ b/app/core/gimpdrawablemodundo.c @@ -21,11 +21,8 @@ #include "core-types.h" -#include "base/pixel-region.h" #include "base/tile-manager.h" -#include "paint-funcs/paint-funcs.h" - #include "gimpimage.h" #include "gimpdrawable.h" #include "gimpdrawablemodundo.h" @@ -94,6 +91,45 @@ gimp_drawable_mod_undo_init (GimpDrawableModUndo *undo) { } +static GObject * +gimp_drawable_mod_undo_constructor (GType type, + guint n_params, + GObjectConstructParam *params) +{ + GObject *object; + GimpDrawableModUndo *drawable_mod_undo; + GimpItem *item; + GimpDrawable *drawable; + + object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params); + + drawable_mod_undo = GIMP_DRAWABLE_MOD_UNDO (object); + + g_assert (GIMP_IS_DRAWABLE (GIMP_ITEM_UNDO (object)->item)); + + item = GIMP_ITEM_UNDO (object)->item; + drawable = GIMP_DRAWABLE (item); + + if (drawable_mod_undo->copy_tiles) + { + drawable_mod_undo->tiles = + tile_manager_duplicate (gimp_drawable_get_tiles (drawable)); + } + else + { + drawable_mod_undo->tiles = + tile_manager_ref (gimp_drawable_get_tiles (drawable)); + } + + drawable_mod_undo->type = gimp_drawable_type (drawable); + + gimp_item_get_offset (item, + &drawable_mod_undo->offset_x, + &drawable_mod_undo->offset_y); + + return object; +} + static void gimp_drawable_mod_undo_set_property (GObject *object, guint property_id, @@ -134,55 +170,6 @@ gimp_drawable_mod_undo_get_property (GObject *object, } } -static GObject * -gimp_drawable_mod_undo_constructor (GType type, - guint n_params, - GObjectConstructParam *params) -{ - GObject *object; - GimpDrawableModUndo *drawable_mod_undo; - GimpItem *item; - GimpDrawable *drawable; - - object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params); - - drawable_mod_undo = GIMP_DRAWABLE_MOD_UNDO (object); - - g_assert (GIMP_IS_DRAWABLE (GIMP_ITEM_UNDO (object)->item)); - - item = GIMP_ITEM_UNDO (object)->item; - drawable = GIMP_DRAWABLE (item); - - if (drawable_mod_undo->copy_tiles) - { - PixelRegion srcPR, destPR; - gint width = gimp_item_get_width (item); - gint height = gimp_item_get_height (item); - - drawable_mod_undo->tiles = - tile_manager_new (width, height, - gimp_drawable_bytes (drawable)); - pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable), - 0, 0, width, height, FALSE); - pixel_region_init (&destPR, drawable_mod_undo->tiles, - 0, 0, width, height, TRUE); - copy_region (&srcPR, &destPR); - } - else - { - drawable_mod_undo->tiles = - tile_manager_ref (gimp_drawable_get_tiles (drawable)); - } - - drawable_mod_undo->type = gimp_drawable_type (drawable); - - gimp_item_get_offset (item, - &drawable_mod_undo->offset_x, - &drawable_mod_undo->offset_y); - - return object; -} - static gint64 gimp_drawable_mod_undo_get_memsize (GimpObject *object, gint64 *gui_size)