mirror of https://github.com/GNOME/gimp.git
app: in GimpApplicator, allow enabling cache/preview after construction; remove preview cache
Remove the use_split_preview and use_result_cache parameters of gimp_applicator_new(), and allow enabling/disabling the cache (through gimp_applicator_set_cache()) and the preview crop (through gimp_applicator_set_preview()) after construction. Move the preview crop node after the result cache, and remove the separate preview cache node. This eliminates an extra cache buffer, reducing the space consumed by filters, and speeds up split preview, since the cached result now includes the output compositing.
This commit is contained in:
parent
42dd3fd939
commit
ab52dc6bca
|
@ -104,7 +104,7 @@ gimp_drawable_real_apply_buffer (GimpDrawable *drawable,
|
||||||
NULL, x, y, width, height);
|
NULL, x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
applicator = gimp_applicator_new (NULL, FALSE, FALSE);
|
applicator = gimp_applicator_new (NULL);
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
{
|
{
|
||||||
|
|
|
@ -150,10 +150,7 @@ gimp_drawable_merge_filter (GimpDrawable *drawable,
|
||||||
|
|
||||||
if (applicator)
|
if (applicator)
|
||||||
{
|
{
|
||||||
/* disable the preview crop, this will force-process the
|
/* disable the preview crop */
|
||||||
* cached result from the preview cache into the result
|
|
||||||
* cache, involving only the layer and affect nodes
|
|
||||||
*/
|
|
||||||
gimp_applicator_set_preview (applicator, FALSE,
|
gimp_applicator_set_preview (applicator, FALSE,
|
||||||
GEGL_RECTANGLE (0, 0, 0, 0));
|
GEGL_RECTANGLE (0, 0, 0, 0));
|
||||||
|
|
||||||
|
|
|
@ -208,10 +208,12 @@ _gimp_drawable_add_floating_sel_filter (GimpDrawable *drawable)
|
||||||
|
|
||||||
gegl_node_add_child (node, fs_source);
|
gegl_node_add_child (node, fs_source);
|
||||||
|
|
||||||
private->fs_applicator = gimp_applicator_new (node, FALSE, TRUE);
|
private->fs_applicator = gimp_applicator_new (node);
|
||||||
|
|
||||||
gimp_filter_set_applicator (private->fs_filter, private->fs_applicator);
|
gimp_filter_set_applicator (private->fs_filter, private->fs_applicator);
|
||||||
|
|
||||||
|
gimp_applicator_set_cache (private->fs_applicator, TRUE);
|
||||||
|
|
||||||
private->fs_crop_node =
|
private->fs_crop_node =
|
||||||
gegl_node_new_child (node,
|
gegl_node_new_child (node,
|
||||||
"operation", "gegl:crop",
|
"operation", "gegl:crop",
|
||||||
|
|
|
@ -212,10 +212,12 @@ gimp_drawable_filter_new (GimpDrawable *drawable,
|
||||||
|
|
||||||
gegl_node_add_child (node, operation);
|
gegl_node_add_child (node, operation);
|
||||||
|
|
||||||
filter->applicator = gimp_applicator_new (node, TRUE, TRUE);
|
filter->applicator = gimp_applicator_new (node);
|
||||||
|
|
||||||
gimp_filter_set_applicator (GIMP_FILTER (filter), filter->applicator);
|
gimp_filter_set_applicator (GIMP_FILTER (filter), filter->applicator);
|
||||||
|
|
||||||
|
gimp_applicator_set_cache (filter->applicator, TRUE);
|
||||||
|
|
||||||
filter->has_input = gegl_node_has_pad (filter->operation, "input");
|
filter->has_input = gegl_node_has_pad (filter->operation, "input");
|
||||||
|
|
||||||
if (filter->has_input)
|
if (filter->has_input)
|
||||||
|
|
|
@ -104,9 +104,7 @@ gimp_applicator_get_property (GObject *object,
|
||||||
}
|
}
|
||||||
|
|
||||||
GimpApplicator *
|
GimpApplicator *
|
||||||
gimp_applicator_new (GeglNode *parent,
|
gimp_applicator_new (GeglNode *parent)
|
||||||
gboolean use_split_preview,
|
|
||||||
gboolean use_result_cache)
|
|
||||||
{
|
{
|
||||||
GimpApplicator *applicator;
|
GimpApplicator *applicator;
|
||||||
|
|
||||||
|
@ -152,30 +150,8 @@ gimp_applicator_new (GeglNode *parent,
|
||||||
applicator->apply_offset_node,
|
applicator->apply_offset_node,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (use_split_preview)
|
|
||||||
{
|
|
||||||
applicator->preview_cache_node =
|
|
||||||
gegl_node_new_child (applicator->node,
|
|
||||||
"operation", "gegl:cache",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
applicator->preview_crop_node =
|
|
||||||
gegl_node_new_child (applicator->node,
|
|
||||||
"operation", "gegl:nop",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
gegl_node_link_many (applicator->apply_offset_node,
|
|
||||||
applicator->preview_cache_node,
|
|
||||||
applicator->preview_crop_node,
|
|
||||||
NULL);
|
|
||||||
gegl_node_connect_to (applicator->preview_crop_node, "output",
|
|
||||||
applicator->mode_node, "aux");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gegl_node_connect_to (applicator->apply_offset_node, "output",
|
gegl_node_connect_to (applicator->apply_offset_node, "output",
|
||||||
applicator->mode_node, "aux");
|
applicator->mode_node, "aux");
|
||||||
}
|
|
||||||
|
|
||||||
applicator->mask_node =
|
applicator->mask_node =
|
||||||
gegl_node_new_child (applicator->node,
|
gegl_node_new_child (applicator->node,
|
||||||
|
@ -197,33 +173,28 @@ gimp_applicator_new (GeglNode *parent,
|
||||||
"mask", applicator->affect,
|
"mask", applicator->affect,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
applicator->output_convert_format_node =
|
applicator->convert_format_node =
|
||||||
gegl_node_new_child (applicator->node,
|
gegl_node_new_child (applicator->node,
|
||||||
"operation", "gegl:nop",
|
"operation", "gegl:nop",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (use_result_cache)
|
applicator->cache_node =
|
||||||
{
|
|
||||||
applicator->output_cache_node =
|
|
||||||
gegl_node_new_child (applicator->node,
|
gegl_node_new_child (applicator->node,
|
||||||
"operation", "gegl:cache",
|
"operation", "gegl:nop",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
applicator->preview_crop_node =
|
||||||
|
gegl_node_new_child (applicator->node,
|
||||||
|
"operation", "gegl:nop",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
gegl_node_link_many (applicator->input_node,
|
gegl_node_link_many (applicator->input_node,
|
||||||
applicator->affect_node,
|
applicator->affect_node,
|
||||||
applicator->output_convert_format_node,
|
applicator->convert_format_node,
|
||||||
applicator->output_cache_node,
|
applicator->cache_node,
|
||||||
|
applicator->preview_crop_node,
|
||||||
applicator->output_node,
|
applicator->output_node,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gegl_node_link_many (applicator->input_node,
|
|
||||||
applicator->affect_node,
|
|
||||||
applicator->output_convert_format_node,
|
|
||||||
applicator->output_node,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
gegl_node_connect_to (applicator->mode_node, "output",
|
gegl_node_connect_to (applicator->mode_node, "output",
|
||||||
applicator->affect_node, "aux");
|
applicator->affect_node, "aux");
|
||||||
|
@ -496,21 +467,55 @@ gimp_applicator_set_output_format (GimpApplicator *applicator,
|
||||||
|
|
||||||
if (applicator->output_format != format)
|
if (applicator->output_format != format)
|
||||||
{
|
{
|
||||||
applicator->output_format = format;
|
|
||||||
|
|
||||||
if (format)
|
if (format)
|
||||||
{
|
{
|
||||||
gegl_node_set (applicator->output_convert_format_node,
|
if (! applicator->output_format)
|
||||||
|
{
|
||||||
|
gegl_node_set (applicator->convert_format_node,
|
||||||
"operation", "gegl:convert-format",
|
"operation", "gegl:convert-format",
|
||||||
"format", format,
|
"format", format,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gegl_node_set (applicator->output_convert_format_node,
|
gegl_node_set (applicator->convert_format_node,
|
||||||
|
"format", format,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gegl_node_set (applicator->convert_format_node,
|
||||||
"operation", "gegl:nop",
|
"operation", "gegl:nop",
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applicator->output_format = format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gimp_applicator_set_cache (GimpApplicator *applicator,
|
||||||
|
gboolean enable)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GIMP_IS_APPLICATOR (applicator));
|
||||||
|
|
||||||
|
if (applicator->cache_enabled != enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
gegl_node_set (applicator->cache_node,
|
||||||
|
"operation", "gegl:cache",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gegl_node_set (applicator->cache_node,
|
||||||
|
"operation", "gegl:nop",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
applicator->cache_enabled = enable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,6 +523,38 @@ gboolean gegl_buffer_list_valid_rectangles (GeglBuffer *buffer,
|
||||||
GeglRectangle **rectangles,
|
GeglRectangle **rectangles,
|
||||||
gint *n_rectangles);
|
gint *n_rectangles);
|
||||||
|
|
||||||
|
GeglBuffer *
|
||||||
|
gimp_applicator_get_cache_buffer (GimpApplicator *applicator,
|
||||||
|
GeglRectangle **rectangles,
|
||||||
|
gint *n_rectangles)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GIMP_IS_APPLICATOR (applicator), NULL);
|
||||||
|
g_return_val_if_fail (rectangles != NULL, NULL);
|
||||||
|
g_return_val_if_fail (n_rectangles != NULL, NULL);
|
||||||
|
|
||||||
|
if (applicator->cache_enabled)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gimp_applicator_set_preview (GimpApplicator *applicator,
|
gimp_applicator_set_preview (GimpApplicator *applicator,
|
||||||
gboolean enable,
|
gboolean enable,
|
||||||
|
@ -526,9 +563,6 @@ gimp_applicator_set_preview (GimpApplicator *applicator,
|
||||||
g_return_if_fail (GIMP_IS_APPLICATOR (applicator));
|
g_return_if_fail (GIMP_IS_APPLICATOR (applicator));
|
||||||
g_return_if_fail (rect != NULL);
|
g_return_if_fail (rect != NULL);
|
||||||
|
|
||||||
if (! applicator->preview_cache_node)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (applicator->preview_enabled != enable ||
|
if (applicator->preview_enabled != enable ||
|
||||||
applicator->preview_rect.x != rect->x ||
|
applicator->preview_rect.x != rect->x ||
|
||||||
applicator->preview_rect.y != rect->y ||
|
applicator->preview_rect.y != rect->y ||
|
||||||
|
@ -562,41 +596,10 @@ gimp_applicator_set_preview (GimpApplicator *applicator,
|
||||||
}
|
}
|
||||||
else if (applicator->preview_enabled)
|
else if (applicator->preview_enabled)
|
||||||
{
|
{
|
||||||
GeglBuffer *cache;
|
|
||||||
|
|
||||||
gegl_node_disconnect (applicator->preview_crop_node, "aux");
|
gegl_node_disconnect (applicator->preview_crop_node, "aux");
|
||||||
gegl_node_set (applicator->preview_crop_node,
|
gegl_node_set (applicator->preview_crop_node,
|
||||||
"operation", "gegl:nop",
|
"operation", "gegl:nop",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* when disabling the preview, preserve the cached result
|
|
||||||
* by processing it into the output cache, which only
|
|
||||||
* involves the mode and affect nodes.
|
|
||||||
*/
|
|
||||||
gegl_node_get (applicator->preview_cache_node,
|
|
||||||
"cache", &cache,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (cache)
|
|
||||||
{
|
|
||||||
GeglRectangle *rectangles;
|
|
||||||
gint n_rectangles;
|
|
||||||
|
|
||||||
if (gegl_buffer_list_valid_rectangles (cache, &rectangles,
|
|
||||||
&n_rectangles))
|
|
||||||
{
|
|
||||||
gint i;
|
|
||||||
|
|
||||||
for (i = 0; i < n_rectangles; i++)
|
|
||||||
gegl_node_blit (applicator->output_cache_node, 1.0,
|
|
||||||
&rectangles[i],
|
|
||||||
NULL, NULL, 0, GEGL_BLIT_DEFAULT);
|
|
||||||
|
|
||||||
g_free (rectangles);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (cache);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
applicator->preview_enabled = enable;
|
applicator->preview_enabled = enable;
|
||||||
|
@ -613,32 +616,3 @@ gimp_applicator_blit (GimpApplicator *applicator,
|
||||||
gegl_node_blit (applicator->dest_node, 1.0, rect,
|
gegl_node_blit (applicator->dest_node, 1.0, rect,
|
||||||
NULL, NULL, 0, GEGL_BLIT_DEFAULT);
|
NULL, NULL, 0, GEGL_BLIT_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
GeglBuffer *
|
|
||||||
gimp_applicator_get_cache_buffer (GimpApplicator *applicator,
|
|
||||||
GeglRectangle **rectangles,
|
|
||||||
gint *n_rectangles)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (GIMP_IS_APPLICATOR (applicator), NULL);
|
|
||||||
g_return_val_if_fail (rectangles != NULL, NULL);
|
|
||||||
g_return_val_if_fail (n_rectangles != NULL, NULL);
|
|
||||||
|
|
||||||
if (applicator->output_cache_node)
|
|
||||||
{
|
|
||||||
GeglBuffer *cache;
|
|
||||||
|
|
||||||
gegl_node_get (applicator->output_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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -48,11 +48,6 @@ struct _GimpApplicator
|
||||||
gint apply_offset_y;
|
gint apply_offset_y;
|
||||||
GeglNode *apply_offset_node;
|
GeglNode *apply_offset_node;
|
||||||
|
|
||||||
gboolean preview_enabled;
|
|
||||||
GeglRectangle preview_rect;
|
|
||||||
GeglNode *preview_cache_node;
|
|
||||||
GeglNode *preview_crop_node;
|
|
||||||
|
|
||||||
gdouble opacity;
|
gdouble opacity;
|
||||||
GimpLayerMode paint_mode;
|
GimpLayerMode paint_mode;
|
||||||
GimpLayerColorSpace blend_space;
|
GimpLayerColorSpace blend_space;
|
||||||
|
@ -64,9 +59,14 @@ struct _GimpApplicator
|
||||||
GeglNode *affect_node;
|
GeglNode *affect_node;
|
||||||
|
|
||||||
const Babl *output_format;
|
const Babl *output_format;
|
||||||
GeglNode *output_convert_format_node;
|
GeglNode *convert_format_node;
|
||||||
|
|
||||||
GeglNode *output_cache_node;
|
gboolean cache_enabled;
|
||||||
|
GeglNode *cache_node;
|
||||||
|
|
||||||
|
gboolean preview_enabled;
|
||||||
|
GeglRectangle preview_rect;
|
||||||
|
GeglNode *preview_crop_node;
|
||||||
|
|
||||||
GeglBuffer *src_buffer;
|
GeglBuffer *src_buffer;
|
||||||
GeglNode *src_node;
|
GeglNode *src_node;
|
||||||
|
@ -90,9 +90,7 @@ struct _GimpApplicatorClass
|
||||||
|
|
||||||
GType gimp_applicator_get_type (void) G_GNUC_CONST;
|
GType gimp_applicator_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
GimpApplicator * gimp_applicator_new (GeglNode *parent,
|
GimpApplicator * gimp_applicator_new (GeglNode *parent);
|
||||||
gboolean use_split_preview,
|
|
||||||
gboolean use_result_cache);
|
|
||||||
|
|
||||||
void gimp_applicator_set_src_buffer (GimpApplicator *applicator,
|
void gimp_applicator_set_src_buffer (GimpApplicator *applicator,
|
||||||
GeglBuffer *dest_buffer);
|
GeglBuffer *dest_buffer);
|
||||||
|
@ -124,6 +122,12 @@ void gimp_applicator_set_affect (GimpApplicator *applicator
|
||||||
void gimp_applicator_set_output_format (GimpApplicator *applicator,
|
void gimp_applicator_set_output_format (GimpApplicator *applicator,
|
||||||
const Babl *format);
|
const Babl *format);
|
||||||
|
|
||||||
|
void gimp_applicator_set_cache (GimpApplicator *applicator,
|
||||||
|
gboolean enable);
|
||||||
|
GeglBuffer * gimp_applicator_get_cache_buffer (GimpApplicator *applicator,
|
||||||
|
GeglRectangle **rectangles,
|
||||||
|
gint *n_rectangles);
|
||||||
|
|
||||||
void gimp_applicator_set_preview (GimpApplicator *applicator,
|
void gimp_applicator_set_preview (GimpApplicator *applicator,
|
||||||
gboolean enable,
|
gboolean enable,
|
||||||
const GeglRectangle *rect);
|
const GeglRectangle *rect);
|
||||||
|
@ -131,9 +135,5 @@ void gimp_applicator_set_preview (GimpApplicator *applicator
|
||||||
void gimp_applicator_blit (GimpApplicator *applicator,
|
void gimp_applicator_blit (GimpApplicator *applicator,
|
||||||
const GeglRectangle *rect);
|
const GeglRectangle *rect);
|
||||||
|
|
||||||
GeglBuffer * gimp_applicator_get_cache_buffer (GimpApplicator *applicator,
|
|
||||||
GeglRectangle **rectangles,
|
|
||||||
gint *n_rectangles);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GIMP_APPLICATOR_H__ */
|
#endif /* __GIMP_APPLICATOR_H__ */
|
||||||
|
|
|
@ -445,7 +445,7 @@ gimp_paint_core_start (GimpPaintCore *core,
|
||||||
|
|
||||||
if (paint_options->use_applicator)
|
if (paint_options->use_applicator)
|
||||||
{
|
{
|
||||||
core->applicator = gimp_applicator_new (NULL, FALSE, FALSE);
|
core->applicator = gimp_applicator_new (NULL);
|
||||||
|
|
||||||
if (core->mask_buffer)
|
if (core->mask_buffer)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue