input: Add support for tracking input events on egress side

This includes an additional _double variant for _Generics and a bool
one.

Similarly, _WESTON_TRACE_ANNOTATE_FUNC_FLOW gets a _Generics macro variant
to handle the case were we have a integer flow ID, rather than an a
pointer.

Finally we always have a flow ID set when weston_input_event gets
initalized.

Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
This commit is contained in:
Marius Vlad 2026-05-14 11:20:03 +03:00
parent 5d07696101
commit a276db50f8
6 changed files with 227 additions and 25 deletions

View file

@ -53,6 +53,7 @@
#include "input-timestamps-unstable-v1-server-protocol.h"
#include "tablet-unstable-v2-server-protocol.h"
#include "timeline.h"
#include "weston-trace.h"
enum pointer_constraint_type {
POINTER_CONSTRAINT_TYPE_LOCK,
@ -565,13 +566,34 @@ pointer_send_relative_motion(struct weston_pointer *pointer,
struct wl_list *resource_list;
struct wl_resource *resource;
if (!pointer->focus_client)
if (!pointer->focus_client) {
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("discard relative pointer motion",
"missing focus client"),
("internal_name", pointer->focus->internal_name),
("label", pointer->focus->surface->label),
("pointer sx", pointer->sx),
("pointer sy", pointer->sy));
return;
}
if (!weston_pointer_motion_to_rel(pointer, event,
&rel,
&rel_unaccel))
if (!weston_pointer_motion_to_rel(pointer, event, &rel, &rel_unaccel)) {
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("discard relative pointer motion",
"invalid relative data"),
("internal_name", pointer->focus->internal_name),
("label", pointer->focus->surface->label),
("pointer sx", pointer->sx),
("pointer sy", pointer->sy));
return;
}
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("send", "relative pointer motion"),
("internal_name", pointer->focus->internal_name),
("label", pointer->focus->surface->label),
("pointer sx", pointer->sx),
("pointer sy", pointer->sy));
resource_list = &pointer->focus_client->relative_pointer_resources;
time_usec = timespec_to_usec(&event->base.ts);
@ -589,9 +611,8 @@ pointer_send_relative_motion(struct weston_pointer *pointer,
}
static void
pointer_send_motion(struct weston_pointer *pointer,
const struct timespec *ts,
wl_fixed_t sx, wl_fixed_t sy)
pointer_send_motion(struct weston_pointer *pointer, wl_fixed_t sx, wl_fixed_t sy,
const struct weston_pointer_motion_event *event)
{
struct wl_list *resource_list;
struct wl_resource *resource;
@ -600,12 +621,19 @@ pointer_send_motion(struct weston_pointer *pointer,
if (!pointer->focus_client)
return;
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("send", "relative pointer motion"),
("internal_name", pointer->focus->internal_name),
("label", pointer->focus->surface->label),
("pointer sx", sx),
("pointer sy", sy));
resource_list = &pointer->focus_client->pointer_resources;
msecs = timespec_to_msec(ts);
msecs = timespec_to_msec(&event->base.ts);
wl_resource_for_each(resource, resource_list) {
send_timestamps_for_input_resource(resource,
&pointer->timestamps_list,
ts);
&event->base.ts);
wl_pointer_send_motion(resource, msecs, sx, sy);
}
}
@ -614,6 +642,8 @@ WL_EXPORT void
weston_pointer_send_motion(struct weston_pointer *pointer,
const struct weston_pointer_motion_event *event)
{
WESTON_TRACE_FUNC_FLOW(&event->base.flow_id);
wl_fixed_t old_sx;
wl_fixed_t old_sy;
struct weston_view *old_focus = pointer->focus;
@ -640,7 +670,7 @@ weston_pointer_send_motion(struct weston_pointer *pointer,
if (pointer->focus && old_focus == pointer->focus &&
(old_sx != pointer->sx || old_sy != pointer->sy)) {
pointer_send_motion(pointer, &event->base.ts, pointer->sx, pointer->sy);
pointer_send_motion(pointer, pointer->sx, pointer->sy, event);
}
pointer_send_relative_motion(pointer, event);
@ -692,8 +722,20 @@ weston_pointer_send_button(struct weston_pointer *pointer,
uint32_t button = button_event->button;
enum wl_pointer_button_state state = button_event->button_state;
if (!weston_pointer_has_focus_resource(pointer))
if (!weston_pointer_has_focus_resource(pointer)) {
WESTON_TRACE_ANNOTATE_FUNC_FLOW(button_event->base.flow_id,
("discard button", "missing focus resource"),
("state", button_event->button_state),
("button", button_event->button));
return;
}
WESTON_TRACE_ANNOTATE_FUNC_FLOW(button_event->base.flow_id,
("send", "button"),
("internal_name", pointer->focus->internal_name),
("label", pointer->focus->surface->label),
("state", button_event->button_state),
("button", button_event->button));
resource_list = &pointer->focus_client->pointer_resources;
serial = wl_display_next_serial(display);
@ -743,8 +785,24 @@ weston_pointer_send_axis(struct weston_pointer *pointer,
struct wl_list *resource_list;
uint32_t msecs;
if (!weston_pointer_has_focus_resource(pointer))
if (!weston_pointer_has_focus_resource(pointer)) {
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("discard axis", "missing focus resource"),
("axis", event->axis),
("value", event->value),
("has_discrete", event->has_discrete),
("discrete", event->discrete));
return;
}
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("send", "axis"),
("internal_name", pointer->focus->internal_name),
("label", pointer->focus->surface->label),
("axis", event->axis),
("value", event->value),
("has_discrete", event->has_discrete),
("discrete", event->discrete));
resource_list = &pointer->focus_client->pointer_resources;
msecs = timespec_to_msec(&event->base.ts);
@ -904,12 +962,28 @@ weston_touch_send_down(const struct weston_touch_event *event)
struct weston_coord_surface surf_pos;
uint32_t msecs;
if (!weston_touch_has_focus_resource(touch))
if (!weston_touch_has_focus_resource(touch)) {
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("discard touch down", "missing focus resource"),
("touch pos x", event->pos.c.x),
("touch pos y", event->pos.c.y),
("touch id", event->touch_id));
return;
}
surf_pos = weston_coord_global_to_surface(touch->focus, event->pos);
weston_view_update_transform(touch->focus);
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("send", "touch down"),
("internal_name", touch->focus->internal_name),
("label", touch->focus->surface->label),
("touch pos x", event->pos.c.x),
("touch pos y", event->pos.c.y),
("surface pos x", surf_pos.c.x),
("surface pos y", surf_pos.c.y),
("touch id", event->touch_id));
resource_list = &touch->focus_resource_list;
serial = wl_display_next_serial(display);
msecs = timespec_to_msec(&event->base.ts);
@ -949,8 +1023,18 @@ weston_touch_send_up(const struct weston_touch_event *event)
struct wl_list *resource_list;
uint32_t msecs;
if (!weston_touch_has_focus_resource(touch))
if (!weston_touch_has_focus_resource(touch)) {
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("discard touch up", "missing focus resource"),
("touch id", event->touch_id));
return;
}
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("send", "touch up"),
("internal_name", touch->focus->internal_name),
("label", touch->focus->surface->label),
("touch id", event->touch_id));
resource_list = &touch->focus_resource_list;
serial = wl_display_next_serial(display);
@ -986,12 +1070,26 @@ weston_touch_send_motion(const struct weston_touch_event *event)
struct weston_coord_surface surf_pos;
struct weston_touch *touch = event->base.seat->touch_state;
if (!weston_touch_has_focus_resource(touch))
if (!weston_touch_has_focus_resource(touch)) {
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("discard touch motion", "missing focus resource"),
("touch pos x", event->pos.c.x),
("touch pos y", event->pos.c.y),
("touch id", event->touch_id));
return;
}
surf_pos = weston_coord_global_to_surface(touch->focus, event->pos);
weston_view_update_transform(touch->focus);
WESTON_TRACE_ANNOTATE_FUNC_FLOW(event->base.flow_id,
("send", "touch motion"),
("internal_name", touch->focus->internal_name),
("label", touch->focus->surface->label),
("touch pos x", event->pos.c.x),
("touch pos y", event->pos.c.y),
("touch id", event->touch_id));
resource_list = &touch->focus_resource_list;
msecs = timespec_to_msec(&event->base.ts);
wl_resource_for_each(resource, resource_list) {
@ -1089,12 +1187,27 @@ weston_keyboard_send_key(struct weston_keyboard *keyboard,
uint32_t key = key_event->key;
enum wl_keyboard_key_state state = key_event->key_state;
if (!weston_keyboard_has_focus_resource(keyboard))
if (!weston_keyboard_has_focus_resource(keyboard)) {
WESTON_TRACE_ANNOTATE_FUNC_FLOW(key_event->base.flow_id,
("discard send key", "missing touch resource"),
("key", key),
("state", state),
("update state", key_event->key_update_state));
return;
}
resource_list = &keyboard->focus_resource_list;
serial = wl_display_next_serial(display);
msecs = timespec_to_msec(&time);
WESTON_TRACE_ANNOTATE_FUNC_FLOW(key_event->base.flow_id,
("send", "key"),
("internal_name", keyboard->focus->internal_name),
("label", keyboard->focus->label),
("key", key),
("state", state),
("update state", key_event->key_update_state));
wl_resource_for_each(resource, resource_list) {
send_timestamps_for_input_resource(resource,
&keyboard->timestamps_list,
@ -5650,6 +5763,8 @@ static void
confined_pointer_grab_pointer_motion(struct weston_pointer_grab *grab,
const struct weston_pointer_motion_event *event)
{
WESTON_TRACE_FUNC_FLOW(&event->base.flow_id);
struct weston_pointer_constraint *constraint =
container_of(grab, struct weston_pointer_constraint, grab);
struct weston_pointer *pointer = grab->pointer;
@ -5679,7 +5794,7 @@ confined_pointer_grab_pointer_motion(struct weston_pointer_grab *grab,
pointer->sy = wl_fixed_from_double(surf_pos.c.y);
if (old_sx != pointer->sx || old_sy != pointer->sy) {
pointer_send_motion(pointer, &event->base.ts, pointer->sx, pointer->sy);
pointer_send_motion(pointer, pointer->sx, pointer->sy, event);
}
pointer_send_relative_motion(pointer, event);

View file

@ -73,6 +73,33 @@ perfetto_annotate_int(struct weston_debug_annotations *annots,
do_annotate_int(annots, annots->count, key, key_size, value);
}
static void
do_annotate_bool(struct weston_debug_annotations *annots,
unsigned char parent,
const char *key,
unsigned char key_size, bool value)
{
weston_assert_u8_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, annots->count);
struct weston_debug_annotation *annot = &annots->annots[annots->count];
annot->type = WESTON_DEBUG_ANNOTATION_STR_VAL;
annot->svalue = value ? " true" : "false";
annot->parent = parent;
annot->key = key;
annot->key_size = key_size;
annots->count++;
}
WL_EXPORT void
perfetto_annotate_bool(struct weston_debug_annotations *annots,
const char *key,
unsigned char key_size,
bool value)
{
do_annotate_bool(annots, annots->count, key, key_size, value);
}
static void
do_annotate_float(struct weston_debug_annotations *annots,
unsigned char parent,
@ -101,6 +128,30 @@ perfetto_annotate_float(struct weston_debug_annotations *annots,
do_annotate_float(annots, annots->count, key, key_size, value);
}
static void
do_annotate_double(struct weston_debug_annotations *annots,
unsigned char parent, const char *key,
unsigned char key_size, double value)
{
weston_assert_u8_gt(NULL, WESTON_MAX_DEBUG_ANNOTS, annots->count);
struct weston_debug_annotation *annot = &annots->annots[annots->count];
annot->type = WESTON_DEBUG_ANNOTATION_DOUBLE_VAL;
annot->fvalue = value;
annot->parent = parent;
annot->key = key;
annot->key_size = key_size;
annots->count++;
}
WL_EXPORT void
perfetto_annotate_double(struct weston_debug_annotations *annots,
const char *key, unsigned char key_size,
double value)
{
do_annotate_double(annots, annots->count, key, key_size, value);
}
static void
do_annotate_string(struct weston_debug_annotations *annots,
unsigned char parent,

View file

@ -35,11 +35,22 @@ perfetto_annotate_int(struct weston_debug_annotations *annots,
unsigned char key_size,
int value);
void
perfetto_annotate_bool(struct weston_debug_annotations *annots,
const char *key,
unsigned char key_size,
bool value);
void
perfetto_annotate_float(struct weston_debug_annotations *annots,
const char *key,
unsigned char key_size,
float value);
void
perfetto_annotate_double(struct weston_debug_annotations *annots,
const char *key,
unsigned char key_size,
double value);
void
perfetto_annotate_string(struct weston_debug_annotations *annots,

View file

@ -241,6 +241,12 @@ util_perfetto_flush_debug_annotation(perfetto::EventContext *ctx,
else
ctx->AddDebugAnnotation(key, annot->fvalue);
break;
case WESTON_DEBUG_ANNOTATION_DOUBLE_VAL:
if (use_built_key)
ctx->AddDebugAnnotation(perfetto::DynamicString(key), annot->dvalue);
else
ctx->AddDebugAnnotation(key, annot->dvalue);
break;
case WESTON_DEBUG_ANNOTATION_STR_VAL:
if (use_built_key)
ctx->AddDebugAnnotation(perfetto::DynamicString(key), annot->svalue);

View file

@ -40,9 +40,10 @@ extern "C" {
#endif
enum weston_debug_annotation_type {
WESTON_DEBUG_ANNOTATION_INT_VAL,
WESTON_DEBUG_ANNOTATION_FLOAT_VAL,
WESTON_DEBUG_ANNOTATION_STR_VAL,
WESTON_DEBUG_ANNOTATION_INT_VAL,
WESTON_DEBUG_ANNOTATION_FLOAT_VAL,
WESTON_DEBUG_ANNOTATION_DOUBLE_VAL,
WESTON_DEBUG_ANNOTATION_STR_VAL,
WESTON_DEBUG_ANNOTATION_CONTAINER,
};
@ -51,6 +52,7 @@ struct weston_debug_annotation {
union {
int ivalue;
float fvalue;
double dvalue;
const char *svalue;
};
unsigned char type;

View file

@ -35,7 +35,7 @@
#define WESTON_MAX_DEBUG_ANNOTS 128
/* maximum key length */
#define WESTON_TRACE_MAX_KEY_LENGTH 30
#define WESTON_TRACE_MAX_KEY_LENGTH 40
/* note that util_perfetto_is_tracing_enabled always returns false until
* util_perfetto_init is called
@ -90,8 +90,10 @@
static_assert(sizeof(k) < WESTON_TRACE_MAX_KEY_LENGTH); \
_Generic((v), \
int: perfetto_annotate_int, \
bool: perfetto_annotate_bool, \
unsigned int: perfetto_annotate_int, \
float: perfetto_annotate_float, \
double: perfetto_annotate_double, \
char *: perfetto_annotate_string, \
const char *: perfetto_annotate_string, \
struct weston_buffer *: perfetto_annotate_buffer, \
@ -190,10 +192,13 @@
__attribute__((cleanup(_weston_trace_scope_end), unused)) = \
_weston_trace_annotate_func_begin(name, &__pd_annots)
#define _WESTON_TRACE_ANNOTATE_FUNC_FLOW(id, name) \
int _WESTON_TRACE_SCOPE_VAR(__LINE__) \
__attribute__((cleanup(_weston_trace_scope_end), unused)) = \
_weston_trace_annotate_func_begin_flow(name, id, &__pd_annots)
#define _WESTON_TRACE_ANNOTATE_FUNC_FLOW(id, name) \
int _WESTON_TRACE_SCOPE_VAR(__LINE__) \
__attribute__((cleanup(_weston_trace_scope_end), unused)) = \
_Generic((id), \
uint64_t *: _weston_trace_annotate_func_begin_flow, \
uint64_t : _weston_trace_annotate_func_begin_const_flow \
)(name, id, &__pd_annots)
static inline int
_weston_trace_scope_begin(const char *name)
@ -270,6 +275,18 @@ _weston_trace_instant_timestamp(const char *name, uint64_t track_id, uint64_t id
return 0;
}
static inline int
_weston_trace_annotate_func_begin_const_flow(const char *name, uint64_t id,
struct weston_debug_annotations *annots)
{
weston_assert_u64_gt(NULL, id, 0);
_WESTON_TRACE_ANNOTATE_FUNC_BEGIN_FLOW(name, id, annots);
annots->count = 0;
return 0;
}
static inline void
_weston_trace_scope_end(int *scope)
{