diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-12 14:31:10 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-12 14:31:10 +0300 |
| commit | dfebac1019560e278c605247de3b98cff1d73226 (patch) | |
| tree | 21df3066f2e60496f259a5981ca5501b4e395b61 | |
| parent | 9ed89c17dee752154c36d71cae93d20cccfc71ef (diff) | |
perf: cache Cocoa software MTLBuffer and optimize Wayland output/focus loops
| -rw-r--r-- | src/cocoa/window.m | 15 | ||||
| -rw-r--r-- | src/wayland/buffer.c | 25 | ||||
| -rw-r--r-- | src/wayland/keyboard.c | 3 |
3 files changed, 27 insertions, 16 deletions
diff --git a/src/cocoa/window.m b/src/cocoa/window.m index 78ab0bd..8856fde 100644 --- a/src/cocoa/window.m +++ b/src/cocoa/window.m @@ -53,6 +53,8 @@ struct cocoa_surface { YaslView *view; CAMetalLayer *layer; id<MTLCommandQueue> software_queue; + id<MTLBuffer> software_buffer; + NSUInteger software_buffer_capacity; CADisplayLink *link; struct cocoa_surface *parent; @@ -1031,15 +1033,20 @@ bool cocoa_surface_present(struct cocoa_surface *w, const struct yasl_framebuffe return false; NSUInteger row_bytes = ((NSUInteger)w->size.x * 4 + 255) & ~(NSUInteger)255; NSUInteger length = row_bytes * (NSUInteger)w->size.y; - id<MTLBuffer> buffer = [w->layer.device newBufferWithLength:length - options:MTLResourceStorageModeShared]; + if (!w->software_buffer || w->software_buffer_capacity < length) { + [w->software_buffer release]; + w->software_buffer = [w->layer.device newBufferWithLength:length + options:MTLResourceStorageModeShared]; + w->software_buffer_capacity = w->software_buffer ? length : 0; + } + id<MTLBuffer> buffer = w->software_buffer; if (!buffer) return false; for (int y = 0; y < w->size.y; y++) memcpy((char *)buffer.contents + (NSUInteger)y * row_bytes, w->pixels + (size_t)y * w->size.x, (size_t)w->size.x * 4); id<MTLCommandBuffer> command = [w->software_queue commandBuffer]; id<MTLBlitCommandEncoder> blit = [command blitCommandEncoder]; - if (!blit) { [buffer release]; return false; } + if (!blit) return false; id<CAMetalDrawable> drawable = w->drawable; [blit copyFromBuffer:buffer sourceOffset:0 sourceBytesPerRow:row_bytes sourceBytesPerImage:length sourceSize:MTLSizeMake(w->size.x, w->size.y, 1) @@ -1048,7 +1055,6 @@ bool cocoa_surface_present(struct cocoa_surface *w, const struct yasl_framebuffe [blit endEncoding]; [command presentDrawable:drawable]; [command commit]; - [buffer release]; } yasl_clock_presented(&w->clock, yasl_loop_now_ns(), false); w->did_present = true; @@ -1394,6 +1400,7 @@ struct cocoa_surface *cocoa_surface_create_toplevel(struct cocoa_display *d, static void surface_free(struct cocoa_surface *w) { [w->link release]; + [w->software_buffer release]; [w->software_queue release]; [w->view release]; [w->controller release]; diff --git a/src/wayland/buffer.c b/src/wayland/buffer.c index 0561da3..4cddfa5 100644 --- a/src/wayland/buffer.c +++ b/src/wayland/buffer.c @@ -200,24 +200,27 @@ static const struct wp_fractional_scale_v1_listener frac_scale_listener = { .preferred_scale = fractional_preferred_scale, }; -static void surface_follow_refresh(struct wayland_surface *w) +void surface_follow_outputs(struct wayland_surface *w) { uint32_t refresh = 0; - for (const struct wl_conn_output *o = w->conn->outputs; o; o = o->next) - if ((o->mask & w->outputs) && o->refresh_ns && - (!refresh || o->refresh_ns < refresh)) - refresh = o->refresh_ns; + int32_t max_scale = 0; + bool need_scale = !w->frac_scale && !surface_gets_preferred_scale(w->surface); + + for (const struct wl_conn_output *o = w->conn->outputs; o; o = o->next) { + if (o->mask & w->outputs) { + if (o->refresh_ns && (!refresh || o->refresh_ns < refresh)) + refresh = o->refresh_ns; + if (need_scale && o->scale > max_scale) + max_scale = o->scale; + } + } if (!refresh && w->conn->outputs) refresh = w->conn->outputs->refresh_ns; if (refresh) w->clock.refresh_ns = refresh; -} -void surface_follow_outputs(struct wayland_surface *w) -{ - surface_follow_refresh(w); - if (!w->frac_scale && !surface_gets_preferred_scale(w->surface)) - surface_request_scale(w, conn_output_scale_120(w->conn, w->outputs)); + if (need_scale) + surface_request_scale(w, (uint32_t)max_scale * YASL_SCALE_UNIT); } static void surface_enter(void *data, struct wl_surface *surface, struct wl_output *output) diff --git a/src/wayland/keyboard.c b/src/wayland/keyboard.c index f7e2691..11c7f3f 100644 --- a/src/wayland/keyboard.c +++ b/src/wayland/keyboard.c @@ -170,7 +170,8 @@ static void seat_settle_focus(struct seat *s) void keyboard_settle_focus(struct wayland_display *c) { for (struct seat *s = c->seats; s; s = s->next) - seat_settle_focus(s); + if (s->focus_leaving) + seat_settle_focus(s); } static void keyboard_leave(void *data, struct wl_keyboard *keyboard, |
