diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/backend.c | 103 | ||||
| -rw-r--r-- | src/common/backend.h | 13 | ||||
| -rw-r--r-- | src/common/loop.c | 59 | ||||
| -rw-r--r-- | src/common/loop.h | 8 | ||||
| -rw-r--r-- | src/common/meson.build | 2 | ||||
| -rw-r--r-- | src/common/native.c | 35 | ||||
| -rw-r--r-- | src/common/timing.c | 7 | ||||
| -rw-r--r-- | src/common/timing.h | 28 |
8 files changed, 101 insertions, 154 deletions
diff --git a/src/common/backend.c b/src/common/backend.c index 27ab297..ad4d908 100644 --- a/src/common/backend.c +++ b/src/common/backend.c @@ -78,22 +78,11 @@ uint32_t yasl_display_caps(const struct yasl_display *d) return d->ops->display_caps(d); } -void yasl_display_dispatch(struct yasl_display *d) -{ - if (!d || !d->ops->display_dispatch) - return; - d->ops->display_dispatch(d); -} - -int yasl_display_dispatch_timeout(struct yasl_display *d, int timeout_ms) +int yasl_display_dispatch(struct yasl_display *d, int timeout_ms) { if (!d) return -1; if (d->ops->display_dispatch_timeout) return d->ops->display_dispatch_timeout(d, timeout_ms); - if (d->ops->display_dispatch) { - d->ops->display_dispatch(d); - return 0; - } return -1; } @@ -147,7 +136,8 @@ void yasl_display_drag_cancel(struct yasl_display *d) d->ops->display_drag_cancel(d); } -struct yasl_surface *yasl_surface_create_toplevel(struct yasl_display *d, const struct yasl_surface_spec *spec) +struct yasl_surface *yasl_create_toplevel(struct yasl_display *d, + const struct yasl_surface_spec *spec, void *graphics_device) { if (!d || !d->ops->surface_create_toplevel || !spec || spec->size.x <= 0 || spec->size.y <= 0 || @@ -156,11 +146,17 @@ struct yasl_surface *yasl_surface_create_toplevel(struct yasl_display *d, const errno = EINVAL; return NULL; } - if (spec->graphics_device && !(yasl_display_caps(d) & YASL_CAP_NATIVE_GRAPHICS)) { + if (graphics_device && !(yasl_display_caps(d) & YASL_CAP_NATIVE_GRAPHICS)) { errno = ENOTSUP; return NULL; } - return d->ops->surface_create_toplevel(d, spec); + return d->ops->surface_create_toplevel(d, spec, graphics_device); +} + +struct yasl_surface *yasl_surface_create_toplevel(struct yasl_display *d, + const struct yasl_surface_spec *spec) +{ + return yasl_create_toplevel(d, spec, NULL); } struct yasl_surface *yasl_surface_create_popup(struct yasl_surface *parent, const struct yasl_popup_spec *spec) @@ -247,18 +243,11 @@ bool yasl_surface_input_poll(struct yasl_surface *s, struct yasl_input_event *ev return s->display->ops->surface_input_poll(s, ev); } -struct yasl_vector2i yasl_surface_size(const struct yasl_surface *s) -{ - if (!s || !s->display->ops->surface_size) - return (struct yasl_vector2i){0}; - return s->display->ops->surface_size(s); -} - -uint32_t yasl_surface_scale_120(const struct yasl_surface *s) +struct yasl_geometry yasl_surface_geometry(const struct yasl_surface *s) { - if (!s || !s->display->ops->surface_scale_120) - return YASL_SCALE_UNIT; - return s->display->ops->surface_scale_120(s); + if (!s || !s->display->ops->surface_geometry) + return (struct yasl_geometry){.scale_120 = YASL_SCALE_UNIT}; + return s->display->ops->surface_geometry(s); } uint32_t yasl_surface_state(const struct yasl_surface *s) @@ -356,20 +345,6 @@ bool yasl_surface_place_under_pointer(struct yasl_surface *s, struct yasl_vector return s->display->ops->surface_place_under_pointer(s, at); } -void *yasl_display_get_native_handle(struct yasl_display *d) -{ - if (!d || !d->ops->display_get_native_handle) - return 0; - return d->ops->display_get_native_handle(d); -} - -void *yasl_surface_get_native_handle(struct yasl_surface *s) -{ - if (!s || !s->display->ops->surface_get_native_handle) - return 0; - return s->display->ops->surface_get_native_handle(s); -} - void yasl_surface_clear_timers(struct yasl_surface *s) { if (!s || !s->timers) return; @@ -408,29 +383,6 @@ yasl_timer_id yasl_surface_add_timer(struct yasl_surface *s, uint64_t interval_n return id; } -yasl_timer_id yasl_surface_add_timer_ms(struct yasl_surface *s, uint32_t interval_ms, - yasl_timer_ms_cb cb, void *ud) -{ - if (!s || !s->display || !s->display->loop || !cb || interval_ms == 0) - return 0; - - yasl_timer_id id = yasl_loop_add_timer_ms(s->display->loop, interval_ms, cb, ud); - if (!id) return 0; - - if (s->timer_count >= s->timer_capacity) { - int new_cap = s->timer_capacity ? s->timer_capacity * 2 : 4; - yasl_timer_id *nt = realloc(s->timers, (size_t)new_cap * sizeof(*nt)); - if (!nt) { - yasl_loop_del_timer(s->display->loop, id); - return 0; - } - s->timers = nt; - s->timer_capacity = new_cap; - } - s->timers[s->timer_count++] = id; - return id; -} - bool yasl_surface_del_timer(struct yasl_surface *s, yasl_timer_id id) { if (!s || id == 0) return false; @@ -445,32 +397,7 @@ bool yasl_surface_del_timer(struct yasl_surface *s, yasl_timer_id id) return false; } -yasl_timer_id yasl_display_add_timer(struct yasl_display *d, uint64_t interval_ns, - yasl_timer_cb cb, void *ud) -{ - if (!d || !d->loop) return 0; - return yasl_loop_add_timer(d->loop, interval_ns, cb, ud); -} - -yasl_timer_id yasl_display_add_timer_ms(struct yasl_display *d, uint32_t interval_ms, - yasl_timer_ms_cb cb, void *ud) -{ - if (!d || !d->loop) return 0; - return yasl_loop_add_timer_ms(d->loop, interval_ms, cb, ud); -} - -bool yasl_display_del_timer(struct yasl_display *d, yasl_timer_id id) -{ - if (!d || !d->loop) return false; - return yasl_loop_del_timer(d->loop, id); -} - struct yasl_loop *yasl_display_loop(struct yasl_display *d) { return d ? d->loop : NULL; } - -struct yasl_loop *yasl_surface_loop(struct yasl_surface *s) -{ - return (s && s->display) ? s->display->loop : NULL; -} diff --git a/src/common/backend.h b/src/common/backend.h index b52a147..6ab7248 100644 --- a/src/common/backend.h +++ b/src/common/backend.h @@ -2,6 +2,8 @@ #define YASL_BACKEND_H #include "yasl/yasl.h" +#include "yasl/loop.h" +#include "yasl/native.h" struct yasl_backend_ops; @@ -21,6 +23,8 @@ struct yasl_surface { }; void yasl_surface_clear_timers(struct yasl_surface *s); +struct yasl_surface *yasl_create_toplevel(struct yasl_display *d, + const struct yasl_surface_spec *spec, void *graphics_device); static inline uint64_t yasl_frame_begin(struct yasl_surface *s) { @@ -33,7 +37,6 @@ struct yasl_backend_ops { struct yasl_display *(*display_open)(struct yasl_loop *loop, const struct yasl_display_spec *spec); void (*display_close)(struct yasl_display *d); uint32_t (*display_caps)(const struct yasl_display *d); - void (*display_dispatch)(struct yasl_display *d); int (*display_dispatch_timeout)(struct yasl_display *d, int timeout_ms); void (*display_flush)(struct yasl_display *d); int (*display_modifiers)(const struct yasl_display *d); @@ -41,7 +44,8 @@ struct yasl_backend_ops { void (*display_paste)(struct yasl_display *d, enum yasl_selection sel, struct yasl_surface *target); bool (*display_drag_start)(struct yasl_display *d, struct yasl_surface *origin, const struct yasl_drag_image *image, const struct yasl_drag_listener *l, void *ud); void (*display_drag_cancel)(struct yasl_display *d); - struct yasl_surface *(*surface_create_toplevel)(struct yasl_display *d, const struct yasl_surface_spec *spec); + struct yasl_surface *(*surface_create_toplevel)(struct yasl_display *d, + const struct yasl_surface_spec *spec, void *graphics_device); struct yasl_surface *(*surface_create_popup)(struct yasl_surface *parent, const struct yasl_popup_spec *spec); bool (*surface_popup_reposition)(struct yasl_surface *popup, const struct yasl_popup_spec *spec); void (*surface_destroy)(struct yasl_surface *s); @@ -51,8 +55,7 @@ struct yasl_backend_ops { void (*surface_schedule_redraw)(struct yasl_surface *s); bool (*surface_present)(struct yasl_surface *s, const struct yasl_framebuffer *fb, const struct yasl_damage_list *damage); bool (*surface_input_poll)(struct yasl_surface *s, struct yasl_input_event *ev); - struct yasl_vector2i (*surface_size)(const struct yasl_surface *s); - uint32_t (*surface_scale_120)(const struct yasl_surface *s); + struct yasl_geometry (*surface_geometry)(const struct yasl_surface *s); uint32_t (*surface_state)(const struct yasl_surface *s); struct yasl_timing (*surface_timing)(const struct yasl_surface *s); uint64_t (*surface_frame_time_ns)(struct yasl_surface *s, uint64_t now); @@ -68,6 +71,8 @@ struct yasl_backend_ops { bool (*surface_place_under_pointer)(struct yasl_surface *s, struct yasl_vector2i at); void *(*display_get_native_handle)(struct yasl_display *d); void *(*surface_get_native_handle)(struct yasl_surface *s); + bool (*surface_get_native_frame)(struct yasl_surface *s, + const struct yasl_framebuffer *target, struct yasl_native_frame *out); }; #if YASL_HAS_WAYLAND diff --git a/src/common/loop.c b/src/common/loop.c index a1f2434..3815e91 100644 --- a/src/common/loop.c +++ b/src/common/loop.c @@ -1,6 +1,6 @@ #define _GNU_SOURCE #define _POSIX_C_SOURCE 200809L -#include "yasl/yasl.h" +#include "loop.h" #include <errno.h> #include <fcntl.h> @@ -23,16 +23,11 @@ struct yasl_fd_source { }; struct yasl_timer_source { - union { - yasl_timer_cb ns; - yasl_timer_ms_cb ms; - void *raw; - } fn; + yasl_timer_cb fn; void *ud; yasl_timer_id id; uint64_t interval_ns; uint64_t deadline_ns; - bool ms_mode; bool deleted; }; @@ -251,44 +246,11 @@ yasl_timer_id yasl_loop_add_timer(struct yasl_loop *l, uint64_t interval_ns, uint64_t now = yasl_loop_now_ns(); l->timers[l->timer_count++] = (struct yasl_timer_source){ - .fn.ns = cb, + .fn = cb, .ud = ud, .id = id, .interval_ns = interval_ns, .deadline_ns = now + interval_ns, - .ms_mode = false, - .deleted = false, - }; - - yasl_loop_kick(l); - return id; -} - -yasl_timer_id yasl_loop_add_timer_ms(struct yasl_loop *l, uint32_t interval_ms, - yasl_timer_ms_cb cb, void *ud) -{ - if (!l || !cb || interval_ms == 0) return 0; - - if (l->timer_count >= l->timer_capacity) { - int new_cap = l->timer_capacity ? l->timer_capacity * 2 : 16; - struct yasl_timer_source *new_timers = realloc(l->timers, (size_t)new_cap * sizeof(*new_timers)); - if (!new_timers) return 0; - l->timers = new_timers; - l->timer_capacity = new_cap; - } - - uint32_t id = l->next_timer_id++; - if (l->next_timer_id == 0) l->next_timer_id = 1; - - uint64_t now = yasl_loop_now_ns(); - uint64_t interval_ns = (uint64_t)interval_ms * 1000000ull; - l->timers[l->timer_count++] = (struct yasl_timer_source){ - .fn.ms = cb, - .ud = ud, - .id = id, - .interval_ns = interval_ns, - .deadline_ns = now + interval_ns, - .ms_mode = true, .deleted = false, }; @@ -390,18 +352,10 @@ int yasl_loop_step(struct yasl_loop *l, int timeout_ms) yasl_timer_id tid = l->timers[i].id; uint64_t interval = l->timers[i].interval_ns; - bool is_ms = l->timers[i].ms_mode; void *ud = l->timers[i].ud; struct yasl_timer_source timer_src = l->timers[i]; - uint64_t next_interval = 0; - if (is_ms) { - uint32_t old_ms = (uint32_t)(interval / 1000000ull); - uint32_t res_ms = timer_src.fn.ms(ud, tid, old_ms); - next_interval = (uint64_t)res_ms * 1000000ull; - } else { - next_interval = timer_src.fn.ns(ud, tid, interval); - } + uint64_t next_interval = timer_src.fn(ud, tid, interval); handled++; for (int j = 0; j < l->timer_count; j++) { @@ -443,8 +397,3 @@ void yasl_loop_quit(struct yasl_loop *l) { if (l) l->running = false; } - -bool yasl_loop_is_running(const struct yasl_loop *l) -{ - return l ? l->running : false; -} diff --git a/src/common/loop.h b/src/common/loop.h new file mode 100644 index 0000000..579fa2c --- /dev/null +++ b/src/common/loop.h @@ -0,0 +1,8 @@ +#ifndef YASL_COMMON_LOOP_H +#define YASL_COMMON_LOOP_H + +#include "yasl/loop.h" + +int yasl_loop_next_timeout_ms(const struct yasl_loop *l); + +#endif /* YASL_COMMON_LOOP_H */ diff --git a/src/common/meson.build b/src/common/meson.build index 5cfb187..ddd0194 100644 --- a/src/common/meson.build +++ b/src/common/meson.build @@ -1 +1 @@ -sources += files('backend.c', 'input.c', 'loop.c', 'timing.c', 'utf8.c') +sources += files('backend.c', 'input.c', 'loop.c', 'native.c', 'timing.c', 'utf8.c') diff --git a/src/common/native.c b/src/common/native.c new file mode 100644 index 0000000..2d9c06f --- /dev/null +++ b/src/common/native.c @@ -0,0 +1,35 @@ +#include "backend.h" + +#include <errno.h> + +void *yasl_display_get_native_handle(struct yasl_display *d) +{ + return d && d->ops->display_get_native_handle ? + d->ops->display_get_native_handle(d) : NULL; +} + +void *yasl_surface_get_native_handle(struct yasl_surface *s) +{ + return s && s->display->ops->surface_get_native_handle ? + s->display->ops->surface_get_native_handle(s) : NULL; +} + +struct yasl_surface *yasl_surface_create_native(struct yasl_display *d, + const struct yasl_surface_spec *spec, void *graphics_device) +{ + if (!graphics_device) { + errno = EINVAL; + return NULL; + } + return yasl_create_toplevel(d, spec, graphics_device); +} + +bool yasl_surface_get_native_frame(struct yasl_surface *s, + const struct yasl_framebuffer *target, struct yasl_native_frame *out) +{ + if (!s || !target || !out || !target->generation || + target->generation != s->frame_generation || + !s->display->ops->surface_get_native_frame) + return false; + return s->display->ops->surface_get_native_frame(s, target, out); +} diff --git a/src/common/timing.c b/src/common/timing.c index 17f71b5..7a91327 100644 --- a/src/common/timing.c +++ b/src/common/timing.c @@ -1,4 +1,4 @@ -#include "yasl/timing.h" +#include "timing.h" uint64_t yasl_clock_extend_ms(uint32_t ms, uint64_t now_ns) { @@ -39,11 +39,6 @@ void yasl_clock_resize_stats(const struct yasl_frame_clock *c, out->minflt = c->resize_minflt; } -double yasl_clock_refresh_ms(const struct yasl_frame_clock *c) -{ - return c->refresh_ns / 1e6; -} - uint64_t yasl_clock_next_present_ns(const struct yasl_frame_clock *c) { uint64_t next = c->last_present_ns + (uint64_t)c->refresh_ns; diff --git a/src/common/timing.h b/src/common/timing.h new file mode 100644 index 0000000..a3c3c88 --- /dev/null +++ b/src/common/timing.h @@ -0,0 +1,28 @@ +#ifndef YASL_COMMON_TIMING_H +#define YASL_COMMON_TIMING_H + +#include "yasl/timing.h" +#include <stdbool.h> + +#define YASL_REFRESH_DEFAULT_NS 16666666.0 + +struct yasl_frame_clock { + uint64_t last_present_ns; + uint64_t resize_count; + uint64_t resize_sum_ns; + uint64_t resize_max_ns; + long resize_minflt; + uint64_t frame_time_ns; + double refresh_ns; + enum yasl_timing_source source; +}; + +uint64_t yasl_clock_extend_ms(uint32_t ms, uint64_t now_ns); +void yasl_clock_presented(struct yasl_frame_clock *c, uint64_t now, bool sample); +void yasl_clock_note_resize(struct yasl_frame_clock *c, uint64_t dt_ns); +void yasl_clock_resize_stats(const struct yasl_frame_clock *c, + struct yasl_resize_stats *out); +uint64_t yasl_clock_next_present_ns(const struct yasl_frame_clock *c); +uint64_t yasl_clock_frame_timestamp_ns(struct yasl_frame_clock *c, uint64_t now); + +#endif /* YASL_COMMON_TIMING_H */ |
