[gimp/wip/animation: 362/373] plug-ins: allow forcing the cache creation when hitting "Reload".



commit 44a895ef55f5c23fb3dfbd62d39bac1170f50d4c
Author: Jehan <jehan girinstud io>
Date:   Tue Aug 1 00:19:11 2017 +0200

    plug-ins: allow forcing the cache creation when hitting "Reload".
    
    Most of the time, we want to rely on cached data, but the "Reload"
    button is explicitly made to create new frames even when no change has
    been made (seemingly). This is a workaround to GIMP plugin limitations,
    as long as we have no signal from GIMP core when a layer has been
    changed.

 plug-ins/animation-play/core/animation-renderer.c |   87 +++++++++++++++++++++
 plug-ins/animation-play/core/animation.c          |   26 ++++++-
 plug-ins/animation-play/core/animation.h          |    3 +
 3 files changed, 115 insertions(+), 1 deletions(-)
---
diff --git a/plug-ins/animation-play/core/animation-renderer.c 
b/plug-ins/animation-play/core/animation-renderer.c
index b6e664c..100c618 100644
--- a/plug-ins/animation-play/core/animation-renderer.c
+++ b/plug-ins/animation-play/core/animation-renderer.c
@@ -441,6 +441,91 @@ on_frames_changed (Animation         *animation,
 }
 
 static void
+on_invalidate_cache (Animation         *animation,
+                     gint               position,
+                     gint               length,
+                     AnimationRenderer *renderer)
+{
+  GList *update = NULL;
+  GList *iter;
+  gint   i;
+
+  if (renderer->priv->idle_id)
+    {
+      g_source_remove (renderer->priv->idle_id);
+      renderer->priv->idle_id = 0;
+    }
+  /* Stop any rendering temporarily. */
+  for (i = 0; i < animation_get_duration (animation); i++)
+    {
+      if (g_async_queue_remove (renderer->priv->queue, GINT_TO_POINTER (i + 1)))
+        update = g_list_insert_sorted_with_data (update, GINT_TO_POINTER (i + 1),
+                                                 (GCompareDataFunc) compare_int_from,
+                                                 /* TODO: right now I am sorting the render
+                                                  * queue in common order. I will have to test
+                                                  * sorting it from the current position.
+                                                  */
+                                                 0);
+    }
+  /* Delete the cache. */
+  g_mutex_lock (&renderer->priv->lock);
+  for (i = position; i < position + length; i++)
+    {
+      gint j;
+
+      if (renderer->priv->cache[i])
+        {
+          /* Delete this frame and all others which share the same cache. */
+          GeglBuffer *tmp = g_object_ref (renderer->priv->cache[i]);
+          for (j = 0; j < animation_get_duration (animation); j++)
+            {
+              if (renderer->priv->cache[j] == tmp)
+                {
+                  g_object_unref (renderer->priv->cache[j]);
+                  renderer->priv->cache[j] = NULL;
+                  g_free (renderer->priv->hashes[j]);
+                  renderer->priv->hashes[j] = NULL;
+                  if (g_list_index (update, GINT_TO_POINTER (j + 1)) == -1)
+                    update = g_list_insert_sorted_with_data (update, GINT_TO_POINTER (j + 1),
+                                                             (GCompareDataFunc) compare_int_from,
+                                                             /* TODO: right now I am sorting the render
+                                                              * queue in common order. I will have to test
+                                                              * sorting it from the current position.
+                                                              */
+                                                             0);
+                }
+            }
+          g_object_unref (tmp);
+        }
+      if (g_list_index (update, GINT_TO_POINTER (i + 1)) == -1)
+        update = g_list_insert_sorted_with_data (update, GINT_TO_POINTER (i + 1),
+                                                 (GCompareDataFunc) compare_int_from,
+                                                 /* TODO: right now I am sorting the render
+                                                  * queue in common order. I will have to test
+                                                  * sorting it from the current position.
+                                                  */
+                                                 0);
+    }
+  g_mutex_unlock (&renderer->priv->lock);
+  /* Queue the invalidated part of the animation. */
+  for (iter = update; iter; iter = iter->next)
+    {
+      g_async_queue_push_sorted (renderer->priv->queue,
+                                 iter->data,
+                                 (GCompareDataFunc) compare_int_from,
+                                 /* TODO: right now I am sorting the render
+                                  * queue in common order. I will have to test
+                                  * sorting it from the current position.
+                                  */
+                                 0);
+    }
+  g_list_free (update);
+  renderer->priv->idle_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE,
+                                             (GSourceFunc) animation_renderer_idle_update,
+                                             renderer, NULL);
+}
+
+static void
 on_duration_changed (Animation         *animation,
                      gint               duration,
                      AnimationRenderer *renderer)
@@ -526,6 +611,8 @@ animation_renderer_new (GObject *playback)
                     G_CALLBACK (on_size_changed), renderer);
   g_signal_connect (animation, "frames-changed",
                     G_CALLBACK (on_frames_changed), renderer);
+  g_signal_connect (animation, "invalidate-cache",
+                    G_CALLBACK (on_invalidate_cache), renderer);
   g_signal_connect (animation, "duration-changed",
                     G_CALLBACK (on_duration_changed), renderer);
   g_signal_connect (animation, "loaded",
diff --git a/plug-ins/animation-play/core/animation.c b/plug-ins/animation-play/core/animation.c
index ef5a555..a071786 100644
--- a/plug-ins/animation-play/core/animation.c
+++ b/plug-ins/animation-play/core/animation.c
@@ -47,6 +47,7 @@ enum
   LOADED,
   SIZE_CHANGED,
   FRAMES_CHANGED,
+  INVALIDATE_CACHE,
   DURATION_CHANGED,
   FRAMERATE_CHANGED,
   LAST_SIGNAL
@@ -182,6 +183,29 @@ animation_class_init (AnimationClass *klass)
                   G_TYPE_INT,
                   G_TYPE_INT);
   /**
+   * Animation::invalidate-cache:
+   * @animation: the animation.
+   * @position: the first frame position whose contents changed.
+   * @length: the number of changed frames from @position.
+   *
+   * The ::invalidate-cache signal must be emitted when one or more
+   * successive frames have to be updated. This is similar to
+   * ::frames-changed except that it forces the cache update even if the
+   * contents apparently did not change. It will also invalidate cache
+   * for similar frames, even when not in the given range.
+   */
+  animation_signals[INVALIDATE_CACHE] =
+    g_signal_new ("invalidate-cache",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (AnimationClass, invalidate_cache),
+                  NULL, NULL,
+                  NULL,
+                  G_TYPE_NONE,
+                  2,
+                  G_TYPE_INT,
+                  G_TYPE_INT);
+  /**
    * Animation::duration:
    * @animation: the animation.
    * @duration: the new duration of @animation in number of frames.
@@ -303,7 +327,7 @@ animation_load (Animation *animation)
   AnimationPrivate *priv = ANIMATION_GET_PRIVATE (animation);
 
   priv->loaded = FALSE;
-  g_signal_emit (animation, animation_signals[FRAMES_CHANGED], 0,
+  g_signal_emit (animation, animation_signals[INVALIDATE_CACHE], 0,
                  0, animation_get_duration (animation));
   priv->loaded = TRUE;
   g_signal_emit (animation, animation_signals[LOADED], 0);
diff --git a/plug-ins/animation-play/core/animation.h b/plug-ins/animation-play/core/animation.h
index 6127ec3..3c7a1c2 100644
--- a/plug-ins/animation-play/core/animation.h
+++ b/plug-ins/animation-play/core/animation.h
@@ -51,6 +51,9 @@ struct _AnimationClass
   void         (*frames_changed)     (Animation    *animation,
                                       gint          position,
                                       gint          length);
+  void         (*invalidate_cache)   (Animation    *animation,
+                                      gint          position,
+                                      gint          length);
   void         (*duration_changed)   (Animation    *animation,
                                       gint          duration);
   void         (*framerate_changed)  (Animation    *animation,


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