metal.zig (2483B)
1 const glfw = @import("glfw.zig"); 2 3 pub fn getMetalLayer(window: *glfw.Window) *anyopaque { 4 const ns_window = try glfw.native.getCocoaWindow(window); 5 const ns_view = msgSend(ns_window, "contentView", .{}, *anyopaque); 6 // Create a CAMetalLayer that covers the whole window. 7 msgSend(ns_view, "setWantsLayer:", .{true}, void); 8 const layer = msgSend( 9 objc_getClass("CAMetalLayer"), 10 "layer", 11 .{}, 12 ?*anyopaque, 13 ) orelse { 14 @panic("failed to create Metal layer"); 15 }; 16 msgSend(ns_view, "setLayer:", .{layer}, void); 17 // Use retina if the window was created with retina support. 18 //const scale_factor = msgSend(ns_window, "backingScaleFactor", .{}, f64); 19 //msgSend(layer, "setContentsScale:", .{scale_factor}, void); 20 return layer; 21 } 22 23 // objective c interop 24 // Borrowed from https://github.com/hexops/mach-gpu 25 // Borrowed from https://github.com/hazeycode/zig-objcrt 26 const SEL = opaque {}; 27 const Class = opaque {}; 28 extern fn sel_getUid(str: [*c]const u8) ?*SEL; 29 extern fn objc_getClass(name: [*c]const u8) ?*Class; 30 extern fn objc_msgSend() void; 31 fn msgSend( 32 obj: anytype, 33 sel_name: [:0]const u8, 34 args: anytype, 35 comptime ReturnType: type 36 ) ReturnType { 37 const args_meta = @typeInfo(@TypeOf(args)).@"struct".fields; 38 const FnType = switch (args_meta.len) { 39 0 => *const fn (@TypeOf(obj), ?*SEL) callconv(.C) ReturnType, 40 1 => *const fn ( 41 @TypeOf(obj), 42 ?*SEL, 43 args_meta[0].type 44 ) callconv(.C) ReturnType, 45 2 => *const fn ( 46 @TypeOf(obj), 47 ?*SEL, 48 args_meta[0].type, 49 args_meta[1].type, 50 ) callconv(.C) ReturnType, 51 3 => *const fn ( 52 @TypeOf(obj), 53 ?*SEL, 54 args_meta[0].type, 55 args_meta[1].type, 56 args_meta[2].type, 57 ) callconv(.C) ReturnType, 58 4 => *const fn ( 59 @TypeOf(obj), 60 ?*SEL, 61 args_meta[0].type, 62 args_meta[1].type, 63 args_meta[2].type, 64 args_meta[3].type, 65 ) callconv(.C) ReturnType, 66 else => @compileError("Unsupported number of args"), 67 }; 68 const func = @as(FnType, @ptrCast(&objc_msgSend)); 69 const sel = sel_getUid(@as([*c]const u8, @ptrCast(sel_name))); 70 return @call(.auto, func, .{ obj, sel } ++ args); 71 }