f60856b1
Add dirty-row packing helpers
a73x 2026-04-08 18:32
diff --git a/src/main.zig b/src/main.zig index 413a922..11fadd0 100644 --- a/src/main.zig +++ b/src/main.zig @@ -622,6 +622,92 @@ test "planRowRefresh rebuilds cursor when only column changes on same row" { try std.testing.expectEqual(@as(usize, 0), plan.rows_to_rebuild.count()); } test "repackRowCaches assigns contiguous offsets" { var rows = [_]RowInstanceCache{ .{ .instances = try makeTestInstances(std.testing.allocator, 2), .gpu_offset_instances = 99, .gpu_len_instances = 0, }, .{ .instances = try makeTestInstances(std.testing.allocator, 3), .gpu_offset_instances = 99, .gpu_len_instances = 0, }, }; defer for (&rows) |*row| row.instances.deinit(std.testing.allocator); var packed_instances: std.ArrayListUnmanaged(renderer.Instance) = .empty; defer packed_instances.deinit(std.testing.allocator); const total = try repackRowCaches(std.testing.allocator, &packed_instances, &rows, &.{}); try std.testing.expectEqual(@as(u32, 0), rows[0].gpu_offset_instances); try std.testing.expectEqual(@as(u32, 2), rows[1].gpu_offset_instances); try std.testing.expectEqual(@as(u32, 5), total); } test "markLayoutDirtyOnLenChange returns true when row length changes" { try std.testing.expect(markLayoutDirtyOnLenChange(2, 3)); try std.testing.expect(!markLayoutDirtyOnLenChange(3, 3)); } const RowInstanceCache = struct { instances: std.ArrayListUnmanaged(renderer.Instance) = .empty, gpu_offset_instances: u32 = 0, gpu_len_instances: u32 = 0, fn deinit(self: *RowInstanceCache, alloc: std.mem.Allocator) void { self.instances.deinit(alloc); } }; fn repackRowCaches( alloc: std.mem.Allocator, packed_instances: *std.ArrayListUnmanaged(renderer.Instance), rows: []RowInstanceCache, cursor_instances: []const renderer.Instance, ) !u32 { packed_instances.clearRetainingCapacity(); var offset: u32 = 0; for (rows) |*row| { row.gpu_offset_instances = offset; row.gpu_len_instances = @intCast(row.instances.items.len); try packed_instances.appendSlice(alloc, row.instances.items); offset += @intCast(row.instances.items.len); } try packed_instances.appendSlice(alloc, cursor_instances); return offset + @as(u32, @intCast(cursor_instances.len)); } fn markLayoutDirtyOnLenChange(old_len: usize, new_len: usize) bool { return old_len != new_len; } fn makeTestInstances( alloc: std.mem.Allocator, count: usize, ) !std.ArrayListUnmanaged(renderer.Instance) { var instances: std.ArrayListUnmanaged(renderer.Instance) = .empty; try instances.ensureTotalCapacity(alloc, count); var i: usize = 0; while (i < count) : (i += 1) { try instances.append(alloc, .{ .cell_pos = .{ @floatFromInt(i), 0.0 }, .glyph_size = .{ 1.0, 1.0 }, .glyph_bearing = .{ 0.0, 0.0 }, .uv_rect = .{ 0.0, 0.0, 1.0, 1.0 }, .fg = .{ 1.0, 1.0, 1.0, 1.0 }, .bg = .{ 0.0, 0.0, 0.0, 1.0 }, }); } return instances; } fn runDrawSmokeTest(alloc: std.mem.Allocator) !void { var conn = try wayland_client.Connection.init(); defer conn.deinit();