aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/renderer/metal/Target.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/renderer/metal/Target.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/renderer/metal/Target.zig')
-rw-r--r--vendor/libghostty-vt/src/renderer/metal/Target.zig108
1 files changed, 108 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/renderer/metal/Target.zig b/vendor/libghostty-vt/src/renderer/metal/Target.zig
new file mode 100644
index 00000000..f20bb0b7
--- /dev/null
+++ b/vendor/libghostty-vt/src/renderer/metal/Target.zig
@@ -0,0 +1,108 @@
+//! Represents a render target.
+//!
+//! In this case, an IOSurface-backed MTLTexture.
+const Self = @This();
+
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const objc = @import("objc");
+const macos = @import("macos");
+const graphics = macos.graphics;
+const IOSurface = macos.iosurface.IOSurface;
+
+const mtl = @import("api.zig");
+
+const log = std.log.scoped(.metal);
+
+/// Options for initializing a Target
+pub const Options = struct {
+ /// MTLDevice
+ device: objc.Object,
+
+ /// Desired width
+ width: usize,
+ /// Desired height
+ height: usize,
+
+ /// Pixel format for the MTLTexture
+ pixel_format: mtl.MTLPixelFormat,
+ /// Storage mode for the MTLTexture
+ storage_mode: mtl.MTLResourceOptions.StorageMode,
+};
+
+/// The underlying IOSurface.
+surface: *IOSurface,
+
+/// The underlying MTLTexture.
+texture: objc.Object,
+
+/// Current width of this target.
+width: usize,
+/// Current height of this target.
+height: usize,
+
+pub fn init(opts: Options) !Self {
+ // We set our surface's color space to Display P3.
+ // This allows us to have "Apple-style" alpha blending,
+ // since it seems to be the case that Apple apps like
+ // Terminal and TextEdit render text in the display's
+ // color space using converted colors, which reduces,
+ // but does not fully eliminate blending artifacts.
+ const colorspace = try graphics.ColorSpace.createNamed(.displayP3);
+ defer colorspace.release();
+
+ const surface = try IOSurface.init(.{
+ .width = @intCast(opts.width),
+ .height = @intCast(opts.height),
+ .pixel_format = .@"32BGRA",
+ .bytes_per_element = 4,
+ .colorspace = colorspace,
+ });
+
+ // Create our descriptor
+ const desc = init: {
+ const Class = objc.getClass("MTLTextureDescriptor").?;
+ const id_alloc = Class.msgSend(objc.Object, objc.sel("alloc"), .{});
+ const id_init = id_alloc.msgSend(objc.Object, objc.sel("init"), .{});
+ break :init id_init;
+ };
+ defer desc.release();
+
+ // Set our properties
+ desc.setProperty("width", @as(c_ulong, @intCast(opts.width)));
+ desc.setProperty("height", @as(c_ulong, @intCast(opts.height)));
+ desc.setProperty("pixelFormat", @intFromEnum(opts.pixel_format));
+ desc.setProperty("usage", mtl.MTLTextureUsage{ .render_target = true });
+ desc.setProperty(
+ "resourceOptions",
+ mtl.MTLResourceOptions{
+ // Indicate that the CPU writes to this resource but never reads it.
+ .cpu_cache_mode = .write_combined,
+ .storage_mode = opts.storage_mode,
+ },
+ );
+
+ const id = opts.device.msgSend(
+ ?*anyopaque,
+ objc.sel("newTextureWithDescriptor:iosurface:plane:"),
+ .{
+ desc,
+ surface,
+ @as(c_ulong, 0),
+ },
+ ) orelse return error.MetalFailed;
+
+ const texture = objc.Object.fromId(id);
+
+ return .{
+ .surface = surface,
+ .texture = texture,
+ .width = opts.width,
+ .height = opts.height,
+ };
+}
+
+pub fn deinit(self: *Self) void {
+ self.surface.deinit();
+ self.texture.release();
+}