[gimp/gimp-2-10] app: in GimpLineArt, use "invalidate-preview" signal of input viewable



commit 13c6fe5db684db2d0e1284b67e2d8418b4d447d3
Author: Ell <ell_se yahoo com>
Date:   Thu Dec 27 17:07:46 2018 -0500

    app: in GimpLineArt, use "invalidate-preview" signal of input viewable
    
    In GimpLineArt, use the "invalidate-preview" signal of the input
    viewable, instead of its "painted" or "rendered" signals, for
    asynchronously computing the line art.  Subsequently, remove the
    aforementioned signals from GimpDrawable and GimpProjection,
    respectively.  This simplifies the code, and reduces the number of
    signals.
    
    (cherry picked from commit ef9b1f6694b9f44f6b55fabfb5898a4b35c5b88f)

 app/core/gimpdrawable.c   |  30 -------------
 app/core/gimpdrawable.h   |   1 -
 app/core/gimplineart.c    | 112 ++++++++++++++++++++--------------------------
 app/core/gimpprojection.c |  11 -----
 app/core/gimpprojection.h |  13 +++---
 5 files changed, 54 insertions(+), 113 deletions(-)
---
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index ef0cc22459..b2d7e24fe6 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -66,7 +66,6 @@
 enum
 {
   UPDATE,
-  PAINTED,
   ALPHA_CHANGED,
   LAST_SIGNAL
 };
@@ -219,16 +218,6 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
   GimpFilterClass   *filter_class      = GIMP_FILTER_CLASS (klass);
   GimpItemClass     *item_class        = GIMP_ITEM_CLASS (klass);
 
-  /**
-   * GimpDrawable::update:
-   * @drawable: the object which received the signal.
-   * @x:
-   * @y:
-   * @width:
-   * @height:
-   *
-   * This signal is emitted when a region of the drawable is updated.
-   **/
   gimp_drawable_signals[UPDATE] =
     g_signal_new ("update",
                   G_TYPE_FROM_CLASS (klass),
@@ -242,24 +231,6 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
                   G_TYPE_INT,
                   G_TYPE_INT);
 
-  /**
-   * GimpDrawable::painted:
-   * @drawable: the object which received the signal.
-   *
-   * This signal is emitted when the drawable has been painted. Unlike
-   * the "update" signal, it will be emitted once for a single paint
-   * event (whereas several "update" signals could be emitted
-   * sequentially for various regions of the drawable).
-   **/
-  gimp_drawable_signals[PAINTED] =
-    g_signal_new ("painted",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_FIRST,
-                  G_STRUCT_OFFSET (GimpDrawableClass, painted),
-                  NULL, NULL,
-                  gimp_marshal_VOID__VOID,
-                  G_TYPE_NONE, 0);
-
   gimp_drawable_signals[ALPHA_CHANGED] =
     g_signal_new ("alpha-changed",
                   G_TYPE_FROM_CLASS (klass),
@@ -1034,7 +1005,6 @@ gimp_drawable_update (GimpDrawable *drawable,
     {
       g_signal_emit (drawable, gimp_drawable_signals[UPDATE], 0,
                      x, y, width, height);
-      g_signal_emit (drawable, gimp_drawable_signals[PAINTED], 0);
     }
   else
     {
diff --git a/app/core/gimpdrawable.h b/app/core/gimpdrawable.h
index 0239ab0880..a36f001c17 100644
--- a/app/core/gimpdrawable.h
+++ b/app/core/gimpdrawable.h
@@ -50,7 +50,6 @@ struct _GimpDrawableClass
                                            gint                  y,
                                            gint                  width,
                                            gint                  height);
-  void          (* painted)               (GimpDrawable         *drawable);
   void          (* alpha_changed)         (GimpDrawable         *drawable);
 
   /*  virtual functions  */
diff --git a/app/core/gimplineart.c b/app/core/gimplineart.c
index 9bf15e438a..c1ada880f7 100644
--- a/app/core/gimplineart.c
+++ b/app/core/gimplineart.c
@@ -28,6 +28,7 @@
 #include "core-types.h"
 
 #include "gimp-parallel.h"
+#include "gimp-priorities.h"
 #include "gimp-utils.h" /* GIMP_TIMER */
 #include "gimpasync.h"
 #include "gimpcancelable.h"
@@ -36,6 +37,7 @@
 #include "gimplineart.h"
 #include "gimppickable.h"
 #include "gimpprojection.h"
+#include "gimpviewable.h"
 #include "gimpwaitable.h"
 
 #include "gimp-intl.h"
@@ -59,6 +61,8 @@ struct _GimpLineArtPrivate
 
   GimpAsync    *async;
 
+  gint          idle_id;
+
   GimpPickable *input;
   GeglBuffer   *closed;
   gfloat       *distmap;
@@ -156,9 +160,8 @@ static LineArtResult * line_art_result_new                     (GeglBuffer
                                                                 gfloat                 *distmap);
 static void            line_art_result_free                    (LineArtResult          *result);
 
-static void            gimp_line_art_projection_rendered       (GimpProjection         *proj,
-                                                                GimpLineArt            *line_art);
-static void            gimp_line_art_drawable_painted          (GimpDrawable           *drawable,
+static gboolean        gimp_line_art_idle                      (GimpLineArt            *line_art);
+static void            gimp_line_art_input_invalidate_preview  (GimpViewable           *viewable,
                                                                 GimpLineArt            *line_art);
 
 
@@ -330,28 +333,9 @@ gimp_line_art_finalize (GObject *object)
 {
   GimpLineArt *line_art = GIMP_LINE_ART (object);
 
-  if (line_art->priv->input)
-    {
-      if (GIMP_IS_IMAGE (line_art->priv->input))
-        g_signal_handlers_disconnect_by_data (gimp_image_get_projection (GIMP_IMAGE (line_art->priv->input)),
-                                              line_art);
-      else
-        g_signal_handlers_disconnect_by_data (line_art->priv->input,
-                                              line_art);
-    }
-  if (line_art->priv->async)
-    {
-      /* we cancel the async, but don't wait for it to finish, since
-       * it can't actually be interrupted.  instead
-       * gimp_bucket_fill_compute_line_art_cb() bails if the async has
-       * been canceled, to avoid accessing the dead tool.
-       */
-      gimp_cancelable_cancel (GIMP_CANCELABLE (line_art->priv->async));
-      g_clear_object (&line_art->priv->async);
-    }
+  line_art->priv->frozen = FALSE;
 
-  g_clear_object (&line_art->priv->closed);
-  g_clear_pointer (&line_art->priv->distmap, g_free);
+  gimp_line_art_set_input (line_art, NULL);
 }
 
 static void
@@ -435,31 +419,20 @@ void
 gimp_line_art_set_input (GimpLineArt  *line_art,
                          GimpPickable *pickable)
 {
+  g_return_if_fail (pickable == NULL || GIMP_IS_VIEWABLE (pickable));
+
   if (line_art->priv->input)
-    {
-      if (GIMP_IS_IMAGE (line_art->priv->input))
-        g_signal_handlers_disconnect_by_data (gimp_image_get_projection (GIMP_IMAGE (line_art->priv->input)),
-                                              line_art);
-      else
-        g_signal_handlers_disconnect_by_data (line_art->priv->input,
-                                              line_art);
-    }
+    g_signal_handlers_disconnect_by_data (line_art->priv->input, line_art);
 
   line_art->priv->input = pickable;
 
   gimp_line_art_compute (line_art);
+
   if (pickable)
     {
-      if (GIMP_IS_IMAGE (pickable))
-        g_signal_connect (gimp_image_get_projection (GIMP_IMAGE (pickable)), "rendered",
-                          G_CALLBACK (gimp_line_art_projection_rendered),
-                          line_art);
-      else if (GIMP_IS_DRAWABLE (pickable))
-        g_signal_connect (pickable, "painted",
-                          G_CALLBACK (gimp_line_art_drawable_painted),
-                          line_art);
-      else
-        g_return_if_reached ();
+      g_signal_connect (pickable, "invalidate-preview",
+                        G_CALLBACK (gimp_line_art_input_invalidate_preview),
+                        line_art);
     }
 }
 
@@ -523,10 +496,20 @@ gimp_line_art_compute (GimpLineArt *line_art)
 
   if (line_art->priv->async)
     {
+      /* we cancel the async, but don't wait for it to finish, since
+       * it can't actually be interrupted.  instead gimp_line_art_compute_cb()
+       * bails if the async has been canceled, to avoid accessing the line art.
+       */
       gimp_cancelable_cancel (GIMP_CANCELABLE (line_art->priv->async));
       g_clear_object (&line_art->priv->async);
     }
 
+  if (line_art->priv->idle_id)
+    {
+      g_source_remove (line_art->priv->idle_id);
+      line_art->priv->idle_id = 0;
+    }
+
   g_clear_object (&line_art->priv->closed);
   g_clear_pointer (&line_art->priv->distmap, g_free);
 
@@ -536,23 +519,15 @@ gimp_line_art_compute (GimpLineArt *line_art)
        * may trigger this signal handler, and will leak a line art (as
        * line_art->priv->async has not been set yet).
        */
-      if (GIMP_IS_IMAGE (line_art->priv->input))
-        g_signal_handlers_block_by_func (gimp_image_get_projection (GIMP_IMAGE (line_art->priv->input)),
-                                         G_CALLBACK (gimp_line_art_projection_rendered),
-                                         line_art);
-      else
-        g_signal_handlers_block_by_func (line_art->priv->input,
-                                         G_CALLBACK (gimp_line_art_drawable_painted),
-                                         line_art);
+      g_signal_handlers_block_by_func (
+        line_art->priv->input,
+        G_CALLBACK (gimp_line_art_input_invalidate_preview),
+        line_art);
       line_art->priv->async = gimp_line_art_prepare_async (line_art, +1);
-      if (GIMP_IS_IMAGE (line_art->priv->input))
-        g_signal_handlers_unblock_by_func (gimp_image_get_projection (GIMP_IMAGE (line_art->priv->input)),
-                                           G_CALLBACK (gimp_line_art_projection_rendered),
-                                           line_art);
-      else
-        g_signal_handlers_unblock_by_func (line_art->priv->input,
-                                           G_CALLBACK (gimp_line_art_drawable_painted),
-                                           line_art);
+      g_signal_handlers_unblock_by_func (
+        line_art->priv->input,
+        G_CALLBACK (gimp_line_art_input_invalidate_preview),
+        line_art);
 
       gimp_async_add_callback_for_object (line_art->priv->async,
                                           (GimpAsyncCallback) gimp_line_art_compute_cb,
@@ -750,18 +725,27 @@ line_art_result_free (LineArtResult *data)
   g_slice_free (LineArtResult, data);
 }
 
-static void
-gimp_line_art_projection_rendered (GimpProjection *proj,
-                                   GimpLineArt    *line_art)
+static gboolean
+gimp_line_art_idle (GimpLineArt *line_art)
 {
+  line_art->priv->idle_id = 0;
+
   gimp_line_art_compute (line_art);
+
+  return G_SOURCE_REMOVE;
 }
 
 static void
-gimp_line_art_drawable_painted (GimpDrawable *drawable,
-                                GimpLineArt  *line_art)
+gimp_line_art_input_invalidate_preview (GimpViewable *viewable,
+                                        GimpLineArt  *line_art)
 {
-  gimp_line_art_compute (line_art);
+  if (! line_art->priv->idle_id)
+    {
+      line_art->priv->idle_id = g_idle_add_full (
+        GIMP_PRIORITY_VIEWABLE_IDLE,
+        (GSourceFunc) gimp_line_art_idle,
+        line_art, NULL);
+    }
 }
 
 /* All actual computation functions. */
diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c
index 9d9765e3bb..b7b2c26a3d 100644
--- a/app/core/gimpprojection.c
+++ b/app/core/gimpprojection.c
@@ -81,7 +81,6 @@ static gdouble GIMP_PROJECTION_CHUNK_TIME = 0.0666;
 enum
 {
   UPDATE,
-  RENDERED,
   LAST_SIGNAL
 };
 
@@ -259,15 +258,6 @@ gimp_projection_class_init (GimpProjectionClass *klass)
                   G_TYPE_INT,
                   G_TYPE_INT);
 
-  projection_signals[RENDERED] =
-    g_signal_new ("rendered",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  G_STRUCT_OFFSET (GimpProjectionClass, rendered),
-                  NULL, NULL,
-                  gimp_marshal_VOID__VOID,
-                  G_TYPE_NONE, 0);
-
   object_class->finalize         = gimp_projection_finalize;
   object_class->set_property     = gimp_projection_set_property;
   object_class->get_property     = gimp_projection_get_property;
@@ -852,7 +842,6 @@ gimp_projection_chunk_render_stop (GimpProjection *proj)
 
   g_source_remove (proj->priv->chunk_render.idle_id);
   proj->priv->chunk_render.idle_id = 0;
-  g_signal_emit (proj, projection_signals[RENDERED], 0);
 }
 
 static gboolean
diff --git a/app/core/gimpprojection.h b/app/core/gimpprojection.h
index 36d76d076c..8c9baf69e6 100644
--- a/app/core/gimpprojection.h
+++ b/app/core/gimpprojection.h
@@ -44,13 +44,12 @@ struct _GimpProjectionClass
 {
   GimpObjectClass  parent_class;
 
-  void (* update)   (GimpProjection *proj,
-                     gboolean        now,
-                     gint            x,
-                     gint            y,
-                     gint            width,
-                     gint            height);
-  void (* rendered) (GimpProjection *proj);
+  void (* update) (GimpProjection *proj,
+                   gboolean        now,
+                   gint            x,
+                   gint            y,
+                   gint            width,
+                   gint            height);
 };
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]