metal: use content scale when resizing

This commit is contained in:
Mitchell Hashimoto
2022-10-29 19:16:41 -07:00
parent ea0265f021
commit 6b7ed3fefb

View File

@ -37,6 +37,9 @@ background: terminal.color.RGB,
/// but we keep this around so that we don't reallocate. /// but we keep this around so that we don't reallocate.
cells: std.ArrayListUnmanaged(GPUCell), cells: std.ArrayListUnmanaged(GPUCell),
/// The current GPU uniform values.
uniforms: GPUUniforms,
/// The font structures. /// The font structures.
font_group: *font.GroupCache, font_group: *font.GroupCache,
font_shaper: font.Shaper, font_shaper: font.Shaper,
@ -247,6 +250,7 @@ pub fn init(alloc: Allocator, font_group: *font.GroupCache) !Metal {
// Render state // Render state
.cells = .{}, .cells = .{},
.uniforms = undefined,
// Fonts // Fonts
.font_group = font_group, .font_group = font_group,
@ -307,6 +311,7 @@ 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,
}; };
// Update all our data as tightly as possible within the mutex. // Update all our data as tightly as possible within the mutex.
@ -335,6 +340,7 @@ pub fn render(
break :critical .{ break :critical .{
.bg = self.background, .bg = self.background,
.screen_size = state.resize_screen,
}; };
}; };
@ -342,12 +348,20 @@ pub fn render(
const pool = objc_autoreleasePoolPush(); const pool = objc_autoreleasePoolPush();
defer objc_autoreleasePoolPop(pool); defer objc_autoreleasePoolPop(pool);
// Ensure our layer size is always updated // If we're resizing, then we have to update a bunch of things...
if (critical.screen_size) |screen_size| {
const bounds = self.swapchain.getProperty(macos.graphics.Rect, "bounds"); const bounds = self.swapchain.getProperty(macos.graphics.Rect, "bounds");
// Set the size of the drawable surface to the bounds of our surface.
self.swapchain.setProperty("drawableSize", bounds.size); self.swapchain.setProperty("drawableSize", bounds.size);
// Our drawable surface is usually scaled so we need to figure
// out the scalem amount so our pixels are correct.
const scaleX = @floatCast(f32, bounds.size.width) / @intToFloat(f32, screen_size.width);
const scaleY = @floatCast(f32, bounds.size.height) / @intToFloat(f32, screen_size.height);
// Setup our uniforms // Setup our uniforms
const uniforms: GPUUniforms = .{ self.uniforms = .{
.projection_matrix = math.ortho2d( .projection_matrix = math.ortho2d(
0, 0,
@floatCast(f32, bounds.size.width), @floatCast(f32, bounds.size.width),
@ -355,9 +369,12 @@ pub fn render(
0, 0,
), ),
// TODO: get content scale to scale these .cell_size = .{
.cell_size = .{ self.cell_size.width / 2, self.cell_size.height / 2 }, self.cell_size.width * scaleX,
self.cell_size.height * scaleY,
},
}; };
}
// Get our surface (CAMetalDrawable) // Get our surface (CAMetalDrawable)
const surface = self.swapchain.msgSend(objc.Object, objc.sel("nextDrawable"), .{}); const surface = self.swapchain.msgSend(objc.Object, objc.sel("nextDrawable"), .{});
@ -422,8 +439,8 @@ pub fn render(
void, void,
objc.sel("setVertexBytes:length:atIndex:"), objc.sel("setVertexBytes:length:atIndex:"),
.{ .{
@ptrCast(*const anyopaque, &uniforms), @ptrCast(*const anyopaque, &self.uniforms),
@as(c_ulong, @sizeOf(@TypeOf(uniforms))), @as(c_ulong, @sizeOf(@TypeOf(self.uniforms))),
@as(c_ulong, 1), @as(c_ulong, 1),
}, },
); );