renderer/metal: properly support padding color = background (not extend)

This commit is contained in:
Qwerasd
2024-08-08 19:03:39 -04:00
parent e5241cb659
commit d68906563e
3 changed files with 65 additions and 33 deletions

View File

@ -625,8 +625,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
.cell_size = undefined, .cell_size = undefined,
.grid_size = undefined, .grid_size = undefined,
.grid_padding = undefined, .grid_padding = undefined,
.padding_extend_top = true, .padding_extend = .{},
.padding_extend_bottom = true,
.min_contrast = options.config.min_contrast, .min_contrast = options.config.min_contrast,
.cursor_pos = .{ std.math.maxInt(u16), std.math.maxInt(u16) }, .cursor_pos = .{ std.math.maxInt(u16), std.math.maxInt(u16) },
.cursor_color = undefined, .cursor_color = undefined,
@ -1950,16 +1949,20 @@ pub fn setScreenSize(
const padded_dim = dim.subPadding(padding); const padded_dim = dim.subPadding(padding);
// Blank space around the grid. // Blank space around the grid.
const blank: renderer.Padding = switch (self.config.padding_color) { const blank: renderer.Padding = dim.blankPadding(padding, grid_size, .{
// We can use zero padding because the background color is our
// clear color.
.background => .{},
.extend => dim.blankPadding(padding, grid_size, .{
.width = self.grid_metrics.cell_width, .width = self.grid_metrics.cell_width,
.height = self.grid_metrics.cell_height, .height = self.grid_metrics.cell_height,
}).add(padding), }).add(padding);
};
var padding_extend = self.uniforms.padding_extend;
if (self.config.padding_color == .extend) {
// If padding extension is enabled, we extend left and right always.
padding_extend.left = true;
padding_extend.right = true;
} else {
// Otherwise, disable all padding extension.
padding_extend = .{};
}
// 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{
@ -1990,8 +1993,7 @@ pub fn setScreenSize(
@floatFromInt(blank.bottom), @floatFromInt(blank.bottom),
@floatFromInt(blank.left), @floatFromInt(blank.left),
}, },
.padding_extend_top = old.padding_extend_top, .padding_extend = padding_extend,
.padding_extend_bottom = old.padding_extend_bottom,
.min_contrast = old.min_contrast, .min_contrast = old.min_contrast,
.cursor_pos = old.cursor_pos, .cursor_pos = old.cursor_pos,
.cursor_color = old.cursor_color, .cursor_color = old.cursor_color,
@ -2136,8 +2138,10 @@ fn rebuildCells(
self.cells.reset(); self.cells.reset();
// We also reset our padding extension depending on the screen type // We also reset our padding extension depending on the screen type
self.uniforms.padding_extend_top = screen_type == .alternate; if (self.config.padding_color == .extend) {
self.uniforms.padding_extend_bottom = screen_type == .alternate; self.uniforms.padding_extend.up = screen_type == .alternate;
self.uniforms.padding_extend.down = screen_type == .alternate;
}
} }
// Go row-by-row to build the cells. We go row by row because we do // Go row-by-row to build the cells. We go row by row because we do
@ -2174,10 +2178,12 @@ fn rebuildCells(
// under certain conditions we feel are safe. This helps make some // under certain conditions we feel are safe. This helps make some
// scenarios look better while avoiding scenarios we know do NOT look // scenarios look better while avoiding scenarios we know do NOT look
// good. // good.
if (self.config.padding_color == .extend) {
if (y == 0 and screen_type == .primary) { if (y == 0 and screen_type == .primary) {
self.uniforms.padding_extend_top = !row.neverExtendBg(); self.uniforms.padding_extend.up = !row.neverExtendBg();
} else if (y == self.cells.size.rows - 1 and screen_type == .primary) { } else if (y == self.cells.size.rows - 1 and screen_type == .primary) {
self.uniforms.padding_extend_bottom = !row.neverExtendBg(); self.uniforms.padding_extend.down = !row.neverExtendBg();
}
} }
// Split our row into runs and shape each one. // Split our row into runs and shape each one.

View File

@ -124,9 +124,10 @@ pub const Uniforms = extern struct {
/// top, right, bottom, left. /// top, right, bottom, left.
grid_padding: [4]f32 align(16), grid_padding: [4]f32 align(16),
/// True if vertical padding gets the extended color of the nearest row. /// Bit mask defining which directions to
padding_extend_top: bool align(1), /// extend cell colors in to the padding.
padding_extend_bottom: bool align(1), /// Order, LSB first: left, right, up, down
padding_extend: PaddingExtend align(1),
/// 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.
@ -135,6 +136,14 @@ pub const Uniforms = extern struct {
/// The cursor position and color. /// The cursor position and color.
cursor_pos: [2]u16 align(4), cursor_pos: [2]u16 align(4),
cursor_color: [4]u8 align(4), cursor_color: [4]u8 align(4),
const PaddingExtend = packed struct(u8) {
left: bool = false,
right: bool = false,
up: bool = false,
down: bool = false,
_padding: u4 = 0,
};
}; };
/// The uniforms used for custom postprocess shaders. /// The uniforms used for custom postprocess shaders.

View File

@ -2,13 +2,19 @@
using namespace metal; using namespace metal;
enum Padding : uint8_t {
EXTEND_LEFT = 1u,
EXTEND_RIGHT = 2u,
EXTEND_UP = 4u,
EXTEND_DOWN = 8u,
};
struct Uniforms { struct Uniforms {
float4x4 projection_matrix; float4x4 projection_matrix;
float2 cell_size; float2 cell_size;
ushort2 grid_size; ushort2 grid_size;
float4 grid_padding; float4 grid_padding;
bool padding_extend_top; uint8_t padding_extend;
bool padding_extend_bottom;
float min_contrast; float min_contrast;
ushort2 cursor_pos; ushort2 cursor_pos;
uchar4 cursor_color; uchar4 cursor_color;
@ -110,21 +116,32 @@ fragment float4 cell_bg_fragment(
constant uchar4 *cells [[buffer(0)]], constant uchar4 *cells [[buffer(0)]],
constant Uniforms& uniforms [[buffer(1)]] constant Uniforms& uniforms [[buffer(1)]]
) { ) {
int2 grid_pos = int2((in.position.xy - uniforms.grid_padding.wx) / uniforms.cell_size); int2 grid_pos = int2(floor((in.position.xy - uniforms.grid_padding.wx) / uniforms.cell_size));
// Clamp x position, extends edge bg colors in to padding on sides. // Clamp x position, extends edge bg colors in to padding on sides.
grid_pos.x = clamp(grid_pos.x, 0, uniforms.grid_size.x - 1); if (grid_pos.x < 0) {
if (uniforms.padding_extend & EXTEND_LEFT) {
// Clamp y position if we should extend, otherwise discard if out of bounds. grid_pos.x = 0;
if (grid_pos.y < 0) { } else {
if (uniforms.padding_extend_top) { return float4(0.0);
grid_pos.y = 0; }
} else if (grid_pos.x > uniforms.grid_size.x - 1) {
if (uniforms.padding_extend & EXTEND_RIGHT) {
grid_pos.x = uniforms.grid_size.x - 1;
} else { } else {
return float4(0.0); return float4(0.0);
} }
} }
if (grid_pos.y > uniforms.grid_size.y - 1) {
if (uniforms.padding_extend_bottom) { // Clamp y position if we should extend, otherwise discard if out of bounds.
if (grid_pos.y < 0) {
if (uniforms.padding_extend & EXTEND_UP) {
grid_pos.y = 0;
} else {
return float4(0.0);
}
} else if (grid_pos.y > uniforms.grid_size.y - 1) {
if (uniforms.padding_extend & EXTEND_DOWN) {
grid_pos.y = uniforms.grid_size.y - 1; grid_pos.y = uniforms.grid_size.y - 1;
} else { } else {
return float4(0.0); return float4(0.0);