mirror of https://github.com/GNOME/gimp.git
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:
parent
de583d4c28
commit
021a49ce73
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue