renderer: move drawFrame AutoreleasePool handling to GraphicsAPI

Introduces `drawFrameStart`/`drawFrameEnd` for this purpose.
This commit is contained in:
Qwerasd
2025-06-20 16:16:17 -06:00
parent ab926fc842
commit ddf1a5b23d
3 changed files with 38 additions and 9 deletions

View File

@@ -61,6 +61,9 @@ blending: configpkg.Config.AlphaBlending,
/// the "shared" storage mode, instead we have to use the "managed" mode.
default_storage_mode: mtl.MTLResourceOptions.StorageMode,
/// We start an AutoreleasePool before `drawFrame` and end it afterwards.
autorelease_pool: ?*objc.AutoreleasePool = null,
pub fn init(alloc: Allocator, opts: rendererpkg.Options) !Metal {
comptime switch (builtin.os.tag) {
.macos, .ios => {},
@@ -185,6 +188,23 @@ fn displayCallback(renderer: *Renderer) align(8) void {
};
}
/// Actions taken before doing anything in `drawFrame`.
///
/// Right now we use this to start an AutoreleasePool.
pub fn drawFrameStart(self: *Metal) void {
assert(self.autorelease_pool == null);
self.autorelease_pool = .init();
}
/// Actions taken after `drawFrame` is done.
///
/// Right now we use this to end our AutoreleasePool.
pub fn drawFrameEnd(self: *Metal) void {
assert(self.autorelease_pool != null);
self.autorelease_pool.?.deinit();
self.autorelease_pool = null;
}
pub fn initShaders(
self: *const Metal,
alloc: Allocator,

View File

@@ -289,6 +289,20 @@ pub fn displayRealized(self: *const OpenGL) void {
}
}
/// Actions taken before doing anything in `drawFrame`.
///
/// Right now there's nothing we need to do for OpenGL.
pub fn drawFrameStart(self: *OpenGL) void {
_ = self;
}
/// Actions taken after `drawFrame` is done.
///
/// Right now there's nothing we need to do for OpenGL.
pub fn drawFrameEnd(self: *OpenGL) void {
_ = self;
}
pub fn initShaders(
self: *const OpenGL,
alloc: Allocator,

View File

@@ -1241,15 +1241,10 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
self.draw_mutex.lock();
defer self.draw_mutex.unlock();
// There's probably a more elegant way to do this...
//
// This is effectively an @autoreleasepool{} block, which we need in
// order to ensure that autoreleased objects are properly released.
const pool = if (builtin.os.tag.isDarwin())
@import("objc").AutoreleasePool.init()
else
void;
defer if (builtin.os.tag.isDarwin()) pool.deinit();
// Let our graphics API do any bookkeeping, etc.
// that it needs to do before / after `drawFrame`.
self.api.drawFrameStart();
defer self.api.drawFrameEnd();
// Retrieve the most up-to-date surface size from the Graphics API
const surface_size = try self.api.surfaceSize();