From 4521efb83df715cdfc6abc804c6fd5ddab81a7a5 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 17 Nov 2022 13:55:04 -0800 Subject: [PATCH] move screen resize to a renderer mailbox message --- src/Window.zig | 7 ++++++- src/renderer/Metal.zig | 37 +++++++++++-------------------------- src/renderer/OpenGL.zig | 13 +------------ src/renderer/State.zig | 3 --- src/renderer/Thread.zig | 4 ++++ src/renderer/message.zig | 4 ++++ src/termio/Exec.zig | 3 --- 7 files changed, 26 insertions(+), 45 deletions(-) diff --git a/src/Window.zig b/src/Window.zig index 1d6beda32..9985dcb9b 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -382,7 +382,6 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window { .renderer_thread = render_thread, .renderer_state = .{ .mutex = mutex, - .resize_screen = screen_size, .cursor = .{ .style = .blinking_block, .visible = true, @@ -689,6 +688,12 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void { "set. Is your padding reasonable?", .{}); } + // Mail the renderer + _ = win.renderer_thread.mailbox.push(.{ + .screen_size = win.screen_size, + }, .{ .forever = {} }); + win.queueRender() catch unreachable; + // Mail the IO thread _ = win.io_thread.mailbox.push(.{ .resize = .{ diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index a3a5af4f7..f6cc0aebf 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -383,7 +383,6 @@ pub fn render( // Data we extract out of the critical area. const Critical = struct { bg: terminal.color.RGB, - screen_size: ?renderer.ScreenSize, devmode: bool, selection: ?terminal.Selection, screen: terminal.Screen, @@ -431,12 +430,8 @@ pub fn render( ); errdefer screen_copy.deinit(); - // We set this in the state below - defer state.resize_screen = null; - break :critical .{ .bg = self.background, - .screen_size = state.resize_screen, .devmode = if (state.devmode) |dm| dm.visible else false, .selection = state.terminal.selection, .screen = screen_copy, @@ -449,26 +444,6 @@ pub fn render( const pool = objc.AutoreleasePool.init(); defer pool.deinit(); - // If we're resizing, then we have to update a bunch of things... - if (critical.screen_size) |_| { - // Note: we ignore the screen size value because our view should be - // automatically updated by being in the window. - - // Scale the bounds based on the layer content scale so that we - // properly handle Retina. - const bounds = self.swapchain.getProperty(macos.graphics.Rect, "bounds"); - const scaled: macos.graphics.Size = scaled: { - const scaleFactor = self.swapchain.getProperty(macos.graphics.c.CGFloat, "contentsScale"); - break :scaled .{ - .width = bounds.size.width * scaleFactor, - .height = bounds.size.height * scaleFactor, - }; - }; - - // Handle our new size - try self.setScreenSize(scaled); - } - // Build our GPU cells try self.rebuildCells( critical.selection, @@ -614,7 +589,17 @@ pub fn render( } /// Resize the screen. -fn setScreenSize(self: *Metal, bounds: macos.graphics.Size) !void { +pub fn setScreenSize(self: *Metal, _: renderer.ScreenSize) !void { + // We use the bounds of our view which should be updated by now. + const unscaled = self.swapchain.getProperty(macos.graphics.Rect, "bounds"); + const bounds: macos.graphics.Size = scaled: { + const scaleFactor = self.swapchain.getProperty(macos.graphics.c.CGFloat, "contentsScale"); + break :scaled .{ + .width = unscaled.size.width * scaleFactor, + .height = unscaled.size.height * scaleFactor, + }; + }; + // Easier to work with our own types const dim: renderer.ScreenSize = .{ .width = @floatToInt(u32, bounds.width), diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 3fcd7a7b9..6da382cd3 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -533,7 +533,6 @@ pub fn render( const Critical = struct { gl_bg: terminal.color.RGB, devmode_data: ?*imgui.DrawData, - screen_size: ?renderer.ScreenSize, active_screen: terminal.Terminal.ScreenType, selection: ?terminal.Selection, screen: terminal.Screen, @@ -595,13 +594,9 @@ pub fn render( ); errdefer screen_copy.deinit(); - // We set this in the state below - defer state.resize_screen = null; - break :critical .{ .gl_bg = self.background, .devmode_data = devmode_data, - .screen_size = state.resize_screen, .active_screen = state.terminal.active_screen, .selection = state.terminal.selection, .screen = screen_copy, @@ -610,12 +605,6 @@ pub fn render( }; defer critical.screen.deinit(); - // If we are resizing we need to update the viewport - if (critical.screen_size) |size| { - // Update our grid size - try self.setScreenSize(size); - } - // Build our GPU cells try self.rebuildCells( critical.active_screen, @@ -1021,7 +1010,7 @@ fn gridSize(self: *OpenGL, screen_size: renderer.ScreenSize) renderer.GridSize { /// Set the screen size for rendering. This will update the projection /// used for the shader so that the scaling of the grid is correct. -fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void { +pub fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void { // Recalculate the rows/columns. const grid_size = self.gridSize(dim); diff --git a/src/renderer/State.zig b/src/renderer/State.zig index f06d1784c..5b1db42a0 100644 --- a/src/renderer/State.zig +++ b/src/renderer/State.zig @@ -12,9 +12,6 @@ const renderer = @import("../renderer.zig"); /// state (i.e. the terminal, devmode, etc. values). mutex: *std.Thread.Mutex, -/// A new screen size if the screen was resized. -resize_screen: ?renderer.ScreenSize, - /// Cursor configuration for rendering cursor: Cursor, diff --git a/src/renderer/Thread.zig b/src/renderer/Thread.zig index 87a949a43..34944b8b1 100644 --- a/src/renderer/Thread.zig +++ b/src/renderer/Thread.zig @@ -279,6 +279,10 @@ fn drainMailbox(self: *Thread) !void { .font_size => |size| { try self.renderer.setFontSize(size); }, + + .screen_size => |size| { + try self.renderer.setScreenSize(size); + }, } } } diff --git a/src/renderer/message.zig b/src/renderer/message.zig index 02c9ddefc..e129d9fe9 100644 --- a/src/renderer/message.zig +++ b/src/renderer/message.zig @@ -2,6 +2,7 @@ const std = @import("std"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; const font = @import("../font/main.zig"); +const renderer = @import("../renderer.zig"); /// The messages that can be sent to a renderer thread. pub const Message = union(enum) { @@ -18,4 +19,7 @@ pub const Message = union(enum) { /// send a grid size change message back to the window thread if /// the size changes. font_size: font.face.DesiredSize, + + /// Change the screen size. + screen_size: renderer.ScreenSize, }; diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 6d061450f..e8828fd56 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -249,9 +249,6 @@ pub fn resize( self.renderer_state.mutex.lock(); defer self.renderer_state.mutex.unlock(); - // We need to setup our render state to store our new pending size - self.renderer_state.resize_screen = screen_size; - // Update the size of our terminal state try self.terminal.resize(self.alloc, grid_size.columns, grid_size.rows); }