[mutter/gbsneto/split-pick-paint: 4/8] clutter: Split pick and paint
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gbsneto/split-pick-paint: 4/8] clutter: Split pick and paint
- Date: Mon, 21 Oct 2019 13:49:49 +0000 (UTC)
commit 179d5ba6a6c0806ca0ac36318c01b9a91c65462b
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 | 145 +++++++++++++++++++++++++++++++++++-
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, 153 insertions(+), 4 deletions(-)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 62a28e945..b6949aff1 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,149 @@ 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.
+ */
+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 pick 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]