app: turn the drawable's shadow tiles into a shadow buffer

This commit is contained in:
Michael Natterer 2012-03-22 19:10:12 +01:00
parent dbc881376e
commit 99ae46b4ed
11 changed files with 88 additions and 85 deletions

View File

@ -59,19 +59,15 @@ gimp_drawable_apply_operation (GimpDrawable *drawable,
&rect.width, &rect.height)) &rect.width, &rect.height))
return; return;
dest_buffer = dest_buffer = gimp_drawable_get_shadow_buffer (drawable);
gimp_tile_manager_create_buffer (gimp_drawable_get_shadow_tiles (drawable),
gimp_drawable_get_format (drawable));
gimp_apply_operation (gimp_drawable_get_buffer (drawable), gimp_apply_operation (gimp_drawable_get_buffer (drawable),
progress, undo_desc, progress, undo_desc,
operation, linear, operation, linear,
dest_buffer, &rect); dest_buffer, &rect);
g_object_unref (dest_buffer); gimp_drawable_merge_shadow_buffer (drawable, TRUE, undo_desc);
gimp_drawable_free_shadow_buffer (drawable);
gimp_drawable_merge_shadow_tiles (drawable, TRUE, undo_desc);
gimp_drawable_free_shadow_tiles (drawable);
gimp_drawable_update (drawable, rect.x, rect.y, rect.width, rect.height); gimp_drawable_update (drawable, rect.x, rect.y, rect.width, rect.height);

View File

@ -23,7 +23,7 @@ struct _GimpDrawablePrivate
const Babl *format; /* format of drawable */ const Babl *format; /* format of drawable */
GeglBuffer *buffer; /* buffer for drawable data */ GeglBuffer *buffer; /* buffer for drawable data */
TileManager *shadow; /* shadow buffer tiles */ GeglBuffer *shadow; /* shadow buffer */
GeglNode *source_node; GeglNode *source_node;
GeglNode *buffer_source_node; GeglNode *buffer_source_node;

View File

@ -25,6 +25,8 @@
#include "base/pixel-processor.h" #include "base/pixel-processor.h"
#include "base/pixel-region.h" #include "base/pixel-region.h"
#include "gegl/gimp-gegl-utils.h"
#include "gimpdrawable.h" #include "gimpdrawable.h"
#include "gimpdrawable-process.h" #include "gimpdrawable-process.h"
#include "gimpdrawable-shadow.h" #include "gimpdrawable-shadow.h"
@ -47,17 +49,20 @@ gimp_drawable_process (GimpDrawable *drawable,
if (gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) if (gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
{ {
PixelRegion srcPR, destPR; GeglBuffer *dest_buffer;
PixelRegion srcPR, destPR;
dest_buffer = gimp_drawable_get_shadow_buffer (drawable);
pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable), pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
x, y, width, height, FALSE); x, y, width, height, FALSE);
pixel_region_init (&destPR, gimp_drawable_get_shadow_tiles (drawable), pixel_region_init (&destPR, gimp_gegl_buffer_get_tiles (dest_buffer),
x, y, width, height, TRUE); x, y, width, height, TRUE);
pixel_regions_process_parallel (func, data, 2, &srcPR, &destPR); pixel_regions_process_parallel (func, data, 2, &srcPR, &destPR);
gimp_drawable_merge_shadow_tiles (drawable, TRUE, undo_desc); gimp_drawable_merge_shadow_buffer (drawable, TRUE, undo_desc);
gimp_drawable_free_shadow_tiles (drawable); gimp_drawable_free_shadow_buffer (drawable);
gimp_drawable_update (drawable, x, y, width, height); gimp_drawable_update (drawable, x, y, width, height);
} }

View File

@ -21,34 +21,36 @@
#include "core-types.h" #include "core-types.h"
#include "base/pixel-region.h" #include "gegl/gimp-gegl-utils.h"
#include "base/tile-manager.h"
#include "gimpdrawable.h" #include "gimpdrawable.h"
#include "gimpdrawable-private.h" #include "gimpdrawable-private.h"
#include "gimpdrawable-shadow.h" #include "gimpdrawable-shadow.h"
TileManager * GeglBuffer *
gimp_drawable_get_shadow_tiles (GimpDrawable *drawable) gimp_drawable_get_shadow_buffer (GimpDrawable *drawable)
{ {
GimpItem *item; GimpItem *item;
gint width;
gint height;
const Babl *format;
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
item = GIMP_ITEM (drawable); item = GIMP_ITEM (drawable);
width = gimp_item_get_width (item);
height = gimp_item_get_height (item);
format = gimp_drawable_get_format (drawable);
if (drawable->private->shadow) if (drawable->private->shadow)
{ {
gint width = gimp_item_get_width (item); if ((width != gegl_buffer_get_width (drawable->private->shadow)) ||
gint height = gimp_item_get_height (item); (height != gegl_buffer_get_height (drawable->private->shadow)) ||
gint bytes = gimp_drawable_bytes (drawable); (format != gegl_buffer_get_format (drawable->private->shadow)))
if ((width != tile_manager_width (drawable->private->shadow)) ||
(height != tile_manager_height (drawable->private->shadow)) ||
(bytes != tile_manager_bpp (drawable->private->shadow)))
{ {
gimp_drawable_free_shadow_tiles (drawable); gimp_drawable_free_shadow_buffer (drawable);
} }
else else
{ {
@ -56,36 +58,35 @@ gimp_drawable_get_shadow_tiles (GimpDrawable *drawable)
} }
} }
drawable->private->shadow = tile_manager_new (gimp_item_get_width (item), drawable->private->shadow =
gimp_item_get_height (item), gimp_gegl_buffer_new (GIMP_GEGL_RECT (0, 0, width, height), format);
gimp_drawable_bytes (drawable));
return drawable->private->shadow; return drawable->private->shadow;
} }
void void
gimp_drawable_free_shadow_tiles (GimpDrawable *drawable) gimp_drawable_free_shadow_buffer (GimpDrawable *drawable)
{ {
g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
if (drawable->private->shadow) if (drawable->private->shadow)
{ {
tile_manager_unref (drawable->private->shadow); g_object_unref (drawable->private->shadow);
drawable->private->shadow = NULL; drawable->private->shadow = NULL;
} }
} }
void void
gimp_drawable_merge_shadow_tiles (GimpDrawable *drawable, gimp_drawable_merge_shadow_buffer (GimpDrawable *drawable,
gboolean push_undo, gboolean push_undo,
const gchar *undo_desc) const gchar *undo_desc)
{ {
gint x, y; gint x, y;
gint width, height; gint width, height;
g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
g_return_if_fail (drawable->private->shadow != NULL); g_return_if_fail (GEGL_IS_BUFFER (drawable->private->shadow));
/* A useful optimization here is to limit the update to the /* A useful optimization here is to limit the update to the
* extents of the selection mask, as it cannot extend beyond * extents of the selection mask, as it cannot extend beyond
@ -93,16 +94,14 @@ gimp_drawable_merge_shadow_tiles (GimpDrawable *drawable,
*/ */
if (gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) if (gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
{ {
TileManager *tiles = tile_manager_ref (drawable->private->shadow); GeglBuffer *buffer = g_object_ref (drawable->private->shadow);
PixelRegion shadowPR;
pixel_region_init (&shadowPR, tiles, x, y, width, height, FALSE); gimp_drawable_apply_buffer (drawable, buffer,
GIMP_GEGL_RECT (x, y, width, height),
gimp_drawable_apply_region (drawable, &shadowPR,
push_undo, undo_desc, push_undo, undo_desc,
GIMP_OPACITY_OPAQUE, GIMP_REPLACE_MODE, GIMP_OPACITY_OPAQUE, GIMP_REPLACE_MODE,
NULL, NULL, x, y); NULL, NULL, x, y);
tile_manager_unref (tiles); g_object_unref (buffer);
} }
} }

View File

@ -21,10 +21,10 @@
#define __GIMP_DRAWABLE_SHADOW_H__ #define __GIMP_DRAWABLE_SHADOW_H__
TileManager * gimp_drawable_get_shadow_tiles (GimpDrawable *drawable); GeglBuffer * gimp_drawable_get_shadow_buffer (GimpDrawable *drawable);
void gimp_drawable_free_shadow_tiles (GimpDrawable *drawable); void gimp_drawable_free_shadow_buffer (GimpDrawable *drawable);
void gimp_drawable_merge_shadow_tiles (GimpDrawable *drawable, void gimp_drawable_merge_shadow_buffer (GimpDrawable *drawable,
gboolean push_undo, gboolean push_undo,
const gchar *undo_desc); const gchar *undo_desc);

View File

@ -294,7 +294,7 @@ gimp_drawable_finalize (GObject *object)
drawable->private->buffer = NULL; drawable->private->buffer = NULL;
} }
gimp_drawable_free_shadow_tiles (drawable); gimp_drawable_free_shadow_buffer (drawable);
if (drawable->private->source_node) if (drawable->private->source_node)
{ {
@ -316,7 +316,7 @@ gimp_drawable_get_memsize (GimpObject *object,
gint64 memsize = 0; gint64 memsize = 0;
memsize += gimp_gegl_buffer_get_memsize (gimp_drawable_get_buffer (drawable)); memsize += gimp_gegl_buffer_get_memsize (gimp_drawable_get_buffer (drawable));
memsize += tile_manager_get_memsize (drawable->private->shadow, FALSE); memsize += gimp_gegl_buffer_get_memsize (drawable->private->shadow);
*gui_size += gimp_preview_cache_get_memsize (drawable->private->preview_cache); *gui_size += gimp_preview_cache_get_memsize (drawable->private->preview_cache);
@ -355,7 +355,7 @@ gimp_drawable_removed (GimpItem *item)
{ {
GimpDrawable *drawable = GIMP_DRAWABLE (item); GimpDrawable *drawable = GIMP_DRAWABLE (item);
gimp_drawable_free_shadow_tiles (drawable); gimp_drawable_free_shadow_buffer (drawable);
if (GIMP_ITEM_CLASS (parent_class)->removed) if (GIMP_ITEM_CLASS (parent_class)->removed)
GIMP_ITEM_CLASS (parent_class)->removed (item); GIMP_ITEM_CLASS (parent_class)->removed (item);

View File

@ -237,7 +237,7 @@ gimp_image_map_finalize (GObject *object)
if (image_map->drawable) if (image_map->drawable)
{ {
gimp_drawable_free_shadow_tiles (image_map->drawable); gimp_drawable_free_shadow_buffer (image_map->drawable);
g_object_unref (image_map->drawable); g_object_unref (image_map->drawable);
image_map->drawable = NULL; image_map->drawable = NULL;
@ -410,14 +410,11 @@ gimp_image_map_apply (GimpImageMap *image_map,
if (image_map->operation) if (image_map->operation)
{ {
const Babl *format = gimp_drawable_get_format (image_map->drawable);
GeglBuffer *input_buffer; GeglBuffer *input_buffer;
GeglBuffer *output_buffer; GeglBuffer *output_buffer;
input_buffer = image_map->undo_buffer; input_buffer = image_map->undo_buffer;
output_buffer = gimp_drawable_get_shadow_buffer (image_map->drawable);
output_buffer =
gimp_tile_manager_create_buffer (gimp_drawable_get_shadow_tiles (image_map->drawable), format);
if (! image_map->gegl) if (! image_map->gegl)
{ {
@ -505,11 +502,13 @@ gimp_image_map_apply (GimpImageMap *image_map,
image_map->processor = gegl_node_new_processor (image_map->output, image_map->processor = gegl_node_new_processor (image_map->output,
&rect); &rect);
g_object_unref (output_buffer);
} }
else else
{ {
GeglBuffer *output_buffer;
output_buffer = gimp_drawable_get_shadow_buffer (image_map->drawable);
/* Configure the src from the drawable data */ /* Configure the src from the drawable data */
pixel_region_init (&image_map->srcPR, pixel_region_init (&image_map->srcPR,
gimp_gegl_buffer_get_tiles (image_map->undo_buffer), gimp_gegl_buffer_get_tiles (image_map->undo_buffer),
@ -519,7 +518,7 @@ gimp_image_map_apply (GimpImageMap *image_map,
/* Configure the dest as the shadow buffer */ /* Configure the dest as the shadow buffer */
pixel_region_init (&image_map->destPR, pixel_region_init (&image_map->destPR,
gimp_drawable_get_shadow_tiles (image_map->drawable), gimp_gegl_buffer_get_tiles (output_buffer),
rect.x, rect.y, rect.x, rect.y,
rect.width, rect.height, rect.width, rect.height,
TRUE); TRUE);
@ -745,8 +744,9 @@ gimp_image_map_do (GimpImageMap *image_map)
*/ */
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{ {
PixelRegion srcPR; GeglBuffer *src_buffer;
gint x, y, w, h; PixelRegion srcPR;
gint x, y, w, h;
if (image_map->timer) if (image_map->timer)
g_timer_continue (image_map->timer); g_timer_continue (image_map->timer);
@ -770,9 +770,10 @@ gimp_image_map_do (GimpImageMap *image_map)
&image_map->srcPR, &image_map->srcPR,
&image_map->destPR); &image_map->destPR);
src_buffer = gimp_drawable_get_shadow_buffer (image_map->drawable);
pixel_region_init (&srcPR, pixel_region_init (&srcPR,
gimp_drawable_get_shadow_tiles (image_map->drawable), gimp_gegl_buffer_get_tiles (src_buffer),
x, y, w, h, FALSE); x, y, w, h, FALSE);
gimp_drawable_apply_region (image_map->drawable, &srcPR, gimp_drawable_apply_region (image_map->drawable, &srcPR,
@ -819,10 +820,7 @@ gimp_image_map_data_written (GObject *operation,
const GeglRectangle *extent, const GeglRectangle *extent,
GimpImageMap *image_map) GimpImageMap *image_map)
{ {
GimpImage *image; GimpImage *image = gimp_item_get_image (GIMP_ITEM (image_map->drawable));
PixelRegion srcPR;
image = gimp_item_get_image (GIMP_ITEM (image_map->drawable));
if (! gimp_channel_is_empty (gimp_image_get_mask (image))) if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
{ {
@ -837,19 +835,15 @@ gimp_image_map_data_written (GObject *operation,
} }
/* Apply the result of the gegl graph. */ /* Apply the result of the gegl graph. */
pixel_region_init (&srcPR, gimp_drawable_apply_buffer (image_map->drawable,
gimp_drawable_get_shadow_tiles (image_map->drawable), gimp_drawable_get_shadow_buffer (image_map->drawable),
extent->x, GIMP_GEGL_RECT (extent->x, extent->y,
extent->y, extent->width, extent->height),
extent->width,
extent->height,
FALSE);
gimp_drawable_apply_region (image_map->drawable, &srcPR,
FALSE, NULL, FALSE, NULL,
GIMP_OPACITY_OPAQUE, GIMP_REPLACE_MODE, GIMP_OPACITY_OPAQUE, GIMP_REPLACE_MODE,
NULL, NULL, NULL, NULL,
extent->x, extent->y); extent->x, extent->y);
gimp_drawable_update (image_map->drawable, gimp_drawable_update (image_map->drawable,
extent->x, extent->y, extent->x, extent->y,
extent->width, extent->height); extent->width, extent->height);

View File

@ -476,7 +476,7 @@ drawable_merge_shadow_invoker (GimpProcedure *procedure,
if (gimp->plug_in_manager->current_plug_in) if (gimp->plug_in_manager->current_plug_in)
undo_desc = gimp_plug_in_get_undo_desc (gimp->plug_in_manager->current_plug_in); undo_desc = gimp_plug_in_get_undo_desc (gimp->plug_in_manager->current_plug_in);
gimp_drawable_merge_shadow_tiles (drawable, undo, undo_desc); gimp_drawable_merge_shadow_buffer (drawable, undo, undo_desc);
} }
else else
success = FALSE; success = FALSE;
@ -505,7 +505,7 @@ drawable_free_shadow_invoker (GimpProcedure *procedure,
gimp_plug_in_cleanup_remove_shadow (gimp->plug_in_manager->current_plug_in, gimp_plug_in_cleanup_remove_shadow (gimp->plug_in_manager->current_plug_in,
drawable); drawable);
gimp_drawable_free_shadow_tiles (drawable); gimp_drawable_free_shadow_buffer (drawable);
} }
return gimp_procedure_get_return_values (procedure, success, return gimp_procedure_get_return_values (procedure, success,

View File

@ -57,7 +57,7 @@ struct _GimpPlugInCleanupItem
GimpItem *item; GimpItem *item;
gint item_ID; gint item_ID;
gboolean shadow_tiles; gboolean shadow_buffer;
}; };
@ -157,7 +157,7 @@ gimp_plug_in_cleanup_add_shadow (GimpPlugIn *plug_in,
cleanup); cleanup);
} }
cleanup->shadow_tiles = TRUE; cleanup->shadow_buffer = TRUE;
return TRUE; return TRUE;
} }
@ -178,7 +178,7 @@ gimp_plug_in_cleanup_remove_shadow (GimpPlugIn *plug_in,
if (! cleanup) if (! cleanup)
return FALSE; return FALSE;
if (! cleanup->shadow_tiles) if (! cleanup->shadow_buffer)
return FALSE; return FALSE;
proc_frame->item_cleanups = g_list_remove (proc_frame->item_cleanups, proc_frame->item_cleanups = g_list_remove (proc_frame->item_cleanups,
@ -332,15 +332,15 @@ gimp_plug_in_cleanup_item (GimpPlugInProcFrame *proc_frame,
{ {
GimpItem *item = cleanup->item; GimpItem *item = cleanup->item;
if (cleanup->shadow_tiles) if (cleanup->shadow_buffer)
{ {
GimpProcedure *proc = proc_frame->procedure; GimpProcedure *proc = proc_frame->procedure;
GIMP_LOG (SHADOW_TILES, GIMP_LOG (SHADOW_TILES,
"Freeing shadow tiles of drawable '%s' on behalf of '%s'.", "Freeing shadow buffer of drawable '%s' on behalf of '%s'.",
gimp_object_get_name (item), gimp_object_get_name (item),
gimp_plug_in_procedure_get_label (GIMP_PLUG_IN_PROCEDURE (proc))); gimp_plug_in_procedure_get_label (GIMP_PLUG_IN_PROCEDURE (proc)));
gimp_drawable_free_shadow_tiles (GIMP_DRAWABLE (item)); gimp_drawable_free_shadow_buffer (GIMP_DRAWABLE (item));
} }
} }

View File

@ -32,6 +32,8 @@
#include "base/tile.h" #include "base/tile.h"
#include "base/tile-manager.h" #include "base/tile-manager.h"
#include "gegl/gimp-gegl-utils.h"
#include "core/gimp.h" #include "core/gimp.h"
#include "core/gimpdrawable.h" #include "core/gimpdrawable.h"
#include "core/gimpdrawable-shadow.h" #include "core/gimpdrawable-shadow.h"
@ -190,6 +192,7 @@ gimp_plug_in_handle_tile_put (GimpPlugIn *plug_in,
GPTileData *tile_info; GPTileData *tile_info;
GimpWireMessage msg; GimpWireMessage msg;
GimpDrawable *drawable; GimpDrawable *drawable;
GeglBuffer *buffer;
TileManager *tm; TileManager *tm;
Tile *tile; Tile *tile;
@ -257,12 +260,13 @@ gimp_plug_in_handle_tile_put (GimpPlugIn *plug_in,
if (tile_info->shadow) if (tile_info->shadow)
{ {
/* don't check whether the drawable is a group or locked here, /* don't check whether the drawable is a group or locked here,
* the plugin will get a proper error message when it tries to * the plugin will get a proper error message when it tries to
* merge the shadow tiles, which is much better than just * merge the shadow tiles, which is much better than just
* killing it. * killing it.
*/ */
tm = gimp_drawable_get_shadow_tiles (drawable); buffer = gimp_drawable_get_shadow_buffer (drawable);
gimp_plug_in_cleanup_add_shadow (plug_in, drawable); gimp_plug_in_cleanup_add_shadow (plug_in, drawable);
} }
@ -291,9 +295,11 @@ gimp_plug_in_handle_tile_put (GimpPlugIn *plug_in,
return; return;
} }
tm = gimp_drawable_get_tiles (drawable); buffer = gimp_drawable_get_buffer (drawable);
} }
tm = gimp_gegl_buffer_get_tiles (buffer);
tile = tile_manager_get (tm, tile_info->tile_num, TRUE, TRUE); tile = tile_manager_get (tm, tile_info->tile_num, TRUE, TRUE);
if (! tile) if (! tile)
@ -335,6 +341,7 @@ gimp_plug_in_handle_tile_get (GimpPlugIn *plug_in,
GPTileData tile_data; GPTileData tile_data;
GimpWireMessage msg; GimpWireMessage msg;
GimpDrawable *drawable; GimpDrawable *drawable;
GeglBuffer *buffer;
TileManager *tm; TileManager *tm;
Tile *tile; Tile *tile;
@ -367,15 +374,17 @@ gimp_plug_in_handle_tile_get (GimpPlugIn *plug_in,
if (request->shadow) if (request->shadow)
{ {
tm = gimp_drawable_get_shadow_tiles (drawable); buffer = gimp_drawable_get_shadow_buffer (drawable);
gimp_plug_in_cleanup_add_shadow (plug_in, drawable); gimp_plug_in_cleanup_add_shadow (plug_in, drawable);
} }
else else
{ {
tm = gimp_drawable_get_tiles (drawable); buffer = gimp_drawable_get_buffer (drawable);
} }
tm = gimp_gegl_buffer_get_tiles (buffer);
tile = tile_manager_get (tm, request->tile_num, TRUE, FALSE); tile = tile_manager_get (tm, request->tile_num, TRUE, FALSE);
if (! tile) if (! tile)

View File

@ -49,7 +49,7 @@ HELP
if (gimp->plug_in_manager->current_plug_in) if (gimp->plug_in_manager->current_plug_in)
undo_desc = gimp_plug_in_get_undo_desc (gimp->plug_in_manager->current_plug_in); undo_desc = gimp_plug_in_get_undo_desc (gimp->plug_in_manager->current_plug_in);
gimp_drawable_merge_shadow_tiles (drawable, undo, undo_desc); gimp_drawable_merge_shadow_buffer (drawable, undo, undo_desc);
} }
else else
success = FALSE; success = FALSE;
@ -83,7 +83,7 @@ HELP
gimp_plug_in_cleanup_remove_shadow (gimp->plug_in_manager->current_plug_in, gimp_plug_in_cleanup_remove_shadow (gimp->plug_in_manager->current_plug_in,
drawable); drawable);
gimp_drawable_free_shadow_tiles (drawable); gimp_drawable_free_shadow_buffer (drawable);
} }
CODE CODE
); );