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

View File

@ -124,9 +124,10 @@ pub const Uniforms = extern struct {
/// top, right, bottom, left.
grid_padding: [4]f32 align(16),
/// True if vertical padding gets the extended color of the nearest row.
padding_extend_top: bool align(1),
padding_extend_bottom: bool align(1),
/// Bit mask defining which directions to
/// extend cell colors in to the padding.
/// Order, LSB first: left, right, up, down
padding_extend: PaddingExtend align(1),
/// The minimum contrast ratio for text. The contrast ratio is calculated
/// according to the WCAG 2.0 spec.
@ -135,6 +136,14 @@ pub const Uniforms = extern struct {
/// The cursor position and color.
cursor_pos: [2]u16 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.

View File

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