move screen resize to a renderer mailbox message

This commit is contained in:
Mitchell Hashimoto
2022-11-17 13:55:04 -08:00
parent fc18be5d32
commit 4521efb83d
7 changed files with 26 additions and 45 deletions

View File

@ -382,7 +382,6 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window {
.renderer_thread = render_thread, .renderer_thread = render_thread,
.renderer_state = .{ .renderer_state = .{
.mutex = mutex, .mutex = mutex,
.resize_screen = screen_size,
.cursor = .{ .cursor = .{
.style = .blinking_block, .style = .blinking_block,
.visible = true, .visible = true,
@ -689,6 +688,12 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void {
"set. Is your padding reasonable?", .{}); "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 // Mail the IO thread
_ = win.io_thread.mailbox.push(.{ _ = win.io_thread.mailbox.push(.{
.resize = .{ .resize = .{

View File

@ -383,7 +383,6 @@ pub fn render(
// Data we extract out of the critical area. // Data we extract out of the critical area.
const Critical = struct { const Critical = struct {
bg: terminal.color.RGB, bg: terminal.color.RGB,
screen_size: ?renderer.ScreenSize,
devmode: bool, devmode: bool,
selection: ?terminal.Selection, selection: ?terminal.Selection,
screen: terminal.Screen, screen: terminal.Screen,
@ -431,12 +430,8 @@ pub fn render(
); );
errdefer screen_copy.deinit(); errdefer screen_copy.deinit();
// We set this in the state below
defer state.resize_screen = null;
break :critical .{ break :critical .{
.bg = self.background, .bg = self.background,
.screen_size = state.resize_screen,
.devmode = if (state.devmode) |dm| dm.visible else false, .devmode = if (state.devmode) |dm| dm.visible else false,
.selection = state.terminal.selection, .selection = state.terminal.selection,
.screen = screen_copy, .screen = screen_copy,
@ -449,26 +444,6 @@ pub fn render(
const pool = objc.AutoreleasePool.init(); const pool = objc.AutoreleasePool.init();
defer pool.deinit(); 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 // Build our GPU cells
try self.rebuildCells( try self.rebuildCells(
critical.selection, critical.selection,
@ -614,7 +589,17 @@ pub fn render(
} }
/// Resize the screen. /// 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 // Easier to work with our own types
const dim: renderer.ScreenSize = .{ const dim: renderer.ScreenSize = .{
.width = @floatToInt(u32, bounds.width), .width = @floatToInt(u32, bounds.width),

View File

@ -533,7 +533,6 @@ pub fn render(
const Critical = struct { const Critical = struct {
gl_bg: terminal.color.RGB, gl_bg: terminal.color.RGB,
devmode_data: ?*imgui.DrawData, devmode_data: ?*imgui.DrawData,
screen_size: ?renderer.ScreenSize,
active_screen: terminal.Terminal.ScreenType, active_screen: terminal.Terminal.ScreenType,
selection: ?terminal.Selection, selection: ?terminal.Selection,
screen: terminal.Screen, screen: terminal.Screen,
@ -595,13 +594,9 @@ pub fn render(
); );
errdefer screen_copy.deinit(); errdefer screen_copy.deinit();
// We set this in the state below
defer state.resize_screen = null;
break :critical .{ break :critical .{
.gl_bg = self.background, .gl_bg = self.background,
.devmode_data = devmode_data, .devmode_data = devmode_data,
.screen_size = state.resize_screen,
.active_screen = state.terminal.active_screen, .active_screen = state.terminal.active_screen,
.selection = state.terminal.selection, .selection = state.terminal.selection,
.screen = screen_copy, .screen = screen_copy,
@ -610,12 +605,6 @@ pub fn render(
}; };
defer critical.screen.deinit(); 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 // Build our GPU cells
try self.rebuildCells( try self.rebuildCells(
critical.active_screen, 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 /// Set the screen size for rendering. This will update the projection
/// used for the shader so that the scaling of the grid is correct. /// 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. // Recalculate the rows/columns.
const grid_size = self.gridSize(dim); const grid_size = self.gridSize(dim);

View File

@ -12,9 +12,6 @@ const renderer = @import("../renderer.zig");
/// state (i.e. the terminal, devmode, etc. values). /// state (i.e. the terminal, devmode, etc. values).
mutex: *std.Thread.Mutex, mutex: *std.Thread.Mutex,
/// A new screen size if the screen was resized.
resize_screen: ?renderer.ScreenSize,
/// Cursor configuration for rendering /// Cursor configuration for rendering
cursor: Cursor, cursor: Cursor,

View File

@ -279,6 +279,10 @@ fn drainMailbox(self: *Thread) !void {
.font_size => |size| { .font_size => |size| {
try self.renderer.setFontSize(size); try self.renderer.setFontSize(size);
}, },
.screen_size => |size| {
try self.renderer.setScreenSize(size);
},
} }
} }
} }

View File

@ -2,6 +2,7 @@ const std = @import("std");
const assert = std.debug.assert; const assert = std.debug.assert;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const font = @import("../font/main.zig"); const font = @import("../font/main.zig");
const renderer = @import("../renderer.zig");
/// The messages that can be sent to a renderer thread. /// The messages that can be sent to a renderer thread.
pub const Message = union(enum) { 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 /// send a grid size change message back to the window thread if
/// the size changes. /// the size changes.
font_size: font.face.DesiredSize, font_size: font.face.DesiredSize,
/// Change the screen size.
screen_size: renderer.ScreenSize,
}; };

View File

@ -249,9 +249,6 @@ pub fn resize(
self.renderer_state.mutex.lock(); self.renderer_state.mutex.lock();
defer self.renderer_state.mutex.unlock(); 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 // Update the size of our terminal state
try self.terminal.resize(self.alloc, grid_size.columns, grid_size.rows); try self.terminal.resize(self.alloc, grid_size.columns, grid_size.rows);
} }