From b5d543705de4ea42407db9e2d49ae03f3ae5cf14 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 13 Feb 2024 20:07:41 -0800 Subject: [PATCH] renderer/metal: free resources when occluded --- src/renderer/Metal.zig | 18 ++++++++++++++++++ src/renderer/Thread.zig | 3 +++ 2 files changed, 21 insertions(+) diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index 4a1f0f131..8296176d4 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -509,6 +509,19 @@ pub fn setFocus(self: *Metal, focus: bool) !void { self.focused = focus; } +/// Callback when the view visibility changes, i.e. if a window is on +/// another workspace, behind a window, etc. +pub fn setVisible(self: *Metal, visible: bool) !void { + //if (true) return; + if (!visible) { + if (self.visible_resources) |*v| { + log.debug("view occluded, deallocating GPU resources", .{}); + v.deinit(self.alloc); + self.visible_resources = null; + } + } +} + /// Set the new font size. /// /// Must be called on the render thread. @@ -712,6 +725,7 @@ pub fn drawFrame(self: *Metal, surface: *apprt.Surface) !void { // Get our cached resources. If we don't have them, then we need to // create them. If we fail to create them, mark the renderer as unhealthy. const resources: *VisibleResources = if (self.visible_resources) |*v| v else resources: { + log.debug("view is visible, allocating GPU resources", .{}); const resources = VisibleResources.init(self) catch |err| { self.setHealth(.unhealthy); return err; @@ -2226,6 +2240,10 @@ const VisibleResources = struct { const texture_color = try initAtlasTexture(m.device, &m.font_group.atlas_color); errdefer deinitMTLResource(texture_color); + // Mark our atlas as modified so the textures are synced + m.font_group.atlas_greyscale.modified = true; + m.font_group.atlas_color.modified = true; + return .{ .shaders = shaders, .buf_cells = buf_cells, diff --git a/src/renderer/Thread.zig b/src/renderer/Thread.zig index 113f6761c..84f1940f5 100644 --- a/src/renderer/Thread.zig +++ b/src/renderer/Thread.zig @@ -250,6 +250,9 @@ fn drainMailbox(self: *Thread) !void { // Set our visible state self.flags.visible = v; + // Set it on the renderer + try self.renderer.setVisible(v); + // If we became visible then we immediately trigger a draw. // We don't need to update frame data because that should // still be happening.