renderer/metal: remove strikethrough support from GPU

This commit is contained in:
Mitchell Hashimoto
2024-04-22 10:26:51 -07:00
parent 0f348e809e
commit ad08842e86
3 changed files with 127 additions and 171 deletions

View File

@ -452,8 +452,6 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
.uniforms = .{ .uniforms = .{
.projection_matrix = undefined, .projection_matrix = undefined,
.cell_size = undefined, .cell_size = undefined,
.strikethrough_position = @floatFromInt(font_critical.metrics.strikethrough_position),
.strikethrough_thickness = @floatFromInt(font_critical.metrics.strikethrough_thickness),
.min_contrast = options.config.min_contrast, .min_contrast = options.config.min_contrast,
}, },
@ -584,8 +582,6 @@ pub fn setFontGrid(self: *Metal, grid: *font.SharedGrid) void {
@floatFromInt(metrics.cell_width), @floatFromInt(metrics.cell_width),
@floatFromInt(metrics.cell_height), @floatFromInt(metrics.cell_height),
}, },
.strikethrough_position = @floatFromInt(metrics.strikethrough_position),
.strikethrough_thickness = @floatFromInt(metrics.strikethrough_thickness),
.min_contrast = self.uniforms.min_contrast, .min_contrast = self.uniforms.min_contrast,
}; };
} }
@ -1436,8 +1432,6 @@ pub fn setScreenSize(
@floatFromInt(self.grid_metrics.cell_width), @floatFromInt(self.grid_metrics.cell_width),
@floatFromInt(self.grid_metrics.cell_height), @floatFromInt(self.grid_metrics.cell_height),
}, },
.strikethrough_position = old.strikethrough_position,
.strikethrough_thickness = old.strikethrough_thickness,
.min_contrast = old.min_contrast, .min_contrast = old.min_contrast,
}; };
@ -1936,14 +1930,6 @@ fn updateCell(
.glyph_size = .{ render.glyph.width, render.glyph.height }, .glyph_size = .{ render.glyph.width, render.glyph.height },
.glyph_offset = .{ render.glyph.offset_x, render.glyph.offset_y }, .glyph_offset = .{ render.glyph.offset_x, render.glyph.offset_y },
}); });
// self.cells.appendAssumeCapacity(.{
// .mode = .strikethrough,
// .grid_pos = .{ @as(f32, @floatFromInt(x)), @as(f32, @floatFromInt(y)) },
// .cell_width = cell.gridWidth(),
// .color = .{ colors.fg.r, colors.fg.g, colors.fg.b, alpha },
// .bg_color = bg,
// });
} }
return true; return true;

View File

@ -103,7 +103,6 @@ pub const Cell = extern struct {
fg = 2, fg = 2,
fg_constrained = 3, fg_constrained = 3,
fg_color = 7, fg_color = 7,
strikethrough = 8,
}; };
}; };
@ -124,10 +123,6 @@ pub const Uniforms = extern struct {
/// Size of a single cell in pixels, unscaled. /// Size of a single cell in pixels, unscaled.
cell_size: [2]f32, cell_size: [2]f32,
/// Metrics for underline/strikethrough
strikethrough_position: f32,
strikethrough_thickness: f32,
/// The minimum contrast ratio for text. The contrast ratio is calculated /// The minimum contrast ratio for text. The contrast ratio is calculated
/// according to the WCAG 2.0 spec. /// according to the WCAG 2.0 spec.
min_contrast: f32, min_contrast: f32,

View File

@ -6,50 +6,47 @@ enum Mode : uint8_t {
MODE_FG = 2u, MODE_FG = 2u,
MODE_FG_CONSTRAINED = 3u, MODE_FG_CONSTRAINED = 3u,
MODE_FG_COLOR = 7u, MODE_FG_COLOR = 7u,
MODE_STRIKETHROUGH = 8u,
}; };
struct Uniforms { struct Uniforms {
float4x4 projection_matrix; float4x4 projection_matrix;
float2 cell_size; float2 cell_size;
float strikethrough_position;
float strikethrough_thickness;
float min_contrast; float min_contrast;
}; };
struct VertexIn { struct VertexIn {
// The mode for this cell. // The mode for this cell.
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) ]]; float2 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)]];
// 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.
uchar4 color [[ attribute(5) ]]; uchar4 color [[attribute(5)]];
// The fields below are present only when rendering text (fg mode) // The fields below are present only when rendering text (fg mode)
// The background color of the cell. This is used to determine if // The background color of the cell. This is used to determine if
// we need to render the text with a different color to ensure // we need to render the text with a different color to ensure
// contrast. // contrast.
uchar4 bg_color [[ attribute(7) ]]; uchar4 bg_color [[attribute(7)]];
// The position of the glyph in the texture (x,y) // The position of the glyph in the texture (x,y)
uint2 glyph_pos [[ attribute(2) ]]; uint2 glyph_pos [[attribute(2)]];
// The size of the glyph in the texture (w,h) // The size of the glyph in the texture (w,h)
uint2 glyph_size [[ attribute(3) ]]; uint2 glyph_size [[attribute(3)]];
// The left and top bearings for the glyph (x,y) // The left and top bearings for the glyph (x,y)
int2 glyph_offset [[ attribute(4) ]]; int2 glyph_offset [[attribute(4)]];
}; };
struct VertexOut { struct VertexOut {
float4 position [[ position ]]; float4 position [[position]];
float2 cell_size; float2 cell_size;
uint8_t mode; uint8_t mode;
float4 color; float4 color;
@ -110,11 +107,9 @@ float4 contrasted_color(float min, float4 fg, float4 bg) {
//------------------------------------------------------------------- //-------------------------------------------------------------------
#pragma mark - Terminal Grid Cell Shader #pragma mark - Terminal Grid Cell Shader
vertex VertexOut uber_vertex( vertex VertexOut uber_vertex(unsigned int vid [[vertex_id]],
unsigned int vid [[ vertex_id ]], VertexIn input [[stage_in]],
VertexIn input [[ stage_in ]], constant Uniforms& uniforms [[buffer(1)]]) {
constant Uniforms &uniforms [[ 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 * input.grid_pos;
@ -147,7 +142,8 @@ vertex VertexOut uber_vertex(
// one cell up and to the left. (Do the math to verify yourself) // one cell up and to the left. (Do the math to verify yourself)
cell_pos = cell_pos + cell_size_scaled * position; cell_pos = cell_pos + cell_size_scaled * position;
out.position = uniforms.projection_matrix * float4(cell_pos.x, cell_pos.y, 0.0f, 1.0f); out.position = uniforms.projection_matrix *
float4(cell_pos.x, cell_pos.y, 0.0f, 1.0f);
break; break;
case MODE_FG: case MODE_FG:
@ -176,49 +172,33 @@ vertex VertexOut uber_vertex(
// Calculate the final position of the cell which uses our glyph size // Calculate the final position of the cell which uses our glyph size
// and glyph offset to create the correct bounding box for the glyph. // and glyph offset to create the correct bounding box for the glyph.
cell_pos = cell_pos + glyph_size * position + glyph_offset; cell_pos = cell_pos + glyph_size * position + glyph_offset;
out.position = uniforms.projection_matrix * float4(cell_pos.x, cell_pos.y, 0.0f, 1.0f); out.position = uniforms.projection_matrix *
float4(cell_pos.x, cell_pos.y, 0.0f, 1.0f);
// Calculate the texture coordinate in pixels. This is NOT normalized // Calculate the texture coordinate in pixels. This is NOT normalized
// (between 0.0 and 1.0) and must be done in the fragment shader. // (between 0.0 and 1.0) and must be done in the fragment shader.
out.tex_coord = float2(input.glyph_pos) + float2(input.glyph_size) * position; out.tex_coord =
float2(input.glyph_pos) + float2(input.glyph_size) * position;
// If we have a minimum contrast, we need to check if we need to // If we have a minimum contrast, we need to check if we need to
// change the color of the text to ensure it has enough contrast // change the color of the text to ensure it has enough contrast
// with the background. // with the background.
if (uniforms.min_contrast > 1.0f && input.mode == MODE_FG) { if (uniforms.min_contrast > 1.0f && input.mode == MODE_FG) {
float4 bg_color = float4(input.bg_color) / 255.0f; float4 bg_color = float4(input.bg_color) / 255.0f;
out.color = contrasted_color(uniforms.min_contrast, out.color, bg_color); out.color =
contrasted_color(uniforms.min_contrast, out.color, bg_color);
} }
break; break;
} }
case MODE_STRIKETHROUGH: {
// Strikethrough Y value is just our thickness
float2 strikethrough_size = float2(cell_size_scaled.x, uniforms.strikethrough_thickness);
// Position the strikethrough where we are told to
float2 strikethrough_offset = float2(cell_size_scaled.x, uniforms.strikethrough_position);
// Go to the bottom of the cell, take away the size of the
// strikethrough, and that is our position. We also float it slightly
// above the bottom.
cell_pos = cell_pos + strikethrough_offset - (strikethrough_size * position);
out.position = uniforms.projection_matrix * float4(cell_pos, 0.0f, 1.0);
break;
}
} }
return out; return out;
} }
fragment float4 uber_fragment( fragment float4 uber_fragment(VertexOut in [[stage_in]],
VertexOut in [[ stage_in ]], texture2d<float> textureGreyscale [[texture(0)]],
texture2d<float> textureGreyscale [[ texture(0) ]], texture2d<float> textureColor [[texture(1)]]) {
texture2d<float> textureColor [[ texture(1) ]]
) {
constexpr sampler textureSampler(address::clamp_to_edge, filter::linear); constexpr sampler textureSampler(address::clamp_to_edge, filter::linear);
switch (in.mode) { switch (in.mode) {
@ -228,7 +208,8 @@ fragment float4 uber_fragment(
case MODE_FG_CONSTRAINED: case MODE_FG_CONSTRAINED:
case MODE_FG: { case MODE_FG: {
// Normalize the texture coordinates to [0,1] // Normalize the texture coordinates to [0,1]
float2 size = float2(textureGreyscale.get_width(), textureGreyscale.get_height()); float2 size =
float2(textureGreyscale.get_width(), textureGreyscale.get_height());
float2 coord = in.tex_coord / size; float2 coord = in.tex_coord / size;
// We premult the alpha to our whole color since our blend function // We premult the alpha to our whole color since our blend function
@ -247,9 +228,6 @@ fragment float4 uber_fragment(
float2 coord = in.tex_coord / size; float2 coord = in.tex_coord / size;
return textureColor.sample(textureSampler, coord); return textureColor.sample(textureSampler, coord);
} }
case MODE_STRIKETHROUGH:
return in.color;
} }
} }
@ -261,30 +239,28 @@ fragment float4 uber_fragment(
struct ImageVertexIn { struct ImageVertexIn {
// The grid coordinates (x, y) where x < columns and y < rows where // The grid coordinates (x, y) where x < columns and y < rows where
// the image will be rendered. It will be rendered from the top left. // the image will be rendered. It will be rendered from the top left.
float2 grid_pos [[ attribute(1) ]]; float2 grid_pos [[attribute(1)]];
// Offset in pixels from the top-left of the cell to make the top-left // Offset in pixels from the top-left of the cell to make the top-left
// corner of the image. // corner of the image.
float2 cell_offset [[ attribute(2) ]]; float2 cell_offset [[attribute(2)]];
// The source rectangle of the texture to sample from. // The source rectangle of the texture to sample from.
float4 source_rect [[ attribute(3) ]]; float4 source_rect [[attribute(3)]];
// The final width/height of the image in pixels. // The final width/height of the image in pixels.
float2 dest_size [[ attribute(4) ]]; float2 dest_size [[attribute(4)]];
}; };
struct ImageVertexOut { struct ImageVertexOut {
float4 position [[ position ]]; float4 position [[position]];
float2 tex_coord; float2 tex_coord;
}; };
vertex ImageVertexOut image_vertex( vertex ImageVertexOut image_vertex(unsigned int vid [[vertex_id]],
unsigned int vid [[ vertex_id ]], ImageVertexIn input [[stage_in]],
ImageVertexIn input [[ stage_in ]], texture2d<uint> image [[texture(0)]],
texture2d<uint> image [[ texture(0) ]], constant Uniforms& uniforms [[buffer(1)]]) {
constant Uniforms &uniforms [[ buffer(1) ]]
) {
// The size of the image in pixels // The size of the image in pixels
float2 image_size = float2(image.get_width(), image.get_height()); float2 image_size = float2(image.get_width(), image.get_height());
@ -315,15 +291,14 @@ vertex ImageVertexOut image_vertex(
float2 image_pos = (uniforms.cell_size * input.grid_pos) + input.cell_offset; float2 image_pos = (uniforms.cell_size * input.grid_pos) + input.cell_offset;
image_pos += input.dest_size * position; image_pos += input.dest_size * position;
out.position = uniforms.projection_matrix * float4(image_pos.x, image_pos.y, 0.0f, 1.0f); out.position =
uniforms.projection_matrix * float4(image_pos.x, image_pos.y, 0.0f, 1.0f);
out.tex_coord = tex_coord; out.tex_coord = tex_coord;
return out; return out;
} }
fragment float4 image_fragment( fragment float4 image_fragment(ImageVertexOut in [[stage_in]],
ImageVertexOut in [[ stage_in ]], texture2d<uint> image [[texture(0)]]) {
texture2d<uint> image [[ texture(0) ]]
) {
constexpr sampler textureSampler(address::clamp_to_edge, filter::linear); constexpr sampler textureSampler(address::clamp_to_edge, filter::linear);
// Ehhhhh our texture is in RGBA8Uint but our color attachment is // Ehhhhh our texture is in RGBA8Uint but our color attachment is
@ -344,12 +319,12 @@ fragment float4 image_fragment(
#pragma mark - Post Shader #pragma mark - Post Shader
struct PostVertexOut { struct PostVertexOut {
float4 position [[ position ]]; float4 position [[position]];
}; };
constant float2 post_pos[4] = { {-1,-1}, {1,-1}, {-1,1}, {1,1 } }; constant float2 post_pos[4] = {{-1, -1}, {1, -1}, {-1, 1}, {1, 1}};
vertex PostVertexOut post_vertex(uint id [[ vertex_id ]]) { vertex PostVertexOut post_vertex(uint id [[vertex_id]]) {
PostVertexOut out; PostVertexOut out;
out.position = float4(post_pos[id], 0, 1); out.position = float4(post_pos[id], 0, 1);
return out; return out;