metal: retain IOSurfaceLayer ourselves instead of relying on the view

If this was Swift code, we'd be using a strong reference, which would
retain the layer for us and release it when the object is deallocated,
but this is Zig land so we have to do that manually.

NOTE: We don't *have* to do this, but it fits much better with Zig idiom
and hopefully avoids potential future footguns. We should do this to any
autoreleased objects that we persist a reference to in a Zig struct.
pull/7620/head
Qwerasd 2025-06-20 14:28:31 -06:00
parent e8460e80b2
commit 8b23e73d20
2 changed files with 5 additions and 4 deletions

View File

@ -165,9 +165,7 @@ pub fn init(alloc: Allocator, opts: rendererpkg.Options) !Metal {
pub fn deinit(self: *Metal) void { pub fn deinit(self: *Metal) void {
self.queue.release(); self.queue.release();
self.device.release(); self.device.release();
self.layer.release();
// NOTE: We don't release the layer here because that should be taken
// care of automatically when the hosting view is destroyed.
} }
pub fn loopEnter(self: *Metal) void { pub fn loopEnter(self: *Metal) void {

View File

@ -21,11 +21,14 @@ var Subclass: ?objc.Class = null;
layer: objc.Object, layer: objc.Object,
pub fn init() !IOSurfaceLayer { pub fn init() !IOSurfaceLayer {
// The layer returned by `[CALayer layer]` is autoreleased, which means
// that at the end of the current autorelease pool it will be deallocated
// if it isn't retained, so we retain it here manually an extra time.
const layer = (try getSubclass()).msgSend( const layer = (try getSubclass()).msgSend(
objc.Object, objc.Object,
objc.sel("layer"), objc.sel("layer"),
.{}, .{},
); ).retain();
errdefer layer.release(); errdefer layer.release();
// The layer gravity is set to top-left so that the contents aren't // The layer gravity is set to top-left so that the contents aren't