Add tile_manager_duplicate() which does quick tile-by-tile COW copy

and use it instead of duplicating the same code twice less efficiently.
This commit is contained in:
Michael Natterer 2010-03-19 19:16:31 +01:00
parent de583d4c28
commit 021a49ce73
4 changed files with 72 additions and 67 deletions

View File

@ -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,

View File

@ -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

View File

@ -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;
}

View File

@ -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)