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
// here because we will render the preedit separately.
const preedit_range: ?struct {
y: usize,
x: [2]usize,
y: terminal.size.CellCountInt,
x: [2]terminal.size.CellCountInt,
cp_offset: usize,
} = if (preedit) |preedit_v| preedit: {
const range = preedit_v.range(screen.cursor.x, screen.pages.cols - 1);
@ -1770,7 +1770,7 @@ fn rebuildCells(
// Build each cell
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| {
defer y += 1;
@ -1809,7 +1809,7 @@ fn rebuildCells(
const screen_cell = row.cells(.all)[screen.cursor.x];
const x = screen.cursor.x - @intFromBool(screen_cell.wide == .spacer_tail);
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))
{
cursor_cell = cell;
@ -1929,8 +1929,8 @@ fn updateCell(
palette: *const terminal.color.Palette,
shaper_cell: font.shape.Cell,
shaper_run: font.shape.TextRun,
x: usize,
y: usize,
x: terminal.size.CellCountInt,
y: terminal.size.CellCountInt,
) !bool {
const BgFg = struct {
/// Background is optional because in un-inverted mode
@ -2031,7 +2031,7 @@ fn updateCell(
self.cells_bg.appendAssumeCapacity(.{
.mode = .rgb,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) },
.grid_pos = .{ x, y },
.cell_width = cell.gridWidth(),
.color = .{ rgb.r, rgb.g, rgb.b, bg_alpha },
});
@ -2068,7 +2068,7 @@ fn updateCell(
self.cells_text.appendAssumeCapacity(.{
.mode = mode,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) },
.grid_pos = .{ x, y },
.cell_width = cell.gridWidth(),
.color = .{ colors.fg.r, colors.fg.g, colors.fg.b, alpha },
.bg_color = bg,
@ -2105,7 +2105,7 @@ fn updateCell(
self.cells_text.appendAssumeCapacity(.{
.mode = .fg,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) },
.grid_pos = .{ x, y },
.cell_width = cell.gridWidth(),
.color = .{ color.r, color.g, color.b, alpha },
.bg_color = bg,
@ -2128,7 +2128,7 @@ fn updateCell(
self.cells_text.appendAssumeCapacity(.{
.mode = .fg,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) },
.grid_pos = .{ x, y },
.cell_width = cell.gridWidth(),
.color = .{ colors.fg.r, colors.fg.g, colors.fg.b, alpha },
.bg_color = bg,
@ -2188,10 +2188,7 @@ fn addCursor(
self.cells_text.appendAssumeCapacity(.{
.mode = .fg,
.grid_pos = .{
@as(f32, @floatFromInt(x)),
@as(f32, @floatFromInt(screen.cursor.y)),
},
.grid_pos = .{ x, screen.cursor.y },
.cell_width = if (wide) 2 else 1,
.color = .{ color.r, color.g, color.b, alpha },
.bg_color = .{ 0, 0, 0, 0 },
@ -2206,8 +2203,8 @@ fn addCursor(
fn addPreeditCell(
self: *Metal,
cp: renderer.State.Preedit.Codepoint,
x: usize,
y: usize,
x: terminal.size.CellCountInt,
y: terminal.size.CellCountInt,
) !void {
// Preedit is rendered inverted
const bg = self.foreground_color;
@ -2232,7 +2229,7 @@ fn addPreeditCell(
// Add our opaque background cell
self.cells_bg.appendAssumeCapacity(.{
.mode = .rgb,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) },
.grid_pos = .{ x, y },
.cell_width = if (cp.wide) 2 else 1,
.color = .{ bg.r, bg.g, bg.b, 255 },
});
@ -2240,7 +2237,7 @@ fn addPreeditCell(
// Add our text
self.cells_text.appendAssumeCapacity(.{
.mode = .fg,
.grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) },
.grid_pos = .{ x, y },
.cell_width = if (cp.wide) 2 else 1,
.color = .{ fg.r, fg.g, fg.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
/// along with any codepoint offset necessary to fit the preedit
/// into the available space.
pub fn range(self: *const Preedit, start: usize, max: usize) struct {
start: usize,
end: usize,
pub fn range(
self: *const Preedit,
start: terminal.size.CellCountInt,
max: terminal.size.CellCountInt,
) struct {
start: terminal.size.CellCountInt,
end: terminal.size.CellCountInt,
cp_offset: usize,
} {
// 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
// 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| {
const reverse_i = self.codepoints.len - i - 1;
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
pub const MTLVertexFormat = enum(c_ulong) {
uchar4 = 3,
ushort2 = 13,
float2 = 29,
float4 = 31,
int2 = 33,

View File

@ -287,7 +287,7 @@ fn initPostPipeline(
/// This is a single parameter for the terminal cell shader.
pub const CellText = extern struct {
mode: Mode,
grid_pos: [2]f32,
grid_pos: [2]u16,
glyph_pos: [2]u32 = .{ 0, 0 },
glyph_size: [2]u32 = .{ 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)},
);
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("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.
pub const CellBg = extern struct {
mode: Mode,
grid_pos: [2]f32,
grid_pos: [2]u16,
color: [4]u8,
cell_width: u8,
@ -574,7 +574,7 @@ fn initCellBgPipeline(device: objc.Object, library: objc.Object) !objc.Object {
.{@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("bufferIndex", @as(c_ulong, 0));
}

View File

@ -70,7 +70,7 @@ struct CellBgVertexIn {
uint8_t mode [[attribute(0)]];
// 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 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
[[buffer(1)]]) {
// 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
float2 cell_size_scaled = uniforms.cell_size;
@ -144,7 +144,7 @@ struct CellTextVertexIn {
uint8_t mode [[attribute(0)]];
// 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).
uint8_t cell_width [[attribute(6)]];
@ -180,7 +180,7 @@ vertex CellTextVertexOut cell_text_vertex(unsigned int vid [[vertex_id]],
constant Uniforms& uniforms
[[buffer(1)]]) {
// 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
float2 cell_size_scaled = uniforms.cell_size;