mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
renderer/metal: use new size struct
This commit is contained in:
@ -397,20 +397,6 @@ pub fn init(
|
|||||||
.right = padding_right,
|
.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.
|
// Build our size struct which has all the sizes we need.
|
||||||
const size: renderer.Size = size: {
|
const size: renderer.Size = size: {
|
||||||
var size: renderer.Size = .{
|
var size: renderer.Size = .{
|
||||||
@ -433,6 +419,17 @@ pub fn init(
|
|||||||
break :size size;
|
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.
|
// The mutex used to protect our renderer state.
|
||||||
const mutex = try alloc.create(std.Thread.Mutex);
|
const mutex = try alloc.create(std.Thread.Mutex);
|
||||||
mutex.* = .{};
|
mutex.* = .{};
|
||||||
|
@ -70,12 +70,8 @@ surface_mailbox: apprt.surface.Mailbox,
|
|||||||
/// Current font metrics defining our grid.
|
/// Current font metrics defining our grid.
|
||||||
grid_metrics: font.face.Metrics,
|
grid_metrics: font.face.Metrics,
|
||||||
|
|
||||||
/// Current screen size dimensions for this grid. This is set on the first
|
/// The size of everything.
|
||||||
/// resize event, and is not immediately available.
|
size: renderer.Size,
|
||||||
screen_size: ?renderer.ScreenSize,
|
|
||||||
|
|
||||||
/// Explicit padding.
|
|
||||||
padding: renderer.Options.Padding,
|
|
||||||
|
|
||||||
/// True if the window is focused
|
/// True if the window is focused
|
||||||
focused: bool,
|
focused: bool,
|
||||||
@ -631,8 +627,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
|
|||||||
.config = options.config,
|
.config = options.config,
|
||||||
.surface_mailbox = options.surface_mailbox,
|
.surface_mailbox = options.surface_mailbox,
|
||||||
.grid_metrics = font_critical.metrics,
|
.grid_metrics = font_critical.metrics,
|
||||||
.screen_size = null,
|
.size = options.size,
|
||||||
.padding = options.padding,
|
|
||||||
.focused = true,
|
.focused = true,
|
||||||
.foreground_color = options.config.foreground,
|
.foreground_color = options.config.foreground,
|
||||||
.background_color = options.config.background,
|
.background_color = options.config.background,
|
||||||
@ -796,19 +791,6 @@ pub fn hasVsync(self: *const Metal) bool {
|
|||||||
return display_link.isRunning();
|
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.
|
/// Callback when the focus changes for the terminal this is rendering.
|
||||||
///
|
///
|
||||||
/// Must be called on the render thread.
|
/// Must be called on the render thread.
|
||||||
@ -878,8 +860,7 @@ pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) void {
|
|||||||
//
|
//
|
||||||
// If the screen size isn't set, it will be eventually so that'll call
|
// If the screen size isn't set, it will be eventually so that'll call
|
||||||
// the setScreenSize automatically.
|
// the setScreenSize automatically.
|
||||||
if (self.screen_size) |size| {
|
self.setScreenSize(self.size) catch |err| {
|
||||||
self.setScreenSize(size, self.padding.explicit) catch |err| {
|
|
||||||
// The setFontGrid function can't fail but resizing our cell
|
// The setFontGrid function can't fail but resizing our cell
|
||||||
// buffer definitely can fail. If it does, our renderer is probably
|
// buffer definitely can fail. If it does, our renderer is probably
|
||||||
// screwed but let's just log it and continue until we can figure
|
// screwed but let's just log it and continue until we can figure
|
||||||
@ -887,7 +868,6 @@ pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) void {
|
|||||||
log.err("error resizing cells buffer err={}", .{err});
|
log.err("error resizing cells buffer err={}", .{err});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Update the frame data.
|
/// Update the frame data.
|
||||||
pub fn updateFrame(
|
pub fn updateFrame(
|
||||||
@ -898,9 +878,6 @@ pub fn updateFrame(
|
|||||||
) !void {
|
) !void {
|
||||||
_ = surface;
|
_ = 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.
|
// Data we extract out of the critical area.
|
||||||
const Critical = struct {
|
const Critical = struct {
|
||||||
bg: terminal.color.RGB,
|
bg: terminal.color.RGB,
|
||||||
@ -1116,9 +1093,6 @@ pub fn updateFrame(
|
|||||||
pub fn drawFrame(self: *Metal, surface: *apprt.Surface) !void {
|
pub fn drawFrame(self: *Metal, surface: *apprt.Surface) !void {
|
||||||
_ = surface;
|
_ = 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
|
// 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
|
// 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
|
// 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.
|
/// Resize the screen.
|
||||||
pub fn setScreenSize(
|
pub fn setScreenSize(
|
||||||
self: *Metal,
|
self: *Metal,
|
||||||
dim: renderer.ScreenSize,
|
size: renderer.Size,
|
||||||
pad: renderer.Padding,
|
|
||||||
) !void {
|
) !void {
|
||||||
// Store our sizes
|
// Store our sizes
|
||||||
self.screen_size = dim;
|
self.size = size;
|
||||||
self.padding.explicit = pad;
|
const grid_size = size.grid();
|
||||||
|
const terminal_size = size.terminal();
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Blank space around the grid.
|
// Blank space around the grid.
|
||||||
const blank: renderer.Padding = dim.blankPadding(padding, grid_size, .{
|
const blank: renderer.Padding = size.screen.blankPadding(
|
||||||
.width = self.grid_metrics.cell_width,
|
size.padding,
|
||||||
.height = self.grid_metrics.cell_height,
|
grid_size,
|
||||||
}).add(padding);
|
size.cell,
|
||||||
|
).add(size.padding);
|
||||||
|
|
||||||
var padding_extend = self.uniforms.padding_extend;
|
var padding_extend = self.uniforms.padding_extend;
|
||||||
switch (self.config.padding_color) {
|
switch (self.config.padding_color) {
|
||||||
@ -2030,18 +1985,18 @@ pub fn setScreenSize(
|
|||||||
|
|
||||||
// Set the size of the drawable surface to the bounds
|
// Set the size of the drawable surface to the bounds
|
||||||
self.layer.setProperty("drawableSize", macos.graphics.Size{
|
self.layer.setProperty("drawableSize", macos.graphics.Size{
|
||||||
.width = @floatFromInt(dim.width),
|
.width = @floatFromInt(size.screen.width),
|
||||||
.height = @floatFromInt(dim.height),
|
.height = @floatFromInt(size.screen.height),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Setup our uniforms
|
// Setup our uniforms
|
||||||
const old = self.uniforms;
|
const old = self.uniforms;
|
||||||
self.uniforms = .{
|
self.uniforms = .{
|
||||||
.projection_matrix = math.ortho2d(
|
.projection_matrix = math.ortho2d(
|
||||||
-1 * @as(f32, @floatFromInt(padding.left)),
|
-1 * @as(f32, @floatFromInt(size.padding.left)),
|
||||||
@floatFromInt(padded_dim.width + padding.right),
|
@floatFromInt(terminal_size.width + size.padding.right),
|
||||||
@floatFromInt(padded_dim.height + padding.bottom),
|
@floatFromInt(terminal_size.height + size.padding.bottom),
|
||||||
-1 * @as(f32, @floatFromInt(padding.top)),
|
-1 * @as(f32, @floatFromInt(size.padding.top)),
|
||||||
),
|
),
|
||||||
.cell_size = .{
|
.cell_size = .{
|
||||||
@floatFromInt(self.grid_metrics.cell_width),
|
@floatFromInt(self.grid_metrics.cell_width),
|
||||||
@ -2082,8 +2037,8 @@ pub fn setScreenSize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.uniforms.resolution = .{
|
state.uniforms.resolution = .{
|
||||||
@floatFromInt(dim.width),
|
@floatFromInt(size.screen.width),
|
||||||
@floatFromInt(dim.height),
|
@floatFromInt(size.screen.height),
|
||||||
1,
|
1,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2097,8 +2052,8 @@ pub fn setScreenSize(
|
|||||||
break :init id_init;
|
break :init id_init;
|
||||||
};
|
};
|
||||||
desc.setProperty("pixelFormat", @intFromEnum(mtl.MTLPixelFormat.bgra8unorm));
|
desc.setProperty("pixelFormat", @intFromEnum(mtl.MTLPixelFormat.bgra8unorm));
|
||||||
desc.setProperty("width", @as(c_ulong, @intCast(dim.width)));
|
desc.setProperty("width", @as(c_ulong, @intCast(size.screen.width)));
|
||||||
desc.setProperty("height", @as(c_ulong, @intCast(dim.height)));
|
desc.setProperty("height", @as(c_ulong, @intCast(size.screen.height)));
|
||||||
desc.setProperty(
|
desc.setProperty(
|
||||||
"usage",
|
"usage",
|
||||||
@intFromEnum(mtl.MTLTextureUsage.render_target) |
|
@intFromEnum(mtl.MTLTextureUsage.render_target) |
|
||||||
@ -2127,8 +2082,8 @@ pub fn setScreenSize(
|
|||||||
break :init id_init;
|
break :init id_init;
|
||||||
};
|
};
|
||||||
desc.setProperty("pixelFormat", @intFromEnum(mtl.MTLPixelFormat.bgra8unorm));
|
desc.setProperty("pixelFormat", @intFromEnum(mtl.MTLPixelFormat.bgra8unorm));
|
||||||
desc.setProperty("width", @as(c_ulong, @intCast(dim.width)));
|
desc.setProperty("width", @as(c_ulong, @intCast(size.screen.width)));
|
||||||
desc.setProperty("height", @as(c_ulong, @intCast(dim.height)));
|
desc.setProperty("height", @as(c_ulong, @intCast(size.screen.height)));
|
||||||
desc.setProperty(
|
desc.setProperty(
|
||||||
"usage",
|
"usage",
|
||||||
@intFromEnum(mtl.MTLTextureUsage.render_target) |
|
@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
|
/// 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.
|
/// The font grid that should be used along with the key for deref-ing.
|
||||||
font_grid: *font.SharedGrid,
|
font_grid: *font.SharedGrid,
|
||||||
|
|
||||||
/// Padding options for the viewport.
|
/// The size of everything.
|
||||||
padding: Padding,
|
size: renderer.Size,
|
||||||
|
|
||||||
/// The mailbox for sending the surface messages. This is only valid
|
/// 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.
|
/// 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();
|
self.renderer.markDirty();
|
||||||
},
|
},
|
||||||
|
|
||||||
.resize => |v| try self.renderer.setScreenSize(
|
.resize => |v| try self.renderer.setScreenSize(v),
|
||||||
v.screen,
|
|
||||||
v.padding,
|
|
||||||
),
|
|
||||||
|
|
||||||
.change_config => |config| {
|
.change_config => |config| {
|
||||||
defer config.alloc.destroy(config.thread);
|
defer config.alloc.destroy(config.thread);
|
||||||
|
Reference in New Issue
Block a user