diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-10 21:51:57 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-10 21:51:57 +0300 |
| commit | 425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch) | |
| tree | e52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/src/renderer/Metal.zig | |
| parent | 90e947a6e26e02f10ec7f1694c4eb5b78a86406b (diff) | |
chore: upgrade libghostty and preserve terminal behavior (#3906)
Diffstat (limited to 'vendor/libghostty-vt/src/renderer/Metal.zig')
| -rw-r--r-- | vendor/libghostty-vt/src/renderer/Metal.zig | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/renderer/Metal.zig b/vendor/libghostty-vt/src/renderer/Metal.zig index 6c7432d2..9247454d 100644 --- a/vendor/libghostty-vt/src/renderer/Metal.zig +++ b/vendor/libghostty-vt/src/renderer/Metal.zig @@ -407,6 +407,44 @@ pub inline fn beginFrame( return try Frame.begin(.{ .queue = self.queue }, renderer, target); } +/// Warm up the Metal device machinery. The first Metal device query in +/// a process takes multiple milliseconds; once warm, subsequent queries +/// are effectively free. Calling this early (e.g. on a background +/// thread at app startup; Metal device queries are thread-safe) moves +/// that one-time cost off the critical path of the first surface's +/// renderer initialization. +pub fn warmup() void { + const device = chooseDevice() catch return; + defer device.release(); + + // Create and release a command queue. The first command queue + // created for a device pays additional one-time driver setup + // costs; subsequent creations are much cheaper. + const queue = device.msgSend(objc.Object, objc.sel("newCommandQueue"), .{}); + queue.release(); + + // Build and discard our shader pipelines for both pixel formats we + // may use (which one is used depends on the blending config). The + // first pipeline state creation compiles shaders which is slow; + // once warm, later creations hit driver and OS caches. + inline for (.{ + mtl.MTLPixelFormat.bgra8unorm_srgb, + mtl.MTLPixelFormat.bgra8unorm, + }) |format| { + if (shaders.Shaders.init( + std.heap.c_allocator, + device, + &.{}, + format, + )) |s| { + var s_mut = s; + s_mut.deinit(std.heap.c_allocator); + } else |err| { + log.warn("metal warmup shader init failed err={}", .{err}); + } + } +} + fn chooseDevice() error{NoMetalDevice}!objc.Object { var chosen_device: ?objc.Object = null; |
