[mutter/gbsneto/split-pick-paint: 1/4] clutter: Split pick and paint



commit 16c4ec3eaab35cb623473808e2b37da40ca44ebc
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Oct 17 17:01:25 2019 +0200

    clutter: Split pick and paint
    
    Add the corresponding clutter_actor_pick() and
    clutter_actor_continue_pick() as public APIs,
    and use them in pick overrides and ClutterEffect.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/865

 clutter/clutter/clutter-actor.c     | 147 +++++++++++++++++++++++++++++++++++-
 clutter/clutter/clutter-actor.h     |   4 +
 clutter/clutter/clutter-effect.c    |   2 +-
 clutter/clutter/clutter-private.h   |   4 +-
 src/compositor/meta-surface-actor.c |   2 +-
 5 files changed, 155 insertions(+), 4 deletions(-)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 62a28e945..2262b9978 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -2373,7 +2373,7 @@ clutter_actor_real_pick (ClutterActor *self)
       for (iter = self->priv->first_child;
            iter != NULL;
            iter = iter->priv->next_sibling)
-        clutter_actor_paint (iter);
+        clutter_actor_pick (iter);
     }
 }
 
@@ -4215,6 +4215,151 @@ clutter_actor_continue_paint (ClutterActor *self)
     }
 }
 
+/**
+ * clutter_actor_pick:
+ * @actor: A #ClutterActor
+ *
+ * Asks @actor to perform a pick.
+ */
+void
+clutter_actor_pick (ClutterActor *actor)
+{
+  ClutterActorPrivate *priv;
+  ClutterActorBox clip;
+  gboolean clip_set = FALSE;
+
+  if (CLUTTER_ACTOR_IN_DESTRUCTION (actor))
+    return;
+
+  priv = actor->priv;
+
+  /* if we aren't paintable (not in a toplevel with all
+   * parents paintable) then do nothing.
+   */
+  if (!CLUTTER_ACTOR_IS_MAPPED (actor))
+    return;
+
+  clutter_actor_ensure_resource_scale (actor);
+
+  /* mark that we are in the paint process */
+  CLUTTER_SET_PRIVATE_FLAGS (actor, CLUTTER_IN_PICK);
+
+  cogl_push_matrix ();
+
+  if (priv->enable_model_view_transform)
+    {
+      CoglMatrix matrix;
+
+      cogl_get_modelview_matrix (&matrix);
+      _clutter_actor_apply_modelview_transform (actor, &matrix);
+      cogl_set_modelview_matrix (&matrix);
+    }
+
+  if (priv->has_clip)
+    {
+      clip.x1 = priv->clip.origin.x;
+      clip.y1 = priv->clip.origin.y;
+      clip.x2 = priv->clip.origin.x + priv->clip.size.width;
+      clip.y2 = priv->clip.origin.y + priv->clip.size.height;
+      clip_set = TRUE;
+    }
+  else if (priv->clip_to_allocation)
+    {
+      clip.x1 = 0.f;
+      clip.y1 = 0.f;
+      clip.x2 = priv->allocation.x2 - priv->allocation.x1;
+      clip.y2 = priv->allocation.y2 - priv->allocation.y1;
+      clip_set = TRUE;
+    }
+
+  if (clip_set)
+    clip_set = _clutter_actor_push_pick_clip (actor, &clip);
+
+  priv->next_effect_to_paint = NULL;
+  if (priv->effects)
+    {
+      priv->next_effect_to_paint =
+        _clutter_meta_group_peek_metas (priv->effects);
+    }
+
+  clutter_actor_continue_pick (actor);
+
+  if (clip_set)
+    _clutter_actor_pop_pick_clip (actor);
+
+  cogl_pop_matrix ();
+
+  /* paint sequence complete */
+  CLUTTER_UNSET_PRIVATE_FLAGS (actor, CLUTTER_IN_PICK);
+}
+
+/**
+ * clutter_actor_continue_pick:
+ * @actor: A #ClutterActor
+ *
+ * Run the next stage of the pick sequence. This function should only
+ * be called within the implementation of the ‘pick’ virtual of a
+ * #ClutterEffect. It will cause the run method of the next effect to
+ * be applied, or it will pick the actual actor if the current effect
+ * is the last effect in the chain.
+ *
+ * Since: 1.8
+ */
+void
+clutter_actor_continue_pick (ClutterActor *actor)
+{
+  ClutterActorPrivate *priv;
+
+  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
+
+  g_return_if_fail (CLUTTER_ACTOR_IN_PICK (actor));
+
+  priv = actor->priv;
+
+  /* Skip any effects that are disabled */
+  while (priv->next_effect_to_paint &&
+         !clutter_actor_meta_get_enabled (priv->next_effect_to_paint->data))
+    priv->next_effect_to_paint = priv->next_effect_to_paint->next;
+
+  /* If this has come from the last effect then we'll just paint the
+   * actual actor.
+   */
+  if (priv->next_effect_to_paint == NULL)
+    {
+      /* The actor will log a silhouette of itself to the stage pick log.
+       *
+       * XXX:2.0 - Call the pick() virtual directly
+       */
+      if (g_signal_has_handler_pending (actor, actor_signals[PICK],
+                                        0, TRUE))
+        g_signal_emit (actor, actor_signals[PICK], 0);
+      else
+        CLUTTER_ACTOR_GET_CLASS (actor)->pick (actor);
+    }
+  else
+    {
+      ClutterEffect *old_current_effect;
+      ClutterEffectPaintFlags run_flags = 0;
+
+      /* Cache the current effect so that we can put it back before
+       * returning.
+       */
+      old_current_effect = priv->current_effect;
+
+      priv->current_effect = priv->next_effect_to_paint->data;
+      priv->next_effect_to_paint = priv->next_effect_to_paint->next;
+
+      /* We can't determine when an actor has been modified since
+       * its last pick so lets just assume it has always been
+       * modified.
+       */
+      run_flags |= CLUTTER_EFFECT_PAINT_ACTOR_DIRTY;
+      _clutter_effect_pick (priv->current_effect, run_flags);
+
+      priv->current_effect = old_current_effect;
+    }
+}
+
 static void
 _clutter_actor_stop_transitions (ClutterActor *self)
 {
diff --git a/clutter/clutter/clutter-actor.h b/clutter/clutter/clutter-actor.h
index d7382c776..efe919ec8 100644
--- a/clutter/clutter/clutter-actor.h
+++ b/clutter/clutter/clutter-actor.h
@@ -353,6 +353,10 @@ void                            clutter_actor_paint
 CLUTTER_EXPORT
 void                            clutter_actor_continue_paint                    (ClutterActor                
*self);
 CLUTTER_EXPORT
+void                            clutter_actor_pick                              (ClutterActor                
*actor);
+CLUTTER_EXPORT
+void                            clutter_actor_continue_pick                     (ClutterActor                
*actor);
+CLUTTER_EXPORT
 void                            clutter_actor_queue_redraw                      (ClutterActor                
*self);
 CLUTTER_EXPORT
 void                            clutter_actor_queue_redraw_with_clip            (ClutterActor                
*self,
diff --git a/clutter/clutter/clutter-effect.c b/clutter/clutter/clutter-effect.c
index 47c11a53a..5a4c7aa87 100644
--- a/clutter/clutter/clutter-effect.c
+++ b/clutter/clutter/clutter-effect.c
@@ -223,7 +223,7 @@ clutter_effect_real_pick (ClutterEffect           *effect,
   ClutterActor *actor;
 
   actor = clutter_actor_meta_get_actor (actor_meta);
-  clutter_actor_continue_paint (actor);
+  clutter_actor_continue_pick (actor);
 }
 
 static void
diff --git a/clutter/clutter/clutter-private.h b/clutter/clutter/clutter-private.h
index 28c56c0d0..94575f06b 100644
--- a/clutter/clutter/clutter-private.h
+++ b/clutter/clutter/clutter-private.h
@@ -67,6 +67,7 @@ typedef struct _ClutterVertex4          ClutterVertex4;
 #define CLUTTER_ACTOR_IN_DESTRUCTION(a)         ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_DESTRUCTION) != 
FALSE)
 #define CLUTTER_ACTOR_IN_REPARENT(a)            ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_REPARENT) != FALSE)
 #define CLUTTER_ACTOR_IN_PAINT(a)               ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PAINT) != FALSE)
+#define CLUTTER_ACTOR_IN_PICK(a)                ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PICK) != FALSE)
 #define CLUTTER_ACTOR_IN_RELAYOUT(a)            ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_RELAYOUT) != FALSE)
 #define CLUTTER_ACTOR_IN_PREF_WIDTH(a)          ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PREF_WIDTH) != 
FALSE)
 #define CLUTTER_ACTOR_IN_PREF_HEIGHT(a)         ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PREF_HEIGHT) != 
FALSE)
@@ -104,9 +105,10 @@ typedef enum
 
   /* Used to avoid recursion */
   CLUTTER_IN_PAINT       = 1 << 5,
+  CLUTTER_IN_PICK        = 1 << 6,
 
   /* Used to avoid recursion */
-  CLUTTER_IN_RELAYOUT    = 1 << 6,
+  CLUTTER_IN_RELAYOUT    = 1 << 7,
 } ClutterPrivateFlags;
 
 /*
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index 19e775dc9..5046a70fa 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -168,7 +168,7 @@ meta_surface_actor_pick (ClutterActor *actor)
   clutter_actor_iter_init (&iter, actor);
 
   while (clutter_actor_iter_next (&iter, &child))
-    clutter_actor_paint (child);
+    clutter_actor_pick (child);
 }
 
 static gboolean


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