[gimp] app: make line art pre-computation in threads.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: make line art pre-computation in threads.
- Date: Wed, 14 Nov 2018 12:42:39 +0000 (UTC)
commit a3cda4abbe229ad5d4d512122c5089d2a77f7ba0
Author: Jehan <jehan girinstud io>
Date: Sun Nov 4 14:29:16 2018 +0100
app: make line art pre-computation in threads.
This makes the speed sensation of the tool much faster as line art can
be computed in dead time when you start the tool or when you move the
pointer.
app/tools/gimpbucketfilltool.c | 108 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 95 insertions(+), 13 deletions(-)
---
diff --git a/app/tools/gimpbucketfilltool.c b/app/tools/gimpbucketfilltool.c
index 2406da91e6..670a7cbb8e 100644
--- a/app/tools/gimpbucketfilltool.c
+++ b/app/tools/gimpbucketfilltool.c
@@ -25,6 +25,8 @@
#include "tools-types.h"
#include "core/gimp.h"
+#include "core/gimpasync.h"
+#include "core/gimpcancelable.h"
#include "core/gimpdrawable-bucket-fill.h"
#include "core/gimpdrawable-edit.h"
#include "core/gimperror.h"
@@ -32,8 +34,10 @@
#include "core/gimpimage.h"
#include "core/gimpitem.h"
#include "core/gimplineart.h"
+#include "core/gimp-parallel.h"
#include "core/gimppickable.h"
#include "core/gimppickable-contiguous-region.h"
+#include "core/gimpwaitable.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpwidgets-utils.h"
@@ -49,6 +53,7 @@
struct _GimpBucketFillToolPrivate
{
+ GimpAsync *async;
GeglBuffer *line_art;
GWeakRef cached_image;
GWeakRef cached_drawable;
@@ -260,8 +265,9 @@ gimp_bucket_fill_tool_button_release (GimpTool *tool,
GimpButtonReleaseType release_type,
GimpDisplay *display)
{
- GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool);
- GimpImage *image = gimp_display_get_image (display);
+ GimpBucketFillTool *bucket_tool = GIMP_BUCKET_FILL_TOOL (tool);
+ GimpBucketFillOptions *options = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool);
+ GimpImage *image = gimp_display_get_image (display);
if ((release_type == GIMP_BUTTON_RELEASE_CLICK ||
release_type == GIMP_BUTTON_RELEASE_NO_MOTION) &&
@@ -292,8 +298,9 @@ gimp_bucket_fill_tool_button_release (GimpTool *tool,
}
else
{
- gint x = coords->x;
- gint y = coords->y;
+ GeglBuffer *line_art;
+ gint x = coords->x;
+ gint y = coords->y;
if (! options->sample_merged)
{
@@ -305,9 +312,13 @@ gimp_bucket_fill_tool_button_release (GimpTool *tool,
y -= off_y;
}
+ gimp_waitable_wait (GIMP_WAITABLE (bucket_tool->priv->async));
+ line_art = g_object_ref (bucket_tool->priv->line_art);
+ g_object_unref (bucket_tool->priv->async);
+ bucket_tool->priv->async = NULL;
gimp_drawable_bucket_fill (drawable,
- GIMP_BUCKET_FILL_TOOL (tool)->priv->line_art,
+ line_art,
fill_options,
options->fill_transparent,
options->fill_criterion,
@@ -315,6 +326,7 @@ gimp_bucket_fill_tool_button_release (GimpTool *tool,
options->sample_merged,
options->diagonal_neighbors,
x, y);
+ g_object_unref (line_art);
}
gimp_image_flush (image);
@@ -408,6 +420,50 @@ gimp_bucket_fill_tool_cursor_update (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
+typedef struct
+{
+ GimpBucketFillTool *tool;
+ GimpPickable *pickable;
+ gboolean fill_transparent;
+} PrecomputeData;
+
+static void
+precompute_data_free (PrecomputeData *data)
+{
+ g_object_unref (data->pickable);
+ g_object_unref (data->tool);
+ g_slice_free (PrecomputeData, data);
+}
+
+static void
+gimp_bucket_fill_compute_line_art_async (GimpAsync *async,
+ PrecomputeData *data)
+{
+ GeglBuffer *line_art;
+
+ line_art = gimp_pickable_contiguous_region_prepare_line_art (data->pickable,
+ data->fill_transparent);
+ precompute_data_free (data);
+ if (gimp_async_is_canceled (async))
+ {
+ g_object_unref (line_art);
+ gimp_async_abort (async);
+ return;
+ }
+ gimp_async_finish (async, line_art);
+}
+
+static void
+gimp_bucket_fill_compute_line_art_cb (GimpAsync *async,
+ GimpBucketFillTool *tool)
+{
+ if (gimp_async_is_canceled (async))
+ return;
+
+ if (gimp_async_is_finished (async))
+ tool->priv->line_art = gimp_async_get_result (async);
+}
+
static void
gimp_bucket_fill_compute_line_art (GimpBucketFillTool *tool)
{
@@ -421,17 +477,43 @@ gimp_bucket_fill_compute_line_art (GimpBucketFillTool *tool)
GimpDrawable *drawable = g_weak_ref_get (&tool->priv->cached_drawable);
if (image && options->sample_merged)
- pickable = GIMP_PICKABLE (image);
+ {
+ pickable = GIMP_PICKABLE (image);
+ g_object_unref (drawable);
+ }
else if (drawable && ! options->sample_merged)
- pickable = GIMP_PICKABLE (drawable);
+ {
+ pickable = GIMP_PICKABLE (drawable);
+ g_object_unref (image);
+ }
+ else
+ {
+ g_object_unref (image);
+ g_object_unref (drawable);
+ }
if (pickable)
- tool->priv->line_art = gimp_pickable_contiguous_region_prepare_line_art (pickable,
- options->fill_transparent);
- if (image)
- g_object_unref (image);
- if (drawable)
- g_object_unref (drawable);
+ {
+ PrecomputeData *data = g_slice_new (PrecomputeData);
+
+ data->tool = g_object_ref (tool);
+ data->pickable = pickable;
+ data->fill_transparent = options->fill_transparent;
+
+ if (tool->priv->async)
+ {
+ gimp_cancelable_cancel (GIMP_CANCELABLE (tool->priv->async));
+ g_object_unref (tool->priv->async);
+ }
+ tool->priv->async = gimp_parallel_run_async_full (1,
+ (GimpParallelRunAsyncFunc)
gimp_bucket_fill_compute_line_art_async,
+ data, (GDestroyNotify) precompute_data_free);
+ gimp_async_add_callback (tool->priv->async,
+ (GimpAsyncCallback) gimp_bucket_fill_compute_line_art_cb,
+ tool);
+ }
+ else
+ g_object_unref (pickable);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]