summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/backend.c103
-rw-r--r--src/common/backend.h13
-rw-r--r--src/common/loop.c59
-rw-r--r--src/common/loop.h8
-rw-r--r--src/common/meson.build2
-rw-r--r--src/common/native.c35
-rw-r--r--src/common/timing.c7
-rw-r--r--src/common/timing.h28
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 */