From 41c25aac6384e6e429a51ace166fffcf219efeca Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Mon, 12 Oct 2026 15:23:19 +0300 Subject: Unify surface input queue, frame clock, and optimize scaling and timers --- src/common/backend.c | 29 ++++++++++++++++++++++------- src/common/backend.h | 5 +++++ src/common/loop.c | 17 ++++++++++------- 3 files changed, 37 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/common/backend.c b/src/common/backend.c index cab1dce..ccb9c27 100644 --- a/src/common/backend.c +++ b/src/common/backend.c @@ -179,6 +179,7 @@ void yasl_surface_destroy(struct yasl_surface *s) if (!s || !s->display->ops->surface_destroy) return; yasl_surface_clear_timers(s); + input_queue_clear(&s->input); s->display->ops->surface_destroy(s); } @@ -244,9 +245,11 @@ bool yasl_surface_present(struct yasl_surface *s, const struct yasl_framebuffer bool yasl_surface_input_poll(struct yasl_surface *s, struct yasl_input_event *ev) { - if (!s || !ev || !s->display->ops->surface_input_poll) - return 0; - return s->display->ops->surface_input_poll(s, ev); + if (!s || !ev) + return false; + if (s->display && s->display->ops && s->display->ops->surface_input_poll) + return s->display->ops->surface_input_poll(s, ev); + return input_queue_pop(&s->input, ev); } struct yasl_geometry yasl_surface_geometry(const struct yasl_surface *s) @@ -269,16 +272,28 @@ uint32_t yasl_surface_state(const struct yasl_surface *s) struct yasl_timing yasl_surface_timing(const struct yasl_surface *s) { - if (!s || !s->display->ops->surface_timing) + if (!s) return (struct yasl_timing){0}; - return s->display->ops->surface_timing(s); + if (s->display && s->display->ops && s->display->ops->surface_timing) + return s->display->ops->surface_timing(s); + struct yasl_timing t = { + .refresh_ns = s->clock.refresh_ns, + .last_present_ns = s->clock.last_present_ns, + .next_present_ns = yasl_clock_next_present_ns(&s->clock), + .frames_skipped = s->frames_skipped, + .source = s->clock.source, + }; + yasl_clock_resize_stats(&s->clock, &t.resize); + return t; } uint64_t yasl_surface_frame_time_ns(struct yasl_surface *s, uint64_t now) { - if (!s || !s->display->ops->surface_frame_time_ns) + if (!s) return 0; - return s->display->ops->surface_frame_time_ns(s, now); + if (s->display && s->display->ops && s->display->ops->surface_frame_time_ns) + return s->display->ops->surface_frame_time_ns(s, now); + return yasl_clock_frame_timestamp_ns(&s->clock, now); } void yasl_surface_set_cursor(struct yasl_surface *s, enum yasl_cursor cursor) diff --git a/src/common/backend.h b/src/common/backend.h index e1d29c5..6014cda 100644 --- a/src/common/backend.h +++ b/src/common/backend.h @@ -4,6 +4,8 @@ #include "yasl/yasl.h" #include "yasl/loop.h" #include "yasl/native.h" +#include "common/input.h" +#include "common/timing.h" struct yasl_backend_ops; @@ -24,6 +26,9 @@ struct yasl_surface { struct yasl_surface_cbs callbacks; void *ud; uint64_t frame_generation; + struct input_queue input; + struct yasl_frame_clock clock; + uint64_t frames_skipped; yasl_timer_id *timers; int timer_count; int timer_capacity; diff --git a/src/common/loop.c b/src/common/loop.c index 18d62b1..1c6a612 100644 --- a/src/common/loop.c +++ b/src/common/loop.c @@ -199,11 +199,9 @@ static void timer_cleanup_deleted(struct yasl_loop *l) if (!l || l->timer_firing_depth > 0) return; int dest = 0; for (int src = 0; src < l->timer_count; src++) { - if (!l->timers[src].deleted) { - if (dest != src) - l->timers[dest] = l->timers[src]; - dest++; - } + struct yasl_timer_source t = l->timers[src]; + l->timers[dest] = t; + dest += !t.deleted; } l->timer_count = dest; } @@ -270,11 +268,16 @@ yasl_timer_id yasl_loop_add_timer(struct yasl_loop *l, uint64_t interval_ns, bool yasl_loop_del_timer(struct yasl_loop *l, yasl_timer_id id) { if (!l || id == 0) return false; - for (int i = 0; i < l->timer_count; i++) { + for (int i = l->timer_count - 1; i >= 0; i--) { if (l->timers[i].id == id && !l->timers[i].deleted) { l->timers[i].deleted = true; if (l->timer_firing_depth == 0) { - timer_cleanup_deleted(l); + if (i == l->timer_count - 1) { + while (l->timer_count > 0 && l->timers[l->timer_count - 1].deleted) + l->timer_count--; + } else { + timer_cleanup_deleted(l); + } } return true; } -- cgit v1.2.3