summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-12 14:31:10 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-12 14:31:10 +0300
commitdfebac1019560e278c605247de3b98cff1d73226 (patch)
tree21df3066f2e60496f259a5981ca5501b4e395b61 /src
parent9ed89c17dee752154c36d71cae93d20cccfc71ef (diff)
perf: cache Cocoa software MTLBuffer and optimize Wayland output/focus loops
Diffstat (limited to 'src')
-rw-r--r--src/cocoa/window.m15
-rw-r--r--src/wayland/buffer.c25
-rw-r--r--src/wayland/keyboard.c3
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,