[mutter/wip/carlosg/unthrottled-wayland: 978/978] clutter: Store the per-pointer picked actor's clear area
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/carlosg/unthrottled-wayland: 978/978] clutter: Store the per-pointer picked actor's clear area
- Date: Mon, 5 Jul 2021 15:45:38 +0000 (UTC)
commit 72467ec0d6487e00965cfbd45cd861240b60e874
Author: Carlos Garnacho <carlosg gnome org>
Date: Mon Jul 5 17:23:21 2021 +0200
clutter: Store the per-pointer picked actor's clear area
And resort to it first, unless we are told to ignore the cache
(e.g. after relayouts). This avoids further pick context operations
while the pointer is on the current actor.
clutter/clutter/clutter-main.c | 1 +
clutter/clutter/clutter-mutter.h | 1 +
clutter/clutter/clutter-stage-private.h | 4 +-
clutter/clutter/clutter-stage.c | 83 +++++++++++++++++++++++++++------
4 files changed, 73 insertions(+), 16 deletions(-)
---
diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c
index 6a9a042989..16930783aa 100644
--- a/clutter/clutter/clutter-main.c
+++ b/clutter/clutter/clutter-main.c
@@ -1392,6 +1392,7 @@ remove_device_for_event (ClutterStage *stage,
point,
time,
NULL,
+ NULL,
TRUE);
clutter_stage_remove_device_entry (stage, device, sequence);
diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h
index 91e1535862..e9ac75e46b 100644
--- a/clutter/clutter/clutter-mutter.h
+++ b/clutter/clutter/clutter-mutter.h
@@ -90,6 +90,7 @@ void clutter_stage_update_device (ClutterStage *stage,
graphene_point_t point,
uint32_t time,
ClutterActor *new_actor,
+ cairo_region_t *region,
gboolean emit_crossing);
CLUTTER_EXPORT
diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h
index eddcc788e7..d93f0741db 100644
--- a/clutter/clutter/clutter-stage-private.h
+++ b/clutter/clutter/clutter-stage-private.h
@@ -35,6 +35,7 @@ typedef enum
{
CLUTTER_DEVICE_UPDATE_NONE = 0,
CLUTTER_DEVICE_UPDATE_EMIT_CROSSING = 1 << 0,
+ CLUTTER_DEVICE_UPDATE_IGNORE_CACHE = 1 << 1,
} ClutterDeviceUpdateFlags;
/* stage */
@@ -133,7 +134,8 @@ void clutter_stage_update_device_entry (ClutterStage *self,
ClutterInputDevice *device,
ClutterEventSequence *sequence,
graphene_point_t coords,
- ClutterActor *actor);
+ ClutterActor *actor,
+ cairo_region_t *clear_area);
void clutter_stage_remove_device_entry (ClutterStage *self,
ClutterInputDevice *device,
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 181aa934ad..c2f4f6e10e 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -104,6 +104,7 @@ typedef struct _PointerDeviceEntry
ClutterEventSequence *sequence;
graphene_point_t coords;
ClutterActor *current_actor;
+ cairo_region_t *clear_area;
} PointerDeviceEntry;
struct _ClutterStagePrivate
@@ -984,6 +985,7 @@ clutter_stage_update_devices (ClutterStage *stage,
clutter_stage_pick_and_update_device (stage,
device,
NULL,
+ CLUTTER_DEVICE_UPDATE_IGNORE_CACHE |
CLUTTER_DEVICE_UPDATE_EMIT_CROSSING,
entry->coords,
CLUTTER_CURRENT_TIME);
@@ -1060,11 +1062,12 @@ setup_ray_for_coordinates (ClutterStage *stage,
}
static ClutterActor *
-_clutter_stage_do_pick_on_view (ClutterStage *stage,
- float x,
- float y,
- ClutterPickMode mode,
- ClutterStageView *view)
+_clutter_stage_do_pick_on_view (ClutterStage *stage,
+ float x,
+ float y,
+ ClutterPickMode mode,
+ ClutterStageView *view,
+ cairo_region_t **clear_area)
{
g_autoptr (ClutterPickStack) pick_stack = NULL;
ClutterPickContext *pick_context;
@@ -1082,7 +1085,7 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
pick_stack = clutter_pick_context_steal_stack (pick_context);
clutter_pick_context_destroy (pick_context);
- actor = clutter_pick_stack_search_actor (pick_stack, &p, &ray, NULL);
+ actor = clutter_pick_stack_search_actor (pick_stack, &p, &ray, clear_area);
return actor ? actor : CLUTTER_ACTOR (stage);
}
@@ -1114,10 +1117,11 @@ clutter_stage_get_view_at (ClutterStage *stage,
}
static ClutterActor *
-_clutter_stage_do_pick (ClutterStage *stage,
- float x,
- float y,
- ClutterPickMode mode)
+_clutter_stage_do_pick (ClutterStage *stage,
+ float x,
+ float y,
+ ClutterPickMode mode,
+ cairo_region_t **clear_area)
{
ClutterActor *actor = CLUTTER_ACTOR (stage);
ClutterStagePrivate *priv = stage->priv;
@@ -1141,7 +1145,7 @@ _clutter_stage_do_pick (ClutterStage *stage,
view = clutter_stage_get_view_at (stage, x, y);
if (view)
- return _clutter_stage_do_pick_on_view (stage, x, y, mode, view);
+ return _clutter_stage_do_pick_on_view (stage, x, y, mode, view, clear_area);
return actor;
}
@@ -1964,7 +1968,7 @@ clutter_stage_get_actor_at_pos (ClutterStage *stage,
{
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
- return _clutter_stage_do_pick (stage, x, y, pick_mode);
+ return _clutter_stage_do_pick (stage, x, y, pick_mode, NULL);
}
/**
@@ -3362,6 +3366,7 @@ on_device_actor_reactive_changed (ClutterActor *actor,
clutter_stage_pick_and_update_device (self,
entry->device,
entry->sequence,
+ CLUTTER_DEVICE_UPDATE_IGNORE_CACHE |
CLUTTER_DEVICE_UPDATE_EMIT_CROSSING,
entry->coords,
CLUTTER_CURRENT_TIME);
@@ -3398,6 +3403,8 @@ free_pointer_device_entry (PointerDeviceEntry *entry)
_clutter_actor_set_has_pointer (actor, FALSE);
}
+ g_clear_pointer (&entry->clear_area, cairo_region_destroy);
+
g_free (entry);
}
@@ -3406,7 +3413,8 @@ clutter_stage_update_device_entry (ClutterStage *self,
ClutterInputDevice *device,
ClutterEventSequence *sequence,
graphene_point_t coords,
- ClutterActor *actor)
+ ClutterActor *actor,
+ cairo_region_t *clear_area)
{
ClutterStagePrivate *priv = self->priv;
PointerDeviceEntry *entry = NULL;
@@ -3462,6 +3470,10 @@ clutter_stage_update_device_entry (ClutterStage *self,
_clutter_actor_set_has_pointer (actor, TRUE);
}
}
+
+ g_clear_pointer (&entry->clear_area, cairo_region_destroy);
+ if (clear_area)
+ entry->clear_area = cairo_region_reference (clear_area);
}
void
@@ -3579,6 +3591,7 @@ clutter_stage_update_device (ClutterStage *stage,
graphene_point_t point,
uint32_t time,
ClutterActor *new_actor,
+ cairo_region_t *clear_area,
gboolean emit_crossing)
{
ClutterInputDeviceType device_type;
@@ -3596,7 +3609,8 @@ clutter_stage_update_device (ClutterStage *stage,
clutter_stage_update_device_entry (stage,
device, sequence,
point,
- new_actor);
+ new_actor,
+ clear_area);
if (device_actor_changed)
{
@@ -3637,11 +3651,38 @@ clutter_stage_repick_device (ClutterStage *stage,
clutter_stage_pick_and_update_device (stage,
device,
NULL,
+ CLUTTER_DEVICE_UPDATE_IGNORE_CACHE |
CLUTTER_DEVICE_UPDATE_EMIT_CROSSING,
point,
CLUTTER_CURRENT_TIME);
}
+static gboolean
+clutter_stage_check_in_clear_area (ClutterStage *stage,
+ ClutterInputDevice *device,
+ ClutterEventSequence *sequence,
+ graphene_point_t point)
+{
+ ClutterStagePrivate *priv = stage->priv;
+ PointerDeviceEntry *entry = NULL;
+
+ g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
+ g_return_val_if_fail (device != NULL, FALSE);
+
+ if (sequence != NULL)
+ entry = g_hash_table_lookup (priv->touch_sequences, sequence);
+ else
+ entry = g_hash_table_lookup (priv->pointer_devices, device);
+
+ if (!entry)
+ return FALSE;
+ if (!entry->clear_area)
+ return FALSE;
+
+ return cairo_region_contains_point (entry->clear_area,
+ point.x, point.y);
+}
+
ClutterActor *
clutter_stage_pick_and_update_device (ClutterStage *stage,
ClutterInputDevice *device,
@@ -3651,11 +3692,20 @@ clutter_stage_pick_and_update_device (ClutterStage *stage,
uint32_t time)
{
ClutterActor *new_actor;
+ cairo_region_t *clear_area = NULL;
+
+ if ((flags & CLUTTER_DEVICE_UPDATE_IGNORE_CACHE) == 0)
+ {
+ if (clutter_stage_check_in_clear_area (stage, device,
+ sequence, point))
+ return clutter_stage_get_device_actor (stage, device, sequence);
+ }
new_actor = _clutter_stage_do_pick (stage,
point.x,
point.y,
- CLUTTER_PICK_REACTIVE);
+ CLUTTER_PICK_REACTIVE,
+ &clear_area);
/* Picking should never fail, but if it does, we bail out here */
g_return_val_if_fail (new_actor != NULL, NULL);
@@ -3665,7 +3715,10 @@ clutter_stage_pick_and_update_device (ClutterStage *stage,
point,
time,
new_actor,
+ clear_area,
!!(flags & CLUTTER_DEVICE_UPDATE_EMIT_CROSSING));
+ g_clear_pointer (&clear_area, cairo_region_destroy);
+
return new_actor;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]