mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
renderer/metal: use new size struct
This commit is contained in:
@ -397,20 +397,6 @@ pub fn init(
|
||||
.right = padding_right,
|
||||
};
|
||||
|
||||
// Create our terminal grid with the initial size
|
||||
const app_mailbox: App.Mailbox = .{ .rt_app = rt_app, .mailbox = &app.mailbox };
|
||||
var renderer_impl = try Renderer.init(alloc, .{
|
||||
.config = try Renderer.DerivedConfig.init(alloc, config),
|
||||
.font_grid = font_grid,
|
||||
.padding = .{
|
||||
.explicit = padding,
|
||||
.balance = config.@"window-padding-balance",
|
||||
},
|
||||
.surface_mailbox = .{ .surface = self, .app = app_mailbox },
|
||||
.rt_surface = rt_surface,
|
||||
});
|
||||
errdefer renderer_impl.deinit();
|
||||
|
||||
// Build our size struct which has all the sizes we need.
|
||||
const size: renderer.Size = size: {
|
||||
var size: renderer.Size = .{
|
||||
@ -433,6 +419,17 @@ pub fn init(
|
||||
break :size size;
|
||||
};
|
||||
|
||||
// Create our terminal grid with the initial size
|
||||
const app_mailbox: App.Mailbox = .{ .rt_app = rt_app, .mailbox = &app.mailbox };
|
||||
var renderer_impl = try Renderer.init(alloc, .{
|
||||
.config = try Renderer.DerivedConfig.init(alloc, config),
|
||||
.font_grid = font_grid,
|
||||
.size = size,
|
||||
.surface_mailbox = .{ .surface = self, .app = app_mailbox },
|
||||
.rt_surface = rt_surface,
|
||||
});
|
||||
errdefer renderer_impl.deinit();
|
||||
|
||||
// The mutex used to protect our renderer state.
|
||||
const mutex = try alloc.create(std.Thread.Mutex);
|
||||
mutex.* = .{};
|
||||
|
@ -70,12 +70,8 @@ surface_mailbox: apprt.surface.Mailbox,
|
||||
/// Current font metrics defining our grid.
|
||||
grid_metrics: font.face.Metrics,
|
||||
|
||||
/// Current screen size dimensions for this grid. This is set on the first
|
||||
/// resize event, and is not immediately available.
|
||||
screen_size: ?renderer.ScreenSize,
|
||||
|
||||
/// Explicit padding.
|
||||
padding: renderer.Options.Padding,
|
||||
/// The size of everything.
|
||||
size: renderer.Size,
|
||||
|
||||
/// True if the window is focused
|
||||
focused: bool,
|
||||
@ -631,8 +627,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
|
||||
.config = options.config,
|
||||
.surface_mailbox = options.surface_mailbox,
|
||||
.grid_metrics = font_critical.metrics,
|
||||
.screen_size = null,
|
||||
.padding = options.padding,
|
||||
.size = options.size,
|
||||
.focused = true,
|
||||
.foreground_color = options.config.foreground,
|
||||
.background_color = options.config.background,
|
||||
@ -796,19 +791,6 @@ pub fn hasVsync(self: *const Metal) bool {
|
||||
return display_link.isRunning();
|
||||
}
|
||||
|
||||
/// Returns the grid size for a given screen size. This is safe to call
|
||||
/// on any thread.
|
||||
fn gridSize(self: *Metal) ?renderer.GridSize {
|
||||
const screen_size = self.screen_size orelse return null;
|
||||
return renderer.GridSize.init(
|
||||
screen_size.subPadding(self.padding.explicit),
|
||||
.{
|
||||
.width = self.grid_metrics.cell_width,
|
||||
.height = self.grid_metrics.cell_height,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Callback when the focus changes for the terminal this is rendering.
|
||||
///
|
||||
/// Must be called on the render thread.
|
||||
@ -878,15 +860,13 @@ pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) void {
|
||||
//
|
||||
// If the screen size isn't set, it will be eventually so that'll call
|
||||
// the setScreenSize automatically.
|
||||
if (self.screen_size) |size| {
|
||||
self.setScreenSize(size, self.padding.explicit) catch |err| {
|
||||
// The setFontGrid function can't fail but resizing our cell
|
||||
// buffer definitely can fail. If it does, our renderer is probably
|
||||
// screwed but let's just log it and continue until we can figure
|
||||
// out a better way to handle this.
|
||||
log.err("error resizing cells buffer err={}", .{err});
|
||||
};
|
||||
}
|
||||
self.setScreenSize(self.size) catch |err| {
|
||||
// The setFontGrid function can't fail but resizing our cell
|
||||
// buffer definitely can fail. If it does, our renderer is probably
|
||||
// screwed but let's just log it and continue until we can figure
|
||||
// out a better way to handle this.
|
||||
log.err("error resizing cells buffer err={}", .{err});
|
||||
};
|
||||
}
|
||||
|
||||
/// Update the frame data.
|
||||
@ -898,9 +878,6 @@ pub fn updateFrame(
|
||||
) !void {
|
||||
_ = surface;
|
||||
|
||||
// If we don't have a screen size yet then we can't render anything.
|
||||
if (self.screen_size == null) return;
|
||||
|
||||
// Data we extract out of the critical area.
|
||||
const Critical = struct {
|
||||
bg: terminal.color.RGB,
|
||||
@ -1116,9 +1093,6 @@ pub fn updateFrame(
|
||||
pub fn drawFrame(self: *Metal, surface: *apprt.Surface) !void {
|
||||
_ = surface;
|
||||
|
||||
// If we don't have a screen size yet then we can't render anything.
|
||||
if (self.screen_size == null) return;
|
||||
|
||||
// If we have no cells rebuilt we can usually skip drawing since there
|
||||
// is no changed data. However, if we have active animations we still
|
||||
// need to draw so that we can update the time uniform and render the
|
||||
@ -1972,38 +1946,19 @@ pub fn changeConfig(self: *Metal, config: *DerivedConfig) !void {
|
||||
/// Resize the screen.
|
||||
pub fn setScreenSize(
|
||||
self: *Metal,
|
||||
dim: renderer.ScreenSize,
|
||||
pad: renderer.Padding,
|
||||
size: renderer.Size,
|
||||
) !void {
|
||||
// Store our sizes
|
||||
self.screen_size = dim;
|
||||
self.padding.explicit = pad;
|
||||
|
||||
// Recalculate the rows/columns. This can't fail since we just set
|
||||
// the screen size above.
|
||||
const grid_size = self.gridSize().?;
|
||||
|
||||
// Determine if we need to pad the window. For "auto" padding, we take
|
||||
// the leftover amounts on the right/bottom that don't fit a full grid cell
|
||||
// and we split them equal across all boundaries.
|
||||
const padding = if (self.padding.balance)
|
||||
renderer.Padding.balanced(
|
||||
dim,
|
||||
grid_size,
|
||||
.{
|
||||
.width = self.grid_metrics.cell_width,
|
||||
.height = self.grid_metrics.cell_height,
|
||||
},
|
||||
)
|
||||
else
|
||||
self.padding.explicit;
|
||||
const padded_dim = dim.subPadding(padding);
|
||||
self.size = size;
|
||||
const grid_size = size.grid();
|
||||
const terminal_size = size.terminal();
|
||||
|
||||
// Blank space around the grid.
|
||||
const blank: renderer.Padding = dim.blankPadding(padding, grid_size, .{
|
||||
.width = self.grid_metrics.cell_width,
|
||||
.height = self.grid_metrics.cell_height,
|
||||
}).add(padding);
|
||||
const blank: renderer.Padding = size.screen.blankPadding(
|
||||
size.padding,
|
||||
grid_size,
|
||||
size.cell,
|
||||
).add(size.padding);
|
||||
|
||||
var padding_extend = self.uniforms.padding_extend;
|
||||
switch (self.config.padding_color) {
|
||||
@ -2030,18 +1985,18 @@ pub fn setScreenSize(
|
||||
|
||||
// Set the size of the drawable surface to the bounds
|
||||
self.layer.setProperty("drawableSize", macos.graphics.Size{
|
||||
.width = @floatFromInt(dim.width),
|
||||
.height = @floatFromInt(dim.height),
|
||||
.width = @floatFromInt(size.screen.width),
|
||||
.height = @floatFromInt(size.screen.height),
|
||||
});
|
||||
|
||||
// Setup our uniforms
|
||||
const old = self.uniforms;
|
||||
self.uniforms = .{
|
||||
.projection_matrix = math.ortho2d(
|
||||
-1 * @as(f32, @floatFromInt(padding.left)),
|
||||
@floatFromInt(padded_dim.width + padding.right),
|
||||
@floatFromInt(padded_dim.height + padding.bottom),
|
||||
-1 * @as(f32, @floatFromInt(padding.top)),
|
||||
-1 * @as(f32, @floatFromInt(size.padding.left)),
|
||||
@floatFromInt(terminal_size.width + size.padding.right),
|
||||
@floatFromInt(terminal_size.height + size.padding.bottom),
|
||||
-1 * @as(f32, @floatFromInt(size.padding.top)),
|
||||
),
|
||||
.cell_size = .{
|
||||
@floatFromInt(self.grid_metrics.cell_width),
|
||||
@ -2082,8 +2037,8 @@ pub fn setScreenSize(
|
||||
}
|
||||
|
||||
state.uniforms.resolution = .{
|
||||
@floatFromInt(dim.width),
|
||||
@floatFromInt(dim.height),
|
||||
@floatFromInt(size.screen.width),
|
||||
@floatFromInt(size.screen.height),
|
||||
1,
|
||||
};
|
||||
|
||||
@ -2097,8 +2052,8 @@ pub fn setScreenSize(
|
||||
break :init id_init;
|
||||
};
|
||||
desc.setProperty("pixelFormat", @intFromEnum(mtl.MTLPixelFormat.bgra8unorm));
|
||||
desc.setProperty("width", @as(c_ulong, @intCast(dim.width)));
|
||||
desc.setProperty("height", @as(c_ulong, @intCast(dim.height)));
|
||||
desc.setProperty("width", @as(c_ulong, @intCast(size.screen.width)));
|
||||
desc.setProperty("height", @as(c_ulong, @intCast(size.screen.height)));
|
||||
desc.setProperty(
|
||||
"usage",
|
||||
@intFromEnum(mtl.MTLTextureUsage.render_target) |
|
||||
@ -2127,8 +2082,8 @@ pub fn setScreenSize(
|
||||
break :init id_init;
|
||||
};
|
||||
desc.setProperty("pixelFormat", @intFromEnum(mtl.MTLPixelFormat.bgra8unorm));
|
||||
desc.setProperty("width", @as(c_ulong, @intCast(dim.width)));
|
||||
desc.setProperty("height", @as(c_ulong, @intCast(dim.height)));
|
||||
desc.setProperty("width", @as(c_ulong, @intCast(size.screen.width)));
|
||||
desc.setProperty("height", @as(c_ulong, @intCast(size.screen.height)));
|
||||
desc.setProperty(
|
||||
"usage",
|
||||
@intFromEnum(mtl.MTLTextureUsage.render_target) |
|
||||
@ -2148,7 +2103,7 @@ pub fn setScreenSize(
|
||||
};
|
||||
}
|
||||
|
||||
log.debug("screen size screen={} grid={}, cell_width={} cell_height={}", .{ dim, grid_size, self.grid_metrics.cell_width, self.grid_metrics.cell_height });
|
||||
log.debug("screen size size={}", .{size});
|
||||
}
|
||||
|
||||
/// Convert the terminal state to GPU cells stored in CPU memory. These
|
||||
|
@ -11,8 +11,8 @@ config: renderer.Renderer.DerivedConfig,
|
||||
/// The font grid that should be used along with the key for deref-ing.
|
||||
font_grid: *font.SharedGrid,
|
||||
|
||||
/// Padding options for the viewport.
|
||||
padding: Padding,
|
||||
/// The size of everything.
|
||||
size: renderer.Size,
|
||||
|
||||
/// The mailbox for sending the surface messages. This is only valid
|
||||
/// once the thread has started and should not be used outside of the thread.
|
||||
|
@ -371,10 +371,7 @@ fn drainMailbox(self: *Thread) !void {
|
||||
self.renderer.markDirty();
|
||||
},
|
||||
|
||||
.resize => |v| try self.renderer.setScreenSize(
|
||||
v.screen,
|
||||
v.padding,
|
||||
),
|
||||
.resize => |v| try self.renderer.setScreenSize(v),
|
||||
|
||||
.change_config => |config| {
|
||||
defer config.alloc.destroy(config.thread);
|
||||
|
Reference in New Issue
Block a user