diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-12 14:27:51 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-12 14:27:51 +0300 |
| commit | 9ed89c17dee752154c36d71cae93d20cccfc71ef (patch) | |
| tree | a32cd894643ff6f6ebce83dd745bd24b35eb6520 /src/wayland/pointer.c | |
| parent | aedd863e6f66fd446227e9b107bc9c1970092634 (diff) | |
perf: optimize hot-path loops, data structures, and cache locality
Diffstat (limited to 'src/wayland/pointer.c')
| -rw-r--r-- | src/wayland/pointer.c | 66 |
1 files changed, 31 insertions, 35 deletions
diff --git a/src/wayland/pointer.c b/src/wayland/pointer.c index 5924eb1..065669f 100644 --- a/src/wayland/pointer.c +++ b/src/wayland/pointer.c @@ -248,8 +248,9 @@ static void press_queue_flush(struct seat *s, struct press_queue *q, struct yasl_mouse_event like) { int kept = 0; - for (int i = 0; i < q->n; i++) { - struct pending_press p = q->ev[i]; + int count = q->n; + for (int i = 0; i < count; i++) { + struct pending_press p = q->ev[(q->head + i) & 7]; if (only && p.surface != only) { q->ev[kept++] = p; continue; @@ -263,26 +264,30 @@ static void press_queue_flush(struct seat *s, struct press_queue *q, ev.kind = (enum yasl_pointer_kind)p.release; push_mouse(s, p.surface, ev); } + q->head = 0; q->n = kept; } static void press_queue_push(struct press_queue *q, struct wayland_surface *w, struct yasl_vector2i pos, int button, bool release) { - if (q->n == (int)(sizeof(q->ev) / sizeof(q->ev[0]))) { - memmove(q->ev, q->ev + 1, sizeof(q->ev[0]) * (size_t)(q->n - 1)); + if (q->n == 8) { + q->head = (q->head + 1) & 7; q->n--; } - q->ev[q->n++] = (struct pending_press){ + q->ev[(q->head + q->n) & 7] = (struct pending_press){ .surface = w, .pos = pos, .button = button, .release = release, }; + q->n++; } static void press_queue_forget(struct press_queue *q, struct wayland_surface *w) { - for (int i = 0; i < q->n; i++) - if (q->ev[i].surface == w) - q->ev[i].surface = NULL; + for (int i = 0; i < q->n; i++) { + int idx = (q->head + i) & 7; + if (q->ev[idx].surface == w) + q->ev[idx].surface = NULL; + } } void seat_pointer_reset(struct seat *s) @@ -566,28 +571,7 @@ static struct yasl_vector2i touch_pos(const struct touch_point *p) }; } -static int touch_count(const struct seat *s) -{ - int n = 0; - for (int i = 0; i < SEAT_TOUCH_POINTS; i++) - if (s->touch_points[i].active && !s->touch_points[i].up) - n++; - return n; -} -static double touch_centroid_y(const struct seat *s, const struct wayland_surface *on) -{ - double sum = 0; - int n = 0; - for (int i = 0; i < SEAT_TOUCH_POINTS; i++) { - const struct touch_point *p = &s->touch_points[i]; - if (p->active && !p->up && p->surface == on) { - sum += p->y; - n++; - } - } - return n ? sum / n : 0; -} static void touch_report(struct seat *s, struct touch_point *p, int button, enum yasl_pointer_kind kind) @@ -641,24 +625,35 @@ static void touch_frame(void *data, struct wl_touch *touch) { (void)touch; struct seat *s = data; + int active_n = 0; + double centroid_sum = 0; + int centroid_n = 0; for (int i = 0; i < SEAT_TOUCH_POINTS; i++) { struct touch_point *p = &s->touch_points[i]; - if (p->active && p->down && !s->touch_primary && !s->touch_scrolling) { + if (!p->active) continue; + if (p->down && !s->touch_primary && !s->touch_scrolling) { s->touch_primary = p; s->touch_pressed = true; touch_report(s, p, 0, YASL_PTR_PRESS); } + if (!p->up) { + active_n++; + if (s->touch_primary && p->surface == s->touch_primary->surface) { + centroid_sum += p->y; + centroid_n++; + } + } } struct touch_point *primary = s->touch_primary; - if (primary && !s->touch_scrolling && touch_count(s) >= 2) { + if (primary && !s->touch_scrolling && active_n >= 2) { if (s->touch_pressed) touch_report(s, primary, 0, YASL_PTR_RELEASE); s->touch_pressed = false; s->touch_scrolling = true; - s->touch_scroll_y = touch_centroid_y(s, primary->surface); + s->touch_scroll_y = centroid_n ? centroid_sum / centroid_n : 0; s->touch_scroll_rest = 0; - } else if (s->touch_scrolling && primary && touch_count(s) >= 2) { - double y = touch_centroid_y(s, primary->surface); + } else if (s->touch_scrolling && primary && active_n >= 2) { + double y = centroid_n ? centroid_sum / centroid_n : 0; double dy = y - s->touch_scroll_y; s->touch_scroll_y = y; if (dy != 0.0) { @@ -679,6 +674,7 @@ static void touch_frame(void *data, struct wl_touch *touch) struct touch_point *p = &s->touch_points[i]; if (!p->active) continue; if (p->up) { + active_n--; if (p == s->touch_primary) { if (s->touch_pressed) touch_report(s, p, 0, YASL_PTR_RELEASE); @@ -690,7 +686,7 @@ static void touch_frame(void *data, struct wl_touch *touch) p->down = p->moved = false; } } - if (!touch_count(s)) + if (active_n <= 0) s->touch_scrolling = false; } |
