[gimp] app: merge layers in chunks, and show progress
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: merge layers in chunks, and show progress
- Date: Mon, 25 Feb 2019 10:11:43 +0000 (UTC)
commit e83d8ac4f2dc0260e97a91938ae3e34608efdbf9
Author: Ell <ell_se yahoo com>
Date: Mon Feb 25 04:49:04 2019 -0500
app: merge layers in chunks, and show progress
In gimp_image_merge_layers() -- the internal function used by the
various layer-merging/flattenning functions -- process the merged-
layer graph in chunks, using gimp_gegl_apply_operation(), instead
of in one go, using gegl_node_blit_buffer(). Processing in chunks
better utilizes the cache, since it reduces the size of
intermediate buffers, reducing the chances of hitting the swap when
merging large images (see, for example, issue #3012.)
Additionally, this allows us to show progress indication. Have the
relevant gimpimage-merge functions take a GimpProgress, and pass it
down to gimp_image_merge_layers(). Adapt all callers.
app/actions/image-commands.c | 33 +++++++++++-------
app/actions/layers-commands.c | 9 +++--
app/core/gimpimage-merge.c | 62 ++++++++++++++++++++++-----------
app/core/gimpimage-merge.h | 5 ++-
app/dialogs/image-merge-layers-dialog.c | 3 +-
app/dialogs/image-merge-layers-dialog.h | 3 +-
app/file/file-open.c | 3 +-
app/pdb/image-cmds.c | 8 +++--
pdb/groups/image.pdb | 8 +++--
9 files changed, 89 insertions(+), 45 deletions(-)
---
diff --git a/app/actions/image-commands.c b/app/actions/image-commands.c
index a2a108de2f..75544be59c 100644
--- a/app/actions/image-commands.c
+++ b/app/actions/image-commands.c
@@ -166,7 +166,8 @@ static void image_merge_layers_callback (GtkWidget *dialog,
GimpContext *context,
GimpMergeType merge_type,
gboolean merge_active_group,
- gboolean discard_invisible);
+ gboolean discard_invisible,
+ gpointer user_data);
/* private variables */
@@ -898,10 +899,12 @@ void
image_merge_layers_cmd_callback (GtkAction *action,
gpointer data)
{
- GtkWidget *dialog;
- GimpImage *image;
- GtkWidget *widget;
+ GtkWidget *dialog;
+ GimpImage *image;
+ GimpDisplay *display;
+ GtkWidget *widget;
return_if_no_image (image, data);
+ return_if_no_display (display, data);
return_if_no_widget (widget, data);
#define MERGE_LAYERS_DIALOG_KEY "gimp-merge-layers-dialog"
@@ -919,7 +922,7 @@ image_merge_layers_cmd_callback (GtkAction *action,
config->layer_merge_active_group_only,
config->layer_merge_discard_invisible,
image_merge_layers_callback,
- NULL);
+ display);
dialogs_attach_dialog (G_OBJECT (image), MERGE_LAYERS_DIALOG_KEY, dialog);
}
@@ -931,13 +934,16 @@ void
image_flatten_image_cmd_callback (GtkAction *action,
gpointer data)
{
- GimpImage *image;
- GtkWidget *widget;
- GError *error = NULL;
+ GimpImage *image;
+ GimpDisplay *display;
+ GtkWidget *widget;
+ GError *error = NULL;
return_if_no_image (image, data);
+ return_if_no_display (display, data);
return_if_no_widget (widget, data);
- if (! gimp_image_flatten (image, action_data_get_context (data), &error))
+ if (! gimp_image_flatten (image, action_data_get_context (data),
+ GIMP_PROGRESS (display), &error))
{
gimp_message_literal (image->gimp,
G_OBJECT (widget), GIMP_MESSAGE_WARNING,
@@ -1458,9 +1464,11 @@ image_merge_layers_callback (GtkWidget *dialog,
GimpContext *context,
GimpMergeType merge_type,
gboolean merge_active_group,
- gboolean discard_invisible)
+ gboolean discard_invisible,
+ gpointer user_data)
{
- GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config);
+ GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config);
+ GimpDisplay *display = user_data;
g_object_set (config,
"layer-merge-type", merge_type,
@@ -1472,7 +1480,8 @@ image_merge_layers_callback (GtkWidget *dialog,
context,
config->layer_merge_type,
config->layer_merge_active_group_only,
- config->layer_merge_discard_invisible);
+ config->layer_merge_discard_invisible,
+ GIMP_PROGRESS (display));
gimp_image_flush (image);
diff --git a/app/actions/layers-commands.c b/app/actions/layers-commands.c
index 4d15d0294b..289a0f0228 100644
--- a/app/actions/layers-commands.c
+++ b/app/actions/layers-commands.c
@@ -577,12 +577,15 @@ void
layers_merge_down_cmd_callback (GtkAction *action,
gpointer data)
{
- GimpImage *image;
- GimpLayer *layer;
+ GimpImage *image;
+ GimpLayer *layer;
+ GimpDisplay *display;
return_if_no_layer (image, layer, data);
+ return_if_no_display (display, data);
gimp_image_merge_down (image, layer, action_data_get_context (data),
- GIMP_EXPAND_AS_NECESSARY, NULL);
+ GIMP_EXPAND_AS_NECESSARY,
+ GIMP_PROGRESS (display), NULL);
gimp_image_flush (image);
}
diff --git a/app/core/gimpimage-merge.c b/app/core/gimpimage-merge.c
index f118a8d4e9..b8dc8cc11b 100644
--- a/app/core/gimpimage-merge.c
+++ b/app/core/gimpimage-merge.c
@@ -48,6 +48,7 @@
#include "gimpmarshal.h"
#include "gimpparasitelist.h"
#include "gimppickable.h"
+#include "gimpprogress.h"
#include "gimpprojectable.h"
#include "gimpundostack.h"
@@ -58,7 +59,9 @@ static GimpLayer * gimp_image_merge_layers (GimpImage *image,
GimpContainer *container,
GSList *merge_list,
GimpContext *context,
- GimpMergeType merge_type);
+ GimpMergeType merge_type,
+ const gchar *undo_desc,
+ GimpProgress *progress);
/* public functions */
@@ -68,7 +71,8 @@ gimp_image_merge_visible_layers (GimpImage *image,
GimpContext *context,
GimpMergeType merge_type,
gboolean merge_active_group,
- gboolean discard_invisible)
+ gboolean discard_invisible,
+ GimpProgress *progress)
{
GimpContainer *container;
GList *list;
@@ -77,6 +81,7 @@ gimp_image_merge_visible_layers (GimpImage *image,
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
+ g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
if (merge_active_group)
{
@@ -126,13 +131,14 @@ gimp_image_merge_visible_layers (GimpImage *image,
if (merge_list)
{
- GimpLayer *layer;
+ GimpLayer *layer;
+ const gchar *undo_desc = C_("undo-type", "Merge Visible Layers");
gimp_set_busy (image->gimp);
gimp_image_undo_group_start (image,
GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE,
- C_("undo-type", "Merge Visible Layers"));
+ undo_desc);
/* if there's a floating selection, anchor it */
if (gimp_image_get_floating_selection (image))
@@ -140,7 +146,8 @@ gimp_image_merge_visible_layers (GimpImage *image,
layer = gimp_image_merge_layers (image,
container,
- merge_list, context, merge_type);
+ merge_list, context, merge_type,
+ undo_desc, progress);
g_slist_free (merge_list);
if (invisible_list)
@@ -164,9 +171,10 @@ gimp_image_merge_visible_layers (GimpImage *image,
}
GimpLayer *
-gimp_image_flatten (GimpImage *image,
- GimpContext *context,
- GError **error)
+gimp_image_flatten (GimpImage *image,
+ GimpContext *context,
+ GimpProgress *progress,
+ GError **error)
{
GList *list;
GSList *merge_list = NULL;
@@ -174,6 +182,7 @@ gimp_image_flatten (GimpImage *image,
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
+ g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
for (list = gimp_image_get_layer_iter (image);
@@ -191,11 +200,13 @@ gimp_image_flatten (GimpImage *image,
if (merge_list)
{
+ const gchar *undo_desc = C_("undo-type", "Flatten Image");
+
gimp_set_busy (image->gimp);
gimp_image_undo_group_start (image,
GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE,
- C_("undo-type", "Flatten Image"));
+ undo_desc);
/* if there's a floating selection, anchor it */
if (gimp_image_get_floating_selection (image))
@@ -204,7 +215,8 @@ gimp_image_flatten (GimpImage *image,
layer = gimp_image_merge_layers (image,
gimp_image_get_layers (image),
merge_list, context,
- GIMP_FLATTEN_IMAGE);
+ GIMP_FLATTEN_IMAGE,
+ undo_desc, progress);
g_slist_free (merge_list);
gimp_image_alpha_changed (image);
@@ -226,17 +238,20 @@ gimp_image_merge_down (GimpImage *image,
GimpLayer *current_layer,
GimpContext *context,
GimpMergeType merge_type,
+ GimpProgress *progress,
GError **error)
{
- GimpLayer *layer;
- GList *list;
- GList *layer_list = NULL;
- GSList *merge_list = NULL;
+ GimpLayer *layer;
+ GList *list;
+ GList *layer_list = NULL;
+ GSList *merge_list = NULL;
+ const gchar *undo_desc;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_LAYER (current_layer), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (current_layer)), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
+ g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
if (gimp_layer_is_floating_sel (current_layer))
@@ -299,15 +314,18 @@ gimp_image_merge_down (GimpImage *image,
merge_list = g_slist_prepend (merge_list, current_layer);
+ undo_desc = C_("undo-type", "Merge Down");
+
gimp_set_busy (image->gimp);
gimp_image_undo_group_start (image,
GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE,
- C_("undo-type", "Merge Down"));
+ undo_desc);
layer = gimp_image_merge_layers (image,
gimp_item_get_container (GIMP_ITEM (current_layer)),
- merge_list, context, merge_type);
+ merge_list, context, merge_type,
+ undo_desc, progress);
g_slist_free (merge_list);
gimp_image_undo_group_end (image);
@@ -457,7 +475,9 @@ gimp_image_merge_layers (GimpImage *image,
GimpContainer *container,
GSList *merge_list,
GimpContext *context,
- GimpMergeType merge_type)
+ GimpMergeType merge_type,
+ const gchar *undo_desc,
+ GimpProgress *progress)
{
GimpLayer *parent;
gint x1, y1;
@@ -478,6 +498,7 @@ gimp_image_merge_layers (GimpImage *image,
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
+ g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
top_layer = merge_list->data;
parent = gimp_layer_get_parent (top_layer);
@@ -660,9 +681,10 @@ gimp_image_merge_layers (GimpImage *image,
gegl_node_disconnect (last_node, "input");
/* Render the graph into the merge layer */
- gegl_node_blit_buffer (offset_node,
- gimp_drawable_get_buffer (GIMP_DRAWABLE (merge_layer)),
- NULL, 0, GEGL_ABYSS_NONE);
+ gimp_gegl_apply_operation (NULL, progress, undo_desc, offset_node,
+ gimp_drawable_get_buffer (
+ GIMP_DRAWABLE (merge_layer)),
+ NULL, FALSE);
/* Reconnect the bottom-layer node's input */
if (last_node_source)
diff --git a/app/core/gimpimage-merge.h b/app/core/gimpimage-merge.h
index 4b7a916561..93aab4e53a 100644
--- a/app/core/gimpimage-merge.h
+++ b/app/core/gimpimage-merge.h
@@ -23,17 +23,20 @@ GimpLayer * gimp_image_merge_visible_layers (GimpImage *image,
GimpContext *context,
GimpMergeType merge_type,
gboolean merge_active_group,
- gboolean discard_invisible);
+ gboolean discard_invisible,
+ GimpProgress *progress);
GimpLayer * gimp_image_merge_down (GimpImage *image,
GimpLayer *current_layer,
GimpContext *context,
GimpMergeType merge_type,
+ GimpProgress *progress,
GError **error);
GimpLayer * gimp_image_merge_group_layer (GimpImage *image,
GimpGroupLayer *group);
GimpLayer * gimp_image_flatten (GimpImage *image,
GimpContext *context,
+ GimpProgress *progress,
GError **error);
GimpVectors * gimp_image_merge_visible_vectors (GimpImage *image,
diff --git a/app/dialogs/image-merge-layers-dialog.c b/app/dialogs/image-merge-layers-dialog.c
index 552d26bafa..67681eb779 100644
--- a/app/dialogs/image-merge-layers-dialog.c
+++ b/app/dialogs/image-merge-layers-dialog.c
@@ -182,7 +182,8 @@ image_merge_layers_dialog_response (GtkWidget *dialog,
private->context,
private->merge_type,
private->merge_active_group,
- private->discard_invisible);
+ private->discard_invisible,
+ private->user_data);
}
else
{
diff --git a/app/dialogs/image-merge-layers-dialog.h b/app/dialogs/image-merge-layers-dialog.h
index e763f91cc9..ee965150ee 100644
--- a/app/dialogs/image-merge-layers-dialog.h
+++ b/app/dialogs/image-merge-layers-dialog.h
@@ -24,7 +24,8 @@ typedef void (* GimpMergeLayersCallback) (GtkWidget *dialog,
GimpContext *context,
GimpMergeType merge_type,
gboolean merge_active_group,
- gboolean discard_invisible);
+ gboolean discard_invisible,
+ gpointer user_data);
GtkWidget *
diff --git a/app/file/file-open.c b/app/file/file-open.c
index 0747c7cf4a..fcb7fc3d5f 100644
--- a/app/file/file-open.c
+++ b/app/file/file-open.c
@@ -634,7 +634,8 @@ file_open_layers (Gimp *gimp,
layer = gimp_image_merge_visible_layers (new_image, context,
GIMP_CLIP_TO_IMAGE,
- FALSE, FALSE);
+ FALSE, FALSE,
+ NULL);
layers = g_list_prepend (NULL, layer);
}
diff --git a/app/pdb/image-cmds.c b/app/pdb/image-cmds.c
index 2ddf89b590..17c56d737b 100644
--- a/app/pdb/image-cmds.c
+++ b/app/pdb/image-cmds.c
@@ -1365,7 +1365,8 @@ image_flatten_invoker (GimpProcedure *procedure,
if (success)
{
- layer = gimp_image_flatten (image, context, error);
+ layer = gimp_image_flatten (image, context,
+ progress, error);
if (! layer)
success = FALSE;
@@ -1400,7 +1401,8 @@ image_merge_visible_layers_invoker (GimpProcedure *procedure,
if (success)
{
layer = gimp_image_merge_visible_layers (image, context, merge_type,
- FALSE, FALSE);
+ FALSE, FALSE,
+ progress);
if (! layer)
success = FALSE;
@@ -1439,7 +1441,7 @@ image_merge_down_invoker (GimpProcedure *procedure,
if (gimp_pdb_item_is_attached (GIMP_ITEM (merge_layer), image, 0, error))
{
layer = gimp_image_merge_down (image, merge_layer, context, merge_type,
- error);
+ progress, error);
if (! layer)
success = FALSE;
diff --git a/pdb/groups/image.pdb b/pdb/groups/image.pdb
index d67ce341e3..d51079082c 100644
--- a/pdb/groups/image.pdb
+++ b/pdb/groups/image.pdb
@@ -740,7 +740,8 @@ HELP
code => <<'CODE'
{
layer = gimp_image_merge_visible_layers (image, context, merge_type,
- FALSE, FALSE);
+ FALSE, FALSE,
+ progress);
if (! layer)
success = FALSE;
@@ -786,7 +787,7 @@ HELP
if (gimp_pdb_item_is_attached (GIMP_ITEM (merge_layer), image, 0, error))
{
layer = gimp_image_merge_down (image, merge_layer, context, merge_type,
- error);
+ progress, error);
if (! layer)
success = FALSE;
@@ -825,7 +826,8 @@ HELP
headers => [ qw("core/gimpimage-merge.h") ],
code => <<'CODE'
{
- layer = gimp_image_flatten (image, context, error);
+ layer = gimp_image_flatten (image, context,
+ progress, error);
if (! layer)
success = FALSE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]