[gimp] app: add an optional gegl:cache at the output of GimpApplicator
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add an optional gegl:cache at the output of GimpApplicator
- Date: Wed, 18 Jun 2014 16:55:25 +0000 (UTC)
commit db2ea536daa835f3d561253499e2e82a8f4a4567
Author: Michael Natterer <mitch gimp org>
Date: Wed Jun 18 18:50:53 2014 +0200
app: add an optional gegl:cache at the output of GimpApplicator
Add "gboolean use_cache" to gimp_applicator_new(). Don't use a cache
anywhere but in GimpImageMap because it incrementally fills that cache
via the projection update. In gimp_drawable_merge_filter(), get that
cache and pass it to gimp_gegl_apply_cached_operation() which then
avoids doing the work twice for the already cached results. Win!
app/core/gimpdrawable-combine.c | 3 +-
app/core/gimpdrawable-filter.c | 33 ++++++++++++++++---
app/core/gimpdrawable.c | 2 +-
app/core/gimpimage-merge.c | 3 +-
app/core/gimpimagemap.c | 3 +-
app/gegl/gimpapplicator.c | 66 +++++++++++++++++++++++++++++++++------
app/gegl/gimpapplicator.h | 8 ++++-
app/paint/gimppaintcore.c | 2 +-
8 files changed, 99 insertions(+), 21 deletions(-)
---
diff --git a/app/core/gimpdrawable-combine.c b/app/core/gimpdrawable-combine.c
index 6f37c2d..cd80dad 100644
--- a/app/core/gimpdrawable-combine.c
+++ b/app/core/gimpdrawable-combine.c
@@ -118,7 +118,8 @@ gimp_drawable_real_apply_buffer (GimpDrawable *drawable,
}
}
- applicator = gimp_applicator_new (NULL, gimp_drawable_get_linear (drawable));
+ applicator = gimp_applicator_new (NULL, gimp_drawable_get_linear (drawable),
+ FALSE);
if (mask)
{
diff --git a/app/core/gimpdrawable-filter.c b/app/core/gimpdrawable-filter.c
index 284a692..82a091e 100644
--- a/app/core/gimpdrawable-filter.c
+++ b/app/core/gimpdrawable-filter.c
@@ -97,6 +97,9 @@ gimp_drawable_merge_filter (GimpDrawable *drawable,
&rect.width, &rect.height))
{
GimpApplicator *applicator;
+ GeglBuffer *cache = NULL;
+ GeglRectangle *rects = NULL;
+ gint n_rects = 0;
gimp_drawable_push_undo (drawable, undo_desc, NULL,
rect.x, rect.y,
@@ -119,13 +122,33 @@ gimp_drawable_merge_filter (GimpDrawable *drawable,
undo->applied_buffer =
gimp_applicator_dup_apply_buffer (applicator, &rect);
}
+
+ cache = gimp_applicator_get_cache_buffer (applicator,
+ &rects, &n_rects);
+
+ if (cache)
+ {
+ gint i;
+
+ for (i = 0; i < n_rects; i++)
+ g_printerr ("valid: %d %d %d %d\n",
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height);
+ }
}
- gimp_gegl_apply_operation (gimp_drawable_get_buffer (drawable),
- progress, undo_desc,
- gimp_filter_get_node (filter),
- gimp_drawable_get_buffer (drawable),
- &rect);
+ gimp_gegl_apply_cached_operation (gimp_drawable_get_buffer (drawable),
+ progress, undo_desc,
+ gimp_filter_get_node (filter),
+ gimp_drawable_get_buffer (drawable),
+ &rect,
+ cache, rects, n_rects);
+
+ if (cache)
+ {
+ g_object_unref (cache);
+ g_free (rects);
+ }
gimp_drawable_update (drawable,
rect.x, rect.y,
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index b4636ef..110756a 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -957,7 +957,7 @@ gimp_drawable_sync_fs_filter (GimpDrawable *drawable,
gegl_node_add_child (node, fs_source);
- private->fs_applicator = gimp_applicator_new (node, linear);
+ private->fs_applicator = gimp_applicator_new (node, linear, FALSE);
private->fs_crop_node =
gegl_node_new_child (node,
diff --git a/app/core/gimpimage-merge.c b/app/core/gimpimage-merge.c
index 7892ead..aec9c75 100644
--- a/app/core/gimpimage-merge.c
+++ b/app/core/gimpimage-merge.c
@@ -614,7 +614,8 @@ gimp_image_merge_layers (GimpImage *image,
applicator =
gimp_applicator_new (NULL,
- gimp_drawable_get_linear (GIMP_DRAWABLE (layer)));
+ gimp_drawable_get_linear (GIMP_DRAWABLE (layer)),
+ FALSE);
if (gimp_layer_get_mask (layer) &&
gimp_layer_get_apply_mask (layer))
diff --git a/app/core/gimpimagemap.c b/app/core/gimpimagemap.c
index 1cea9a2..73439b0 100644
--- a/app/core/gimpimagemap.c
+++ b/app/core/gimpimagemap.c
@@ -288,7 +288,8 @@ gimp_image_map_apply (GimpImageMap *image_map,
image_map->applicator =
gimp_applicator_new (filter_node,
- gimp_drawable_get_linear (image_map->drawable));
+ gimp_drawable_get_linear (image_map->drawable),
+ TRUE);
gimp_filter_set_applicator (image_map->filter,
image_map->applicator);
diff --git a/app/gegl/gimpapplicator.c b/app/gegl/gimpapplicator.c
index fc85be8..b8dd90b 100644
--- a/app/gegl/gimpapplicator.c
+++ b/app/gegl/gimpapplicator.c
@@ -106,7 +106,8 @@ gimp_applicator_get_property (GObject *object,
GimpApplicator *
gimp_applicator_new (GeglNode *parent,
- gboolean linear)
+ gboolean linear,
+ gboolean use_cache)
{
GimpApplicator *applicator;
@@ -148,16 +149,15 @@ gimp_applicator_new (GeglNode *parent,
"operation", "gegl:translate",
NULL);
- gegl_node_connect_to (applicator->aux_node, "output",
- applicator->apply_offset_node, "input");
-
applicator->dup_apply_buffer_node =
gegl_node_new_child (applicator->node,
"operation", "gegl:copy-buffer",
NULL);
- gegl_node_connect_to (applicator->apply_offset_node, "output",
- applicator->dup_apply_buffer_node, "input");
+ gegl_node_link_many (applicator->aux_node,
+ applicator->apply_offset_node,
+ applicator->dup_apply_buffer_node,
+ NULL);
gegl_node_connect_to (applicator->dup_apply_buffer_node, "output",
applicator->mode_node, "aux");
@@ -181,12 +181,29 @@ gimp_applicator_new (GeglNode *parent,
"mask", applicator->affect,
NULL);
- gegl_node_connect_to (applicator->input_node, "output",
- applicator->affect_node, "input");
+ if (use_cache)
+ {
+ applicator->cache_node =
+ gegl_node_new_child (applicator->node,
+ "operation", "gegl:cache",
+ NULL);
+
+ gegl_node_link_many (applicator->input_node,
+ applicator->affect_node,
+ applicator->cache_node,
+ applicator->output_node,
+ NULL);
+ }
+ else
+ {
+ gegl_node_link_many (applicator->input_node,
+ applicator->affect_node,
+ applicator->output_node,
+ NULL);
+ }
+
gegl_node_connect_to (applicator->mode_node, "output",
applicator->affect_node, "aux");
- gegl_node_connect_to (applicator->affect_node, "output",
- applicator->output_node, "input");
return applicator;
}
@@ -450,3 +467,32 @@ gimp_applicator_dup_apply_buffer (GimpApplicator *applicator,
return buffer;
}
+
+gboolean gegl_buffer_list_valid_rectangles (GeglBuffer *buffer,
+ GeglRectangle **rectangles,
+ gint *n_rectangles);
+
+GeglBuffer *
+gimp_applicator_get_cache_buffer (GimpApplicator *applicator,
+ GeglRectangle **rectangles,
+ gint *n_rectangles)
+{
+ if (applicator->cache_node)
+ {
+ GeglBuffer *cache;
+
+ gegl_node_get (applicator->cache_node,
+ "cache", &cache,
+ NULL);
+
+ if (cache)
+ {
+ if (gegl_buffer_list_valid_rectangles (cache, rectangles, n_rectangles))
+ return cache;
+
+ g_object_unref (cache);
+ }
+ }
+
+ return NULL;
+}
diff --git a/app/gegl/gimpapplicator.h b/app/gegl/gimpapplicator.h
index f434bc8..9ba5e70 100644
--- a/app/gegl/gimpapplicator.h
+++ b/app/gegl/gimpapplicator.h
@@ -58,6 +58,8 @@ struct _GimpApplicator
GimpComponentMask affect;
GeglNode *affect_node;
+ GeglNode *cache_node;
+
GeglBuffer *src_buffer;
GeglNode *src_node;
@@ -81,7 +83,8 @@ struct _GimpApplicatorClass
GType gimp_applicator_get_type (void) G_GNUC_CONST;
GimpApplicator * gimp_applicator_new (GeglNode *parent,
- gboolean linear);
+ gboolean linear,
+ gboolean use_cache);
void gimp_applicator_set_src_buffer (GimpApplicator *applicator,
GeglBuffer *dest_buffer);
@@ -111,6 +114,9 @@ void gimp_applicator_blit (GimpApplicator *applicator,
GeglBuffer * gimp_applicator_dup_apply_buffer (GimpApplicator *applicator,
const GeglRectangle *rect);
+GeglBuffer * gimp_applicator_get_cache_buffer (GimpApplicator *applicator,
+ GeglRectangle **rectangles,
+ gint *n_rectangles);
#endif /* __GIMP_APPLICATOR_H__ */
diff --git a/app/paint/gimppaintcore.c b/app/paint/gimppaintcore.c
index 117cbf1..87e1258 100644
--- a/app/paint/gimppaintcore.c
+++ b/app/paint/gimppaintcore.c
@@ -429,7 +429,7 @@ gimp_paint_core_start (GimpPaintCore *core,
if (paint_options->use_applicator)
{
- core->applicator = gimp_applicator_new (NULL, core->linear_mode);
+ core->applicator = gimp_applicator_new (NULL, core->linear_mode, FALSE);
if (core->mask_buffer)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]