summaryrefslogtreecommitdiff
path: root/src/platform/wayland/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/wayland/buffer.c')
-rw-r--r--src/platform/wayland/buffer.c93
1 files changed, 51 insertions, 42 deletions
diff --git a/src/platform/wayland/buffer.c b/src/platform/wayland/buffer.c
index 874cc76..bbc055d 100644
--- a/src/platform/wayland/buffer.c
+++ b/src/platform/wayland/buffer.c
@@ -24,7 +24,7 @@ static const struct wl_buffer_listener buffer_listener;
int device_px(int logical, uint32_t scale_120)
{
- int64_t px = ((int64_t)logical * scale_120 + YASL_SCALE_UNIT / 2) / YASL_SCALE_UNIT;
+ int64_t px = ((int64_t)logical * scale_120 + YASL_PRIVATE_SCALE_UNIT / 2) / YASL_PRIVATE_SCALE_UNIT;
return px > 0 && px <= INT_MAX ? (int)px : -1;
}
@@ -58,7 +58,7 @@ int buffer_reserve(struct wayland_surface *w, struct buffer *b, size_t needed)
if (b->busy || needed > INT32_MAX) return -1;
size_t capacity = b->capacity <= INT32_MAX / 2 ? b->capacity * 2 : INT32_MAX;
if (capacity < needed) capacity = needed;
- int fd = memfd_create("yasl_surface_buffer", MFD_CLOEXEC | MFD_ALLOW_SEALING);
+ int fd = memfd_create("yasl_private_surface_buffer", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (fd < 0) return -1;
if (!fd_truncate(fd, capacity) ||
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_SEAL) < 0) {
@@ -89,7 +89,7 @@ int buffer_prepare(struct wayland_surface *w, struct buffer *b, int width, int h
{
if (b->proxy && !b->busy && b->width == width && b->height == height) return 0;
long faults_before = minor_faults();
- uint64_t t0 = yasl_loop_now_ns();
+ uint64_t t0 = yasl_private_loop_now_ns();
size_t bytes;
if (!buffer_size(width, height, &bytes) || buffer_reserve(w, b, bytes) < 0)
return -1;
@@ -104,7 +104,7 @@ int buffer_prepare(struct wayland_surface *w, struct buffer *b, int width, int h
b->busy = false;
b->presented = false;
wl_buffer_add_listener(proxy, listener, b);
- yasl_clock_note_resize(&w->clock, yasl_loop_now_ns() - t0);
+ yasl_private_clock_note_resize(&w->clock, yasl_private_loop_now_ns() - t0);
long faults = minor_faults() - faults_before;
if (faults > 0) w->clock.resize_minflt += faults;
return 0;
@@ -114,10 +114,10 @@ static void publish_surface_scale(struct wayland_surface *w)
{
if (w->viewport) {
wp_viewport_set_destination(w->viewport, w->logical_width, w->logical_height);
- } else if (w->scale_120 % YASL_SCALE_UNIT == 0 &&
+ } else if (w->scale_120 % YASL_PRIVATE_SCALE_UNIT == 0 &&
wl_proxy_get_version((struct wl_proxy *)w->surface) >=
WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) {
- wl_surface_set_buffer_scale(w->surface, (int32_t)(w->scale_120 / YASL_SCALE_UNIT));
+ wl_surface_set_buffer_scale(w->surface, (int32_t)(w->scale_120 / YASL_PRIVATE_SCALE_UNIT));
}
}
@@ -137,16 +137,16 @@ int apply_pending_geometry(struct wayland_surface *w)
return 0;
}
bool floating = !w->parent && !(w->base.state &
- (YASL_STATE_MAXIMIZED | YASL_STATE_FULLSCREEN | YASL_STATE_TILED));
+ (YASL_PRIVATE_STATE_MAXIMIZED | YASL_PRIVATE_STATE_FULLSCREEN | YASL_PRIVATE_STATE_TILED));
int free_w = floating && w->floating_width > 0 ? w->floating_width : w->logical_width;
int free_h = floating && w->floating_height > 0 ? w->floating_height : w->logical_height;
int logical_w = !w->parent && w->req_width > 0 ? w->req_width : free_w;
int logical_h = !w->parent && w->req_height > 0 ? w->req_height : free_h;
if (!w->parent) {
- if (logical_w < YASL_MIN_LOGICAL_PX) logical_w = YASL_MIN_LOGICAL_PX;
- if (logical_h < YASL_MIN_LOGICAL_PX) logical_h = YASL_MIN_LOGICAL_PX;
+ if (logical_w < YASL_PRIVATE_MIN_LOGICAL_PX) logical_w = YASL_PRIVATE_MIN_LOGICAL_PX;
+ if (logical_h < YASL_PRIVATE_MIN_LOGICAL_PX) logical_h = YASL_PRIVATE_MIN_LOGICAL_PX;
}
- if (!(w->base.state & YASL_STATE_FULLSCREEN)) {
+ if (!(w->base.state & YASL_PRIVATE_STATE_FULLSCREEN)) {
if (w->bound_width > 0 && logical_w > w->bound_width)
logical_w = w->bound_width;
if (w->bound_height > 0 && logical_h > w->bound_height)
@@ -155,7 +155,9 @@ int apply_pending_geometry(struct wayland_surface *w)
int width = device_px(logical_w, w->pending_scale_120);
int height = device_px(logical_h, w->pending_scale_120);
size_t bytes;
- if (!buffer_size(width, height, &bytes)) {
+ if (width <= 0 || height <= 0 ||
+ (w->base.presenter == YASL_PRIVATE_PRESENTER_CPU &&
+ !buffer_size(width, height, &bytes))) {
return -1;
}
bool rescaled = w->scale_120 != w->pending_scale_120;
@@ -169,13 +171,17 @@ int apply_pending_geometry(struct wayland_surface *w)
return 0;
w->scale_120 = w->pending_scale_120;
- w->scale_factor = (double)w->scale_120 / YASL_SCALE_UNIT;
+ w->scale_factor = (double)w->scale_120 / YASL_PRIVATE_SCALE_UNIT;
w->width = width;
w->height = height;
- w->base.size = (struct yasl_vector2i){width, height};
+ w->base.size = (struct yasl_private_vector2i){width, height};
w->base.scale_120 = w->scale_120;
w->logical_width = logical_w;
w->logical_height = logical_h;
+#if YASL_HAS_EGL
+ if (w->egl_window && (resized || rescaled))
+ wl_egl_window_resize(w->egl_window, width, height, 0, 0);
+#endif
surface_update_opaque_region(w);
if (resized || rescaled) {
for (int i = 0; i < NBUF; i++)
@@ -183,7 +189,7 @@ int apply_pending_geometry(struct wayland_surface *w)
}
publish_surface_scale(w);
if (resized || rescaled) {
- yasl_surface_notify_configure(&w->base, (struct yasl_geometry){
+ yasl_private_surface_notify_configure(&w->base, (struct yasl_private_geometry){
.size = { .x = width, .y = height }, .scale_120 = w->scale_120,
});
if (w->closed || w->destroyed)
@@ -225,7 +231,7 @@ void surface_follow_outputs(struct wayland_surface *w)
w->clock.refresh_ns = refresh;
if (need_scale)
- surface_request_scale(w, (uint32_t)max_scale * YASL_SCALE_UNIT);
+ surface_request_scale(w, (uint32_t)max_scale * YASL_PRIVATE_SCALE_UNIT);
}
static void surface_enter(void *data, struct wl_surface *surface, struct wl_output *output)
@@ -250,7 +256,7 @@ static void surface_preferred_scale(void *data, struct wl_surface *surface, int3
struct wayland_surface *w = data;
if (w->frac_scale || w->parent || factor <= 0)
return;
- surface_request_scale(w, (uint32_t)factor * YASL_SCALE_UNIT);
+ surface_request_scale(w, (uint32_t)factor * YASL_PRIVATE_SCALE_UNIT);
}
static void surface_preferred_transform(void *data, struct wl_surface *surface,
@@ -285,13 +291,15 @@ static void frame_done(void *data, struct wl_callback *cb, uint32_t ms)
wl_callback_destroy(cb);
w->frame_cb = NULL;
- uint64_t now = yasl_loop_now_ns();
+ uint64_t now = yasl_private_loop_now_ns();
if (!w->conn->pres_clock_known) {
- yasl_clock_presented(&w->clock, yasl_clock_extend_ms(ms, now), w->sample_refresh);
- w->clock.source = YASL_TIMING_FRAME_CALLBACK;
+ yasl_private_clock_presented(&w->clock, yasl_private_clock_extend_ms(ms, now), w->sample_refresh);
+ w->clock.source = YASL_PRIVATE_TIMING_FRAME_CALLBACK;
}
- if (w->want_draw)
+ if (w->base.presenter != YASL_PRIVATE_PRESENTER_CPU)
+ yasl_private_surface_notify_refresh(&w->base);
+ else if (w->want_draw)
wayland_surface_schedule_redraw(w);
}
@@ -299,14 +307,14 @@ static const struct wl_callback_listener frame_listener = {
.done = frame_done,
};
-static void arm_frame(struct wayland_surface *w)
+void wayland_surface_arm_frame(struct wayland_surface *w)
{
if (!w->configured || w->closed || w->frame_cb)
return;
w->frame_cb = wl_surface_frame(w->surface);
if (!w->frame_cb) { surface_fail(w); return; }
w->sample_refresh = w->clock.last_present_ns &&
- yasl_loop_now_ns() - w->clock.last_present_ns <
+ yasl_private_loop_now_ns() - w->clock.last_present_ns <
(uint64_t)(w->clock.refresh_ns / 2);
if (wl_callback_add_listener(w->frame_cb, &frame_listener, w) < 0) {
wl_callback_destroy(w->frame_cb);
@@ -365,7 +373,7 @@ static void presented(void *data, struct wp_presentation_feedback *fb,
(((uint64_t)tv_sec_hi << 32) | tv_sec_lo) * 1000000000ull + tv_nsec);
if (refresh) w->clock.refresh_ns = refresh;
w->clock.last_present_ns = ns;
- w->clock.source = YASL_TIMING_PRESENTATION;
+ w->clock.source = YASL_PRIVATE_TIMING_PRESENTATION;
}
(void)fb;
feedback_destroy(feedback);
@@ -419,7 +427,7 @@ static void commit_buffer(struct wayland_surface *w, int idx)
{
wl_surface_attach(w->surface, w->buffers[idx].proxy, 0, 0);
- const struct yasl_damage_list *d = &w->damage;
+ const struct yasl_private_damage_list *d = &w->damage;
if (d->n < 0 || !w->buffers[idx].presented)
wl_surface_damage_buffer(w->surface, 0, 0, w->width, w->height);
else
@@ -438,8 +446,8 @@ static void commit_buffer(struct wayland_surface *w, int idx)
wp_fifo_v1_set_barrier(w->fifo);
}
if (w->commit_timer && w->conn->pres_clock_known) {
- uint64_t now = yasl_loop_now_ns();
- uint64_t next = yasl_clock_next_present_ns(&w->clock);
+ uint64_t now = yasl_private_loop_now_ns();
+ uint64_t next = yasl_private_clock_next_present_ns(&w->clock);
bool soon = next > now && next - now < (uint64_t)(w->clock.refresh_ns * 1.5);
next = conn_mono_to_pres(w->conn, next);
if (soon)
@@ -458,10 +466,11 @@ static void commit_buffer(struct wayland_surface *w, int idx)
w->buffers[idx].presented = true;
}
-bool wayland_surface_present(struct wayland_surface *w, const struct yasl_framebuffer *fb,
- const struct yasl_damage_list *damage)
+bool wayland_surface_present(struct wayland_surface *w, const struct yasl_private_framebuffer *fb,
+ const struct yasl_private_damage_list *damage)
{
- if (!w || w->closed || !w->frame_active || w->frame_presented || !fb ||
+ if (!w || w->base.presenter != YASL_PRIVATE_PRESENTER_CPU ||
+ w->closed || !w->frame_active || w->frame_presented || !fb ||
!damage || fb->pixels != w->frame.target.pixels ||
fb->size.x != w->width || fb->size.y != w->height)
return false;
@@ -470,7 +479,7 @@ bool wayland_surface_present(struct wayland_surface *w, const struct yasl_frameb
w->damage.bounds = damage->bounds;
if (damage->n > 0)
memcpy(w->damage.rects, damage->rects, (size_t)damage->n * sizeof(damage->rects[0]));
- arm_frame(w);
+ wayland_surface_arm_frame(w);
if (w->closed)
return false;
commit_buffer(w, w->cur);
@@ -481,17 +490,17 @@ bool wayland_surface_present(struct wayland_surface *w, const struct yasl_frameb
}
bool wayland_surface_read_pixels(struct wayland_surface *w, uint32_t *out, size_t cap,
- struct yasl_vector2i *size)
+ struct yasl_private_vector2i *size)
{
if (!w || w->closed || w->frame_active || !w->has_shown) return false;
const struct buffer *b = &w->buffers[w->shown];
if (!b->pixels) return false;
- return yasl_copy_frame(b->pixels, (struct yasl_vector2i){b->width, b->height}, out, cap, size);
+ return yasl_private_copy_frame(b->pixels, (struct yasl_private_vector2i){b->width, b->height}, out, cap, size);
}
void surface_draw_frame(struct wayland_surface *w)
{
- if (w->closed || !w->configured)
+ if (w->closed || !w->configured || w->base.presenter != YASL_PRIVATE_PRESENTER_CPU)
return;
if (apply_pending_geometry(w) < 0) {
surface_fail(w);
@@ -517,18 +526,18 @@ void surface_draw_frame(struct wayland_surface *w)
if (w->parent)
memset(w->buffers[idx].pixels, 0, (size_t)w->width * (size_t)w->height * sizeof(uint32_t));
- w->damage = (struct yasl_damage_list){0};
- w->frame = (struct yasl_frame){
+ w->damage = (struct yasl_private_damage_list){0};
+ w->frame = (struct yasl_private_frame){
.surface = &w->base,
.target = {
- .generation = yasl_frame_begin(&w->base),
+ .generation = yasl_private_frame_begin(&w->base),
.pixels = w->buffers[idx].pixels,
.size = { .x = w->width, .y = w->height },
},
};
w->frame_active = true;
w->frame_presented = false;
- yasl_surface_draw(&w->base, &w->frame);
+ yasl_private_surface_draw(&w->base, &w->frame);
if (w->closed || w->destroyed)
return;
w->frame_active = false;
@@ -555,21 +564,21 @@ int surface_init_scaling(struct wayland_surface *w)
void wayland_surface_set_title(struct wayland_surface *w, const char *title)
{
if (!w || !w->toplevel || !title) return;
- char *copy = yasl_utf8_sanitize_dup(title);
+ char *copy = yasl_private_utf8_sanitize_dup(title);
if (!copy) return;
xdg_toplevel_set_title(w->toplevel, copy);
free(copy);
}
-struct yasl_timing wayland_surface_timing(const struct wayland_surface *w)
+struct yasl_private_timing wayland_surface_timing(const struct wayland_surface *w)
{
- struct yasl_timing t = {
+ struct yasl_private_timing t = {
.refresh_ns = w->clock.refresh_ns,
.last_present_ns = w->clock.last_present_ns,
- .next_present_ns = yasl_clock_next_present_ns(&w->clock),
+ .next_present_ns = yasl_private_clock_next_present_ns(&w->clock),
.frames_skipped = w->frames_skipped,
.source = w->clock.source,
};
- yasl_clock_resize_stats(&w->clock, &t.resize);
+ yasl_private_clock_resize_stats(&w->clock, &t.resize);
return t;
}