mirror of https://github.com/GNOME/gimp.git
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!
This commit is contained in:
parent
14614cb349
commit
db2ea536da
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue