diff --git a/src/renderer/renderer_metal.mm b/src/renderer/renderer_metal.mm index b8259dd..425160f 100644 --- a/src/renderer/renderer_metal.mm +++ b/src/renderer/renderer_metal.mm @@ -166,6 +166,9 @@ struct Renderer { CTFontRef measure_font; F32 measure_font_size; + // Current drawable (acquired in begin_frame) + id current_drawable; + // Clear color F32 clear_r, clear_g, clear_b; }; @@ -635,18 +638,23 @@ void renderer_destroy(Renderer *r) { bool renderer_begin_frame(Renderer *r) { if (r->width <= 0 || r->height <= 0) return false; + + // Wait for an in-flight frame to finish, then acquire a drawable. + // Doing this BEFORE input sampling ensures the freshest mouse position + // is used for rendering, reducing perceived drag latency. + dispatch_semaphore_wait(r->frame_semaphore, DISPATCH_TIME_FOREVER); + r->current_drawable = [r->metal_layer nextDrawable]; + if (!r->current_drawable) { + dispatch_semaphore_signal(r->frame_semaphore); + return false; + } return true; } void renderer_end_frame(Renderer *r, Clay_RenderCommandArray render_commands) { - dispatch_semaphore_wait(r->frame_semaphore, DISPATCH_TIME_FOREVER); - @autoreleasepool { - id drawable = [r->metal_layer nextDrawable]; - if (!drawable) { - dispatch_semaphore_signal(r->frame_semaphore); - return; - } + id drawable = r->current_drawable; + r->current_drawable = nil; uint32_t buf_idx = r->frame_index % NUM_BACK_BUFFERS;