a73x

f60856b1

Add dirty-row packing helpers

a73x   2026-04-08 18:32

Commit message
Add dirty-row packing helpers

src/main.zig
Old New
@@ -622,6 +622,92 @@ test "planRowRefresh rebuilds cursor when only column changes on same row" {
622 try std.testing.expectEqual(@as(usize, 0), plan.rows_to_rebuild.count()); 622 try std.testing.expectEqual(@as(usize, 0), plan.rows_to_rebuild.count());
623 } 623 }
624 624
625 test "repackRowCaches assigns contiguous offsets" {
626 var rows = [_]RowInstanceCache{
627 .{
628 .instances = try makeTestInstances(std.testing.allocator, 2),
629 .gpu_offset_instances = 99,
630 .gpu_len_instances = 0,
631 },
632 .{
633 .instances = try makeTestInstances(std.testing.allocator, 3),
634 .gpu_offset_instances = 99,
635 .gpu_len_instances = 0,
636 },
637 };
638 defer for (&rows) |*row| row.instances.deinit(std.testing.allocator);
639
640 var packed_instances: std.ArrayListUnmanaged(renderer.Instance) = .empty;
641 defer packed_instances.deinit(std.testing.allocator);
642
643 const total = try repackRowCaches(std.testing.allocator, &packed_instances, &rows, &.{});
644
645 try std.testing.expectEqual(@as(u32, 0), rows[0].gpu_offset_instances);
646 try std.testing.expectEqual(@as(u32, 2), rows[1].gpu_offset_instances);
647 try std.testing.expectEqual(@as(u32, 5), total);
648 }
649
650 test "markLayoutDirtyOnLenChange returns true when row length changes" {
651 try std.testing.expect(markLayoutDirtyOnLenChange(2, 3));
652 try std.testing.expect(!markLayoutDirtyOnLenChange(3, 3));
653 }
654
655 const RowInstanceCache = struct {
656 instances: std.ArrayListUnmanaged(renderer.Instance) = .empty,
657 gpu_offset_instances: u32 = 0,
658 gpu_len_instances: u32 = 0,
659
660 fn deinit(self: *RowInstanceCache, alloc: std.mem.Allocator) void {
661 self.instances.deinit(alloc);
662 }
663 };
664
665 fn repackRowCaches(
666 alloc: std.mem.Allocator,
667 packed_instances: *std.ArrayListUnmanaged(renderer.Instance),
668 rows: []RowInstanceCache,
669 cursor_instances: []const renderer.Instance,
670 ) !u32 {
671 packed_instances.clearRetainingCapacity();
672
673 var offset: u32 = 0;
674 for (rows) |*row| {
675 row.gpu_offset_instances = offset;
676 row.gpu_len_instances = @intCast(row.instances.items.len);
677 try packed_instances.appendSlice(alloc, row.instances.items);
678 offset += @intCast(row.instances.items.len);
679 }
680
681 try packed_instances.appendSlice(alloc, cursor_instances);
682 return offset + @as(u32, @intCast(cursor_instances.len));
683 }
684
685 fn markLayoutDirtyOnLenChange(old_len: usize, new_len: usize) bool {
686 return old_len != new_len;
687 }
688
689 fn makeTestInstances(
690 alloc: std.mem.Allocator,
691 count: usize,
692 ) !std.ArrayListUnmanaged(renderer.Instance) {
693 var instances: std.ArrayListUnmanaged(renderer.Instance) = .empty;
694 try instances.ensureTotalCapacity(alloc, count);
695
696 var i: usize = 0;
697 while (i < count) : (i += 1) {
698 try instances.append(alloc, .{
699 .cell_pos = .{ @floatFromInt(i), 0.0 },
700 .glyph_size = .{ 1.0, 1.0 },
701 .glyph_bearing = .{ 0.0, 0.0 },
702 .uv_rect = .{ 0.0, 0.0, 1.0, 1.0 },
703 .fg = .{ 1.0, 1.0, 1.0, 1.0 },
704 .bg = .{ 0.0, 0.0, 0.0, 1.0 },
705 });
706 }
707
708 return instances;
709 }
710
625 fn runDrawSmokeTest(alloc: std.mem.Allocator) !void { 711 fn runDrawSmokeTest(alloc: std.mem.Allocator) !void {
626 var conn = try wayland_client.Connection.init(); 712 var conn = try wayland_client.Connection.init();
627 defer conn.deinit(); 713 defer conn.deinit();