From 4145406fae437dce2f0af6e078e35566634f2c19 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Mon, 12 Oct 2026 15:14:41 +0300 Subject: perf: unify platform-independent state, branchless queue masking and native handle caching --- src/cocoa/window.m | 7 +++++++ src/common/backend.c | 19 ++++++++++++------- src/common/backend.h | 7 +++++++ src/common/input.c | 21 +++++++++++++-------- src/common/native.c | 8 ++++++-- src/wayland/buffer.c | 2 ++ src/wayland/popup.c | 3 +++ src/wayland/surface.c | 4 ++++ src/x11/window.c | 9 +++++++++ 9 files changed, 63 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/cocoa/window.m b/src/cocoa/window.m index 8856fde..335c065 100644 --- a/src/cocoa/window.m +++ b/src/cocoa/window.m @@ -1259,6 +1259,7 @@ struct cocoa_display *cocoa_display_open(struct yasl_loop *loop, const struct ya const char *name = spec && spec->app_id ? spec->app_id : "YASL"; @autoreleasepool { app_init(name); } darwin_ctx.base.ops = &yasl_cocoa_backend; + darwin_ctx.base.native_handle = (__bridge void *)[NSApplication sharedApplication]; darwin_ctx.open = true; if (!loop) { darwin_ctx.loop = yasl_loop_create(); @@ -1341,6 +1342,9 @@ struct cocoa_surface *cocoa_surface_create_toplevel(struct cocoa_display *d, backing:NSBackingStoreBuffered defer:NO]; w->window.releasedWhenClosed = NO; + w->base.native_handle = (__bridge void *)w->window; + w->base.size = w->size; + w->base.scale_120 = w->scale_120; w->controller = [[YaslWindowController alloc] initWithWindow:w->window]; w->controller.surface = w; w->window.delegate = w->controller; @@ -1714,6 +1718,9 @@ struct cocoa_surface *cocoa_surface_create_popup(struct cocoa_surface *parent, backing:NSBackingStoreBuffered defer:NO]; w->window.releasedWhenClosed = NO; + w->base.native_handle = (__bridge void *)w->window; + w->base.size = w->size; + w->base.scale_120 = w->scale_120; w->window.opaque = NO; w->window.backgroundColor = [NSColor clearColor]; w->window.hasShadow = NO; diff --git a/src/common/backend.c b/src/common/backend.c index c8d2caf..cab1dce 100644 --- a/src/common/backend.c +++ b/src/common/backend.c @@ -184,16 +184,17 @@ void yasl_surface_destroy(struct yasl_surface *s) struct yasl_display *yasl_surface_display(const struct yasl_surface *s) { - if (!s || !s->display->ops->surface_display) - return 0; - return s->display->ops->surface_display(s); + return s ? s->display : NULL; } void yasl_surface_set_callbacks(struct yasl_surface *s, const struct yasl_surface_cbs *cbs, void *ud) { - if (!s || !s->display->ops->surface_set_callbacks) + if (!s) return; - s->display->ops->surface_set_callbacks(s, cbs, ud); + s->callbacks = cbs ? *cbs : (struct yasl_surface_cbs){0}; + s->ud = ud; + if (s->display && s->display->ops && s->display->ops->surface_set_callbacks) + s->display->ops->surface_set_callbacks(s, cbs, ud); } void yasl_surface_set_title(struct yasl_surface *s, const char *title) @@ -250,9 +251,13 @@ bool yasl_surface_input_poll(struct yasl_surface *s, struct yasl_input_event *ev struct yasl_geometry yasl_surface_geometry(const struct yasl_surface *s) { - if (!s || !s->display->ops->surface_geometry) + if (!s) return (struct yasl_geometry){.scale_120 = YASL_SCALE_UNIT}; - return s->display->ops->surface_geometry(s); + if (s->scale_120) + return (struct yasl_geometry){s->size, s->scale_120}; + if (s->display && s->display->ops && s->display->ops->surface_geometry) + return s->display->ops->surface_geometry(s); + return (struct yasl_geometry){s->size, YASL_SCALE_UNIT}; } uint32_t yasl_surface_state(const struct yasl_surface *s) diff --git a/src/common/backend.h b/src/common/backend.h index 6ab7248..e1d29c5 100644 --- a/src/common/backend.h +++ b/src/common/backend.h @@ -9,13 +9,20 @@ struct yasl_backend_ops; struct yasl_display { const struct yasl_backend_ops *ops; + void *native_handle; struct yasl_display_cbs callbacks; struct yasl_loop *loop; }; struct yasl_surface { struct yasl_display *display; + void *native_handle; + struct yasl_vector2i size; + uint32_t scale_120; + uint32_t state; + uint32_t bg_color; struct yasl_surface_cbs callbacks; + void *ud; uint64_t frame_generation; yasl_timer_id *timers; int timer_count; diff --git a/src/common/input.c b/src/common/input.c index ff578e3..471cd2b 100644 --- a/src/common/input.c +++ b/src/common/input.c @@ -35,11 +35,11 @@ static void discard_pending(struct input_queue *q) bool input_queue_push(struct input_queue *q, const struct yasl_input_event *ev) { struct yasl_input_event copy = *ev; - size_t len; - const char *text = event_text(ev, &len); char *owned = NULL; if (ev->kind == YASL_INPUT_TEXT || ev->kind == YASL_INPUT_PASTE || ev->kind == YASL_INPUT_DROP_FILES) { + size_t len; + const char *text = event_text(ev, &len); if ((!text && len) || len == SIZE_MAX) goto failed; owned = malloc(len + 1); if (!owned) goto failed; @@ -65,7 +65,7 @@ bool input_queue_push(struct input_queue *q, const struct yasl_input_event *ev) q->capacity = capacity; q->head = 0; } - q->events[(q->head + q->count) % q->capacity] = copy; + q->events[(q->head + q->count) & (q->capacity - 1)] = copy; q->count++; return true; @@ -82,8 +82,10 @@ failed: bool input_queue_pop(struct input_queue *q, struct yasl_input_event *ev) { if (!ev || (!q->count && !q->reset_pending)) return false; - free(q->last_text); - q->last_text = NULL; + if (q->last_text) { + free(q->last_text); + q->last_text = NULL; + } if (q->reset_pending) { *ev = (struct yasl_input_event){ .surface = q->reset_surface, .kind = YASL_INPUT_RESET, @@ -92,9 +94,12 @@ bool input_queue_pop(struct input_queue *q, struct yasl_input_event *ev) return true; } *ev = q->events[q->head]; - size_t len; - q->last_text = (char *)event_text(ev, &len); - q->head = (q->head + 1) % q->capacity; + if (ev->kind == YASL_INPUT_TEXT || ev->kind == YASL_INPUT_PASTE || + ev->kind == YASL_INPUT_DROP_FILES) { + size_t len; + q->last_text = (char *)event_text(ev, &len); + } + q->head = (q->head + 1) & (q->capacity - 1); q->count--; return true; } diff --git a/src/common/native.c b/src/common/native.c index 6e1c69a..33837e4 100644 --- a/src/common/native.c +++ b/src/common/native.c @@ -12,13 +12,17 @@ void *yasl_display_get_native_handle(struct yasl_display *d) { - return d && d->ops->display_get_native_handle ? + if (!d) return NULL; + if (d->native_handle) return d->native_handle; + return d->ops && 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 ? + if (!s) return NULL; + if (s->native_handle) return s->native_handle; + return s->display && s->display->ops && s->display->ops->surface_get_native_handle ? s->display->ops->surface_get_native_handle(s) : NULL; } diff --git a/src/wayland/buffer.c b/src/wayland/buffer.c index 4cddfa5..142f85f 100644 --- a/src/wayland/buffer.c +++ b/src/wayland/buffer.c @@ -174,6 +174,8 @@ int apply_pending_geometry(struct wayland_surface *w) w->scale_factor = (double)w->scale_120 / YASL_SCALE_UNIT; w->width = width; w->height = height; + w->base.size = (struct yasl_vector2i){width, height}; + w->base.scale_120 = w->scale_120; w->logical_width = logical_w; w->logical_height = logical_h; surface_update_opaque_region(w); diff --git a/src/wayland/popup.c b/src/wayland/popup.c index 4364934..3a85435 100644 --- a/src/wayland/popup.c +++ b/src/wayland/popup.c @@ -147,6 +147,9 @@ struct wayland_surface *wayland_surface_create_popup(struct wayland_surface *par w->surface = wl_compositor_create_surface(c->compositor); if (!w->surface) goto err; + w->base.native_handle = w->surface; + w->base.size = (struct yasl_vector2i){spec->size.x, spec->size.y}; + w->base.scale_120 = parent->scale_120; wl_surface_set_user_data(w->surface, w); if (surface_init_scaling(w) < 0) goto err; diff --git a/src/wayland/surface.c b/src/wayland/surface.c index 8a2bb5b..ca9db72 100644 --- a/src/wayland/surface.c +++ b/src/wayland/surface.c @@ -252,6 +252,7 @@ struct wayland_display *wayland_display_open(struct yasl_loop *loop, const struc c->xkb_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); c->wl = c->xkb_ctx ? wl_display_connect(NULL) : NULL; if (!c->wl) goto err; + c->base.native_handle = c->wl; c->registry = wl_display_get_registry(c->wl); if (!c->registry) goto err; @@ -354,6 +355,9 @@ struct wayland_surface *wayland_surface_create_toplevel(struct wayland_display * w->surface = wl_compositor_create_surface(c->compositor); if (!w->surface) goto err; + w->base.native_handle = w->surface; + w->base.size = (struct yasl_vector2i){width, height}; + w->base.scale_120 = YASL_SCALE_UNIT; wl_surface_set_user_data(w->surface, w); if (surface_init_scaling(w) < 0) goto err; if (surface_init_shell(w, spec->title) < 0) goto err; diff --git a/src/x11/window.c b/src/x11/window.c index 271c128..12fc954 100644 --- a/src/x11/window.c +++ b/src/x11/window.c @@ -526,6 +526,8 @@ static bool resize(struct x11_surface *s, struct yasl_vector2i size) s->image = image; s->pixels = pixels; s->size = size; + s->base.size = size; + s->base.scale_120 = YASL_SCALE_UNIT; s->want_draw = true; yasl_clock_note_resize(&s->clock, yasl_loop_now_ns() - start); return true; @@ -630,6 +632,9 @@ static struct yasl_surface *create_toplevel(struct yasl_display *base, if (!resize(s, spec->size)) { free(s); return NULL; } s->window = XCreateSimpleWindow(d->native, RootWindow(d->native, d->screen), 0, 0, (unsigned)spec->size.x, (unsigned)spec->size.y, 0, 0, 0); + s->base.native_handle = (void *)(uintptr_t)s->window; + s->base.size = s->size; + s->base.scale_120 = YASL_SCALE_UNIT; s->gc = XCreateGC(d->native, s->window, 0, NULL); XSelectInput(d->native, s->window, ExposureMask | StructureNotifyMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask | @@ -769,6 +774,9 @@ static struct yasl_surface *surface_create_popup(struct yasl_surface *parent_bas surface_destroy(&s->base); return NULL; } + s->base.native_handle = (void *)(uintptr_t)s->window; + s->base.size = s->size; + s->base.scale_120 = YASL_SCALE_UNIT; s->gc = XCreateGC(d->native, s->window, 0, NULL); XSelectInput(d->native, s->window, ExposureMask | StructureNotifyMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask | @@ -1390,6 +1398,7 @@ static struct yasl_display *display_open(struct yasl_loop *loop, d->base.callbacks = spec && spec->cbs ? *spec->cbs : (struct yasl_display_cbs){0}; d->native = XOpenDisplay(NULL); if (!d->native) { free(d); errno = ENODEV; return NULL; } + d->base.native_handle = d->native; d->screen = DefaultScreen(d->native); int xi_event_base, xi_error_base; int major = 2, minor = 0; -- cgit v1.2.3