renderer/metal: grid pos for bg/text should be ushort2

This saves 50% memory per vertex.
This commit is contained in:
Mitchell Hashimoto
2024-04-25 19:16:40 -07:00
parent 15b7a37cf9
commit ced8776120
5 changed files with 32 additions and 30 deletions

View File

@ -1751,8 +1751,8 @@ fn rebuildCells(
// Determine our x/y range for preedit. We don't want to render anything // Determine our x/y range for preedit. We don't want to render anything
// here because we will render the preedit separately. // here because we will render the preedit separately.
const preedit_range: ?struct { const preedit_range: ?struct {
y: usize, y: terminal.size.CellCountInt,
x: [2]usize, x: [2]terminal.size.CellCountInt,
cp_offset: usize, cp_offset: usize,
} = if (preedit) |preedit_v| preedit: { } = if (preedit) |preedit_v| preedit: {
const range = preedit_v.range(screen.cursor.x, screen.pages.cols - 1); const range = preedit_v.range(screen.cursor.x, screen.pages.cols - 1);
@ -1770,7 +1770,7 @@ fn rebuildCells(
// Build each cell // Build each cell
var row_it = screen.pages.rowIterator(.right_down, .{ .viewport = .{} }, null); var row_it = screen.pages.rowIterator(.right_down, .{ .viewport = .{} }, null);
var y: usize = 0; var y: terminal.size.CellCountInt = 0;
while (row_it.next()) |row| { while (row_it.next()) |row| {
defer y += 1; defer y += 1;
@ -1809,7 +1809,7 @@ fn rebuildCells(
const screen_cell = row.cells(.all)[screen.cursor.x]; const screen_cell = row.cells(.all)[screen.cursor.x];
const x = screen.cursor.x - @intFromBool(screen_cell.wide == .spacer_tail); const x = screen.cursor.x - @intFromBool(screen_cell.wide == .spacer_tail);
for (self.cells_text.items[start_i..]) |cell| { for (self.cells_text.items[start_i..]) |cell| {
if (cell.grid_pos[0] == @as(f32, @floatFromInt(x)) and if (cell.grid_pos[0] == x and
(cell.mode == .fg or cell.mode == .fg_color)) (cell.mode == .fg or cell.mode == .fg_color))
{ {
cursor_cell = cell; cursor_cell = cell;
@ -1929,8 +1929,8 @@ fn updateCell(
palette: *const terminal.color.Palette, palette: *const terminal.color.Palette,
shaper_cell: font.shape.Cell, shaper_cell: font.shape.Cell,
shaper_run: font.shape.TextRun, shaper_run: font.shape.TextRun,
x: usize, x: terminal.size.CellCountInt,
y: usize, y: terminal.size.CellCountInt,
) !bool { ) !bool {
const BgFg = struct { const BgFg = struct {
/// Background is optional because in un-inverted mode /// Background is optional because in un-inverted mode
@ -2031,7 +2031,7 @@ fn updateCell(
self.cells_bg.appendAssumeCapacity(.{ self.cells_bg.appendAssumeCapacity(.{
.mode = .rgb, .mode = .rgb,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) }, .grid_pos = .{ x, y },
.cell_width = cell.gridWidth(), .cell_width = cell.gridWidth(),
.color = .{ rgb.r, rgb.g, rgb.b, bg_alpha }, .color = .{ rgb.r, rgb.g, rgb.b, bg_alpha },
}); });
@ -2068,7 +2068,7 @@ fn updateCell(
self.cells_text.appendAssumeCapacity(.{ self.cells_text.appendAssumeCapacity(.{
.mode = mode, .mode = mode,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) }, .grid_pos = .{ x, y },
.cell_width = cell.gridWidth(), .cell_width = cell.gridWidth(),
.color = .{ colors.fg.r, colors.fg.g, colors.fg.b, alpha }, .color = .{ colors.fg.r, colors.fg.g, colors.fg.b, alpha },
.bg_color = bg, .bg_color = bg,
@ -2105,7 +2105,7 @@ fn updateCell(
self.cells_text.appendAssumeCapacity(.{ self.cells_text.appendAssumeCapacity(.{
.mode = .fg, .mode = .fg,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) }, .grid_pos = .{ x, y },
.cell_width = cell.gridWidth(), .cell_width = cell.gridWidth(),
.color = .{ color.r, color.g, color.b, alpha }, .color = .{ color.r, color.g, color.b, alpha },
.bg_color = bg, .bg_color = bg,
@ -2128,7 +2128,7 @@ fn updateCell(
self.cells_text.appendAssumeCapacity(.{ self.cells_text.appendAssumeCapacity(.{
.mode = .fg, .mode = .fg,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) }, .grid_pos = .{ x, y },
.cell_width = cell.gridWidth(), .cell_width = cell.gridWidth(),
.color = .{ colors.fg.r, colors.fg.g, colors.fg.b, alpha }, .color = .{ colors.fg.r, colors.fg.g, colors.fg.b, alpha },
.bg_color = bg, .bg_color = bg,
@ -2188,10 +2188,7 @@ fn addCursor(
self.cells_text.appendAssumeCapacity(.{ self.cells_text.appendAssumeCapacity(.{
.mode = .fg, .mode = .fg,
.grid_pos = .{ .grid_pos = .{ x, screen.cursor.y },
@as(f32, @floatFromInt(x)),
@as(f32, @floatFromInt(screen.cursor.y)),
},
.cell_width = if (wide) 2 else 1, .cell_width = if (wide) 2 else 1,
.color = .{ color.r, color.g, color.b, alpha }, .color = .{ color.r, color.g, color.b, alpha },
.bg_color = .{ 0, 0, 0, 0 }, .bg_color = .{ 0, 0, 0, 0 },
@ -2206,8 +2203,8 @@ fn addCursor(
fn addPreeditCell( fn addPreeditCell(
self: *Metal, self: *Metal,
cp: renderer.State.Preedit.Codepoint, cp: renderer.State.Preedit.Codepoint,
x: usize, x: terminal.size.CellCountInt,
y: usize, y: terminal.size.CellCountInt,
) !void { ) !void {
// Preedit is rendered inverted // Preedit is rendered inverted
const bg = self.foreground_color; const bg = self.foreground_color;
@ -2232,7 +2229,7 @@ fn addPreeditCell(
// Add our opaque background cell // Add our opaque background cell
self.cells_bg.appendAssumeCapacity(.{ self.cells_bg.appendAssumeCapacity(.{
.mode = .rgb, .mode = .rgb,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) }, .grid_pos = .{ x, y },
.cell_width = if (cp.wide) 2 else 1, .cell_width = if (cp.wide) 2 else 1,
.color = .{ bg.r, bg.g, bg.b, 255 }, .color = .{ bg.r, bg.g, bg.b, 255 },
}); });
@ -2240,7 +2237,7 @@ fn addPreeditCell(
// Add our text // Add our text
self.cells_text.appendAssumeCapacity(.{ self.cells_text.appendAssumeCapacity(.{
.mode = .fg, .mode = .fg,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) }, .grid_pos = .{ x, y },
.cell_width = if (cp.wide) 2 else 1, .cell_width = if (cp.wide) 2 else 1,
.color = .{ fg.r, fg.g, fg.b, 255 }, .color = .{ fg.r, fg.g, fg.b, 255 },
.bg_color = .{ bg.r, bg.g, bg.b, 255 }, .bg_color = .{ bg.r, bg.g, bg.b, 255 },

View File

@ -78,9 +78,13 @@ pub const Preedit = struct {
/// Range returns the start and end x position of the preedit text /// Range returns the start and end x position of the preedit text
/// along with any codepoint offset necessary to fit the preedit /// along with any codepoint offset necessary to fit the preedit
/// into the available space. /// into the available space.
pub fn range(self: *const Preedit, start: usize, max: usize) struct { pub fn range(
start: usize, self: *const Preedit,
end: usize, start: terminal.size.CellCountInt,
max: terminal.size.CellCountInt,
) struct {
start: terminal.size.CellCountInt,
end: terminal.size.CellCountInt,
cp_offset: usize, cp_offset: usize,
} { } {
// If our width is greater than the number of cells we have // If our width is greater than the number of cells we have
@ -92,7 +96,7 @@ pub const Preedit = struct {
// Rebuild our width in reverse order. This is because we want // Rebuild our width in reverse order. This is because we want
// to offset by the end cells, not the start cells (if we have to). // to offset by the end cells, not the start cells (if we have to).
var w: usize = 0; var w: terminal.size.CellCountInt = 0;
for (0..self.codepoints.len) |i| { for (0..self.codepoints.len) |i| {
const reverse_i = self.codepoints.len - i - 1; const reverse_i = self.codepoints.len - i - 1;
const cp = self.codepoints[reverse_i]; const cp = self.codepoints[reverse_i];

View File

@ -50,6 +50,7 @@ pub const MTLIndexType = enum(c_ulong) {
/// https://developer.apple.com/documentation/metal/mtlvertexformat?language=objc /// https://developer.apple.com/documentation/metal/mtlvertexformat?language=objc
pub const MTLVertexFormat = enum(c_ulong) { pub const MTLVertexFormat = enum(c_ulong) {
uchar4 = 3, uchar4 = 3,
ushort2 = 13,
float2 = 29, float2 = 29,
float4 = 31, float4 = 31,
int2 = 33, int2 = 33,

View File

@ -287,7 +287,7 @@ fn initPostPipeline(
/// This is a single parameter for the terminal cell shader. /// This is a single parameter for the terminal cell shader.
pub const CellText = extern struct { pub const CellText = extern struct {
mode: Mode, mode: Mode,
grid_pos: [2]f32, grid_pos: [2]u16,
glyph_pos: [2]u32 = .{ 0, 0 }, glyph_pos: [2]u32 = .{ 0, 0 },
glyph_size: [2]u32 = .{ 0, 0 }, glyph_size: [2]u32 = .{ 0, 0 },
glyph_offset: [2]i32 = .{ 0, 0 }, glyph_offset: [2]i32 = .{ 0, 0 },
@ -363,7 +363,7 @@ fn initCellTextPipeline(device: objc.Object, library: objc.Object) !objc.Object
.{@as(c_ulong, 1)}, .{@as(c_ulong, 1)},
); );
attr.setProperty("format", @intFromEnum(mtl.MTLVertexFormat.float2)); attr.setProperty("format", @intFromEnum(mtl.MTLVertexFormat.ushort2));
attr.setProperty("offset", @as(c_ulong, @offsetOf(CellText, "grid_pos"))); attr.setProperty("offset", @as(c_ulong, @offsetOf(CellText, "grid_pos")));
attr.setProperty("bufferIndex", @as(c_ulong, 0)); attr.setProperty("bufferIndex", @as(c_ulong, 0));
} }
@ -505,7 +505,7 @@ fn initCellTextPipeline(device: objc.Object, library: objc.Object) !objc.Object
/// This is a single parameter for the cell bg shader. /// This is a single parameter for the cell bg shader.
pub const CellBg = extern struct { pub const CellBg = extern struct {
mode: Mode, mode: Mode,
grid_pos: [2]f32, grid_pos: [2]u16,
color: [4]u8, color: [4]u8,
cell_width: u8, cell_width: u8,
@ -574,7 +574,7 @@ fn initCellBgPipeline(device: objc.Object, library: objc.Object) !objc.Object {
.{@as(c_ulong, 1)}, .{@as(c_ulong, 1)},
); );
attr.setProperty("format", @intFromEnum(mtl.MTLVertexFormat.float2)); attr.setProperty("format", @intFromEnum(mtl.MTLVertexFormat.ushort2));
attr.setProperty("offset", @as(c_ulong, @offsetOf(CellBg, "grid_pos"))); attr.setProperty("offset", @as(c_ulong, @offsetOf(CellBg, "grid_pos")));
attr.setProperty("bufferIndex", @as(c_ulong, 0)); attr.setProperty("bufferIndex", @as(c_ulong, 0));
} }

View File

@ -70,7 +70,7 @@ struct CellBgVertexIn {
uint8_t mode [[attribute(0)]]; uint8_t mode [[attribute(0)]];
// The grid coordinates (x, y) where x < columns and y < rows // The grid coordinates (x, y) where x < columns and y < rows
float2 grid_pos [[attribute(1)]]; ushort2 grid_pos [[attribute(1)]];
// The color. For BG modes, this is the bg color, for FG modes this is // The color. For BG modes, this is the bg color, for FG modes this is
// the text color. For styles, this is the color of the style. // the text color. For styles, this is the color of the style.
@ -90,7 +90,7 @@ vertex CellBgVertexOut cell_bg_vertex(unsigned int vid [[vertex_id]],
constant Uniforms& uniforms constant Uniforms& uniforms
[[buffer(1)]]) { [[buffer(1)]]) {
// Convert the grid x,y into world space x, y by accounting for cell size // Convert the grid x,y into world space x, y by accounting for cell size
float2 cell_pos = uniforms.cell_size * input.grid_pos; float2 cell_pos = uniforms.cell_size * float2(input.grid_pos);
// Scaled cell size for the cell width // Scaled cell size for the cell width
float2 cell_size_scaled = uniforms.cell_size; float2 cell_size_scaled = uniforms.cell_size;
@ -144,7 +144,7 @@ struct CellTextVertexIn {
uint8_t mode [[attribute(0)]]; uint8_t mode [[attribute(0)]];
// The grid coordinates (x, y) where x < columns and y < rows // The grid coordinates (x, y) where x < columns and y < rows
float2 grid_pos [[attribute(1)]]; ushort2 grid_pos [[attribute(1)]];
// The width of the cell in cells (i.e. 2 for double-wide). // The width of the cell in cells (i.e. 2 for double-wide).
uint8_t cell_width [[attribute(6)]]; uint8_t cell_width [[attribute(6)]];
@ -180,7 +180,7 @@ vertex CellTextVertexOut cell_text_vertex(unsigned int vid [[vertex_id]],
constant Uniforms& uniforms constant Uniforms& uniforms
[[buffer(1)]]) { [[buffer(1)]]) {
// Convert the grid x,y into world space x, y by accounting for cell size // Convert the grid x,y into world space x, y by accounting for cell size
float2 cell_pos = uniforms.cell_size * input.grid_pos; float2 cell_pos = uniforms.cell_size * float2(input.grid_pos);
// Scaled cell size for the cell width // Scaled cell size for the cell width
float2 cell_size_scaled = uniforms.cell_size; float2 cell_size_scaled = uniforms.cell_size;