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



commit 021a49ce7346707984bbfb4808b02b55f1dac567
Author: Michael Natterer <mitch gimp org>
Date:   Fri Mar 19 19:16:31 2010 +0100

    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 556498c..2f29c32 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 40b5045..336c9cd 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 fea787d..8e69658 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 a416790..12b24fb 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)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]