[gimp/gimp-2-10] app: when freezing a drawable's preview, freeze ancestors' previews



commit b9ca245736968d1e2bf00ea0631ed963513a5a35
Author: Ell <ell_se yahoo com>
Date:   Thu Mar 28 12:03:49 2019 -0400

    app: when freezing a drawable's preview, freeze ancestors' previews
    
    Add GimpViewable::preview_{freeze,thaw}() virtual functions, which
    get called when the viewable's preview is frozen/thawed.  Implement
    the functions in GimpDrawable, recursively freezing the parent
    drawable's preview (or the image's preview, for top-level
    drawables) while the drawable's preview is frozen.  For layer
    masks, freeze the associated layer's parent.
    
    This avoids updating layer-group/image previews while painting on,
    or applying a filter to, a descendant layer.  This both reduces
    lag, and fixes a discrepancy between the layer's preview, which
    isn't updated, and its parents' previews.
    
    (cherry picked from commit e2ea2e4a8283d655453dee3bf270ce03f1f22b81)

 app/core/gimpdrawable.c  | 26 ++++++++++++++++++++++++++
 app/core/gimplayermask.c | 40 ++++++++++++++++++++++++++++++++++++++++
 app/core/gimpviewable.c  | 13 ++++++++++++-
 app/core/gimpviewable.h  |  3 +++
 4 files changed, 81 insertions(+), 1 deletion(-)
---
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index 228adffe5b..a35c041c9f 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -100,6 +100,8 @@ static gint64     gimp_drawable_get_memsize        (GimpObject        *object,
 static gboolean   gimp_drawable_get_size           (GimpViewable      *viewable,
                                                     gint              *width,
                                                     gint              *height);
+static void       gimp_drawable_preview_freeze     (GimpViewable      *viewable);
+static void       gimp_drawable_preview_thaw       (GimpViewable      *viewable);
 
 static GeglNode * gimp_drawable_get_node           (GimpFilter        *filter);
 
@@ -266,6 +268,8 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
   viewable_class->get_size        = gimp_drawable_get_size;
   viewable_class->get_new_preview = gimp_drawable_get_new_preview;
   viewable_class->get_new_pixbuf  = gimp_drawable_get_new_pixbuf;
+  viewable_class->preview_freeze  = gimp_drawable_preview_freeze;
+  viewable_class->preview_thaw    = gimp_drawable_preview_thaw;
 
   filter_class->get_node          = gimp_drawable_get_node;
 
@@ -416,6 +420,28 @@ gimp_drawable_get_size (GimpViewable *viewable,
   return TRUE;
 }
 
+static void
+gimp_drawable_preview_freeze (GimpViewable *viewable)
+{
+  GimpViewable *parent = gimp_viewable_get_parent (viewable);
+
+  if (! parent)
+    parent = GIMP_VIEWABLE (gimp_item_get_image (GIMP_ITEM (viewable)));
+
+  gimp_viewable_preview_freeze (parent);
+}
+
+static void
+gimp_drawable_preview_thaw (GimpViewable *viewable)
+{
+  GimpViewable *parent = gimp_viewable_get_parent (viewable);
+
+  if (! parent)
+    parent = GIMP_VIEWABLE (gimp_item_get_image (GIMP_ITEM (viewable)));
+
+  gimp_viewable_preview_thaw (parent);
+}
+
 static GeglNode *
 gimp_drawable_get_node (GimpFilter *filter)
 {
diff --git a/app/core/gimplayermask.c b/app/core/gimplayermask.c
index 23e3ba8de5..8c3dc97f71 100644
--- a/app/core/gimplayermask.c
+++ b/app/core/gimplayermask.c
@@ -32,6 +32,9 @@
 #include "gimp-intl.h"
 
 
+static void            gimp_layer_mask_preview_freeze     (GimpViewable      *viewable);
+static void            gimp_layer_mask_preview_thaw       (GimpViewable      *viewable);
+
 static gboolean        gimp_layer_mask_is_attached        (GimpItem          *item);
 static gboolean        gimp_layer_mask_is_content_locked  (GimpItem          *item);
 static gboolean        gimp_layer_mask_is_position_locked (GimpItem          *item);
@@ -67,6 +70,9 @@ gimp_layer_mask_class_init (GimpLayerMaskClass *klass)
 
   viewable_class->default_icon_name = "gimp-layer-mask";
 
+  viewable_class->preview_freeze = gimp_layer_mask_preview_freeze;
+  viewable_class->preview_thaw   = gimp_layer_mask_preview_thaw;
+
   item_class->is_attached        = gimp_layer_mask_is_attached;
   item_class->is_content_locked  = gimp_layer_mask_is_content_locked;
   item_class->is_position_locked = gimp_layer_mask_is_position_locked;
@@ -85,6 +91,40 @@ gimp_layer_mask_init (GimpLayerMask *layer_mask)
   layer_mask->layer = NULL;
 }
 
+static void
+gimp_layer_mask_preview_freeze (GimpViewable *viewable)
+{
+  GimpLayerMask *mask  = GIMP_LAYER_MASK (viewable);
+  GimpLayer     *layer = gimp_layer_mask_get_layer (mask);
+
+  if (layer)
+    {
+      GimpViewable *parent = gimp_viewable_get_parent (GIMP_VIEWABLE (layer));
+
+      if (! parent)
+        parent = GIMP_VIEWABLE (gimp_item_get_image (GIMP_ITEM (layer)));
+
+      gimp_viewable_preview_freeze (parent);
+    }
+}
+
+static void
+gimp_layer_mask_preview_thaw (GimpViewable *viewable)
+{
+  GimpLayerMask *mask  = GIMP_LAYER_MASK (viewable);
+  GimpLayer     *layer = gimp_layer_mask_get_layer (mask);
+
+  if (layer)
+    {
+      GimpViewable *parent = gimp_viewable_get_parent (GIMP_VIEWABLE (layer));
+
+      if (! parent)
+        parent = GIMP_VIEWABLE (gimp_item_get_image (GIMP_ITEM (layer)));
+
+      gimp_viewable_preview_thaw (parent);
+    }
+}
+
 static gboolean
 gimp_layer_mask_is_content_locked (GimpItem *item)
 {
diff --git a/app/core/gimpviewable.c b/app/core/gimpviewable.c
index 0fbe0e7bf9..8961fb06ba 100644
--- a/app/core/gimpviewable.c
+++ b/app/core/gimpviewable.c
@@ -206,6 +206,8 @@ gimp_viewable_class_init (GimpViewableClass *klass)
   klass->get_new_pixbuf          = gimp_viewable_real_get_new_pixbuf;
   klass->get_description         = gimp_viewable_real_get_description;
   klass->is_name_editable        = gimp_viewable_real_is_name_editable;
+  klass->preview_freeze          = NULL;
+  klass->preview_thaw            = NULL;
   klass->get_children            = gimp_viewable_real_get_children;
   klass->set_expanded            = NULL;
   klass->get_expanded            = NULL;
@@ -1280,7 +1282,12 @@ gimp_viewable_preview_freeze (GimpViewable *viewable)
   private->freeze_count++;
 
   if (private->freeze_count == 1)
-    g_object_notify (G_OBJECT (viewable), "frozen");
+    {
+      if (GIMP_VIEWABLE_GET_CLASS (viewable)->preview_freeze)
+        GIMP_VIEWABLE_GET_CLASS (viewable)->preview_freeze (viewable);
+
+      g_object_notify (G_OBJECT (viewable), "frozen");
+    }
 }
 
 void
@@ -1299,7 +1306,11 @@ gimp_viewable_preview_thaw (GimpViewable *viewable)
   if (private->freeze_count == 0)
     {
       gimp_viewable_invalidate_preview (viewable);
+
       g_object_notify (G_OBJECT (viewable), "frozen");
+
+      if (GIMP_VIEWABLE_GET_CLASS (viewable)->preview_thaw)
+        GIMP_VIEWABLE_GET_CLASS (viewable)->preview_thaw (viewable);
     }
 }
 
diff --git a/app/core/gimpviewable.h b/app/core/gimpviewable.h
index b3c1fa84e4..249750ec17 100644
--- a/app/core/gimpviewable.h
+++ b/app/core/gimpviewable.h
@@ -97,6 +97,9 @@ struct _GimpViewableClass
 
   gboolean        (* is_name_editable)   (GimpViewable  *viewable);
 
+  void            (* preview_freeze)     (GimpViewable  *viewable);
+  void            (* preview_thaw)       (GimpViewable  *viewable);
+
   GimpContainer * (* get_children)       (GimpViewable  *viewable);
 
   void            (* set_expanded)       (GimpViewable  *viewable,


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