7a8bf92e
Add render cache data structures
a73x 2026-04-08 18:52
Commit message
src/main.zig
| Old | New | ||
|---|---|---|---|
| @@ -719,6 +719,56 @@ test "repackRowCaches keeps cursor span explicit for empty and non-empty cursor | |||
| 719 | try std.testing.expectEqualDeep([2]f32{ 9.0, 10.0 }, packed_instances.items[2].cell_pos); | 719 | try std.testing.expectEqualDeep([2]f32{ 9.0, 10.0 }, packed_instances.items[2].cell_pos); |
| 720 | } | 720 | } |
| 721 | 721 | ||
| 722 | test "RenderCache resizeRows preserves surviving row caches" { | ||
| 723 | var cache = RenderCache.empty; | ||
| 724 | defer cache.deinit(std.testing.allocator); | ||
| 725 | |||
| 726 | try cache.resizeRows(std.testing.allocator, 2); | ||
| 727 | cache.rows[0].instances = try makeTestInstances(std.testing.allocator, 1); | ||
| 728 | cache.rows[0].gpu_offset_instances = 17; | ||
| 729 | cache.rows[0].gpu_len_instances = 1; | ||
| 730 | |||
| 731 | try cache.resizeRows(std.testing.allocator, 3); | ||
| 732 | try std.testing.expectEqual(@as(usize, 3), cache.rows.len); | ||
| 733 | try std.testing.expectEqual(@as(usize, 1), cache.rows[0].instances.items.len); | ||
| 734 | try std.testing.expectEqual(@as(u32, 17), cache.rows[0].gpu_offset_instances); | ||
| 735 | try std.testing.expectEqual(@as(u32, 1), cache.rows[0].gpu_len_instances); | ||
| 736 | try std.testing.expectEqual(@as(usize, 0), cache.rows[2].instances.items.len); | ||
| 737 | |||
| 738 | try cache.resizeRows(std.testing.allocator, 1); | ||
| 739 | try std.testing.expectEqual(@as(usize, 1), cache.rows.len); | ||
| 740 | try std.testing.expectEqual(@as(usize, 1), cache.rows[0].instances.items.len); | ||
| 741 | try std.testing.expectEqual(@as(u32, 17), cache.rows[0].gpu_offset_instances); | ||
| 742 | try std.testing.expectEqual(@as(u32, 1), cache.rows[0].gpu_len_instances); | ||
| 743 | } | ||
| 744 | |||
| 745 | test "RenderCache deinit resets fields after releasing row storage" { | ||
| 746 | var cache = RenderCache.empty; | ||
| 747 | |||
| 748 | try cache.resizeRows(std.testing.allocator, 2); | ||
| 749 | cache.rows[0].instances = try makeTestInstances(std.testing.allocator, 2); | ||
| 750 | cache.rows[1].instances = try makeTestInstances(std.testing.allocator, 1); | ||
| 751 | |||
| 752 | var cursor_instances = try makeTestInstances(std.testing.allocator, 1); | ||
| 753 | defer cursor_instances.deinit(std.testing.allocator); | ||
| 754 | try cache.cursor_instances.append(std.testing.allocator, cursor_instances.items[0]); | ||
| 755 | |||
| 756 | var packed_instances = try makeTestInstances(std.testing.allocator, 1); | ||
| 757 | defer packed_instances.deinit(std.testing.allocator); | ||
| 758 | try cache.packed_instances.append(std.testing.allocator, packed_instances.items[0]); | ||
| 759 | |||
| 760 | cache.total_instance_count = 3; | ||
| 761 | cache.layout_dirty = false; | ||
| 762 | |||
| 763 | cache.deinit(std.testing.allocator); | ||
| 764 | |||
| 765 | try std.testing.expectEqual(@as(usize, 0), cache.rows.len); | ||
| 766 | try std.testing.expectEqual(@as(usize, 0), cache.cursor_instances.items.len); | ||
| 767 | try std.testing.expectEqual(@as(usize, 0), cache.packed_instances.items.len); | ||
| 768 | try std.testing.expectEqual(@as(u32, 0), cache.total_instance_count); | ||
| 769 | try std.testing.expect(cache.layout_dirty); | ||
| 770 | } | ||
| 771 | |||
| 722 | const RowInstanceCache = struct { | 772 | const RowInstanceCache = struct { |
| 723 | instances: std.ArrayListUnmanaged(renderer.Instance) = .empty, | 773 | instances: std.ArrayListUnmanaged(renderer.Instance) = .empty, |
| 724 | gpu_offset_instances: u32 = 0, | 774 | gpu_offset_instances: u32 = 0, |
| @@ -726,6 +776,65 @@ const RowInstanceCache = struct { | |||
| 726 | 776 | ||
| 727 | fn deinit(self: *RowInstanceCache, alloc: std.mem.Allocator) void { | 777 | fn deinit(self: *RowInstanceCache, alloc: std.mem.Allocator) void { |
| 728 | self.instances.deinit(alloc); | 778 | self.instances.deinit(alloc); |
| 779 | self.* = .{}; | ||
| 780 | } | ||
| 781 | }; | ||
| 782 | |||
| 783 | const RenderCache = struct { | ||
| 784 | rows: []RowInstanceCache = &.{}, | ||
| 785 | cursor_instances: std.ArrayListUnmanaged(renderer.Instance) = .empty, | ||
| 786 | packed_instances: std.ArrayListUnmanaged(renderer.Instance) = .empty, | ||
| 787 | total_instance_count: u32 = 0, | ||
| 788 | layout_dirty: bool = true, | ||
| 789 | |||
| 790 | const empty: RenderCache = .{}; | ||
| 791 | |||
| 792 | fn resizeRows(self: *RenderCache, alloc: std.mem.Allocator, row_count: usize) !void { | ||
| 793 | if (self.rows.len == row_count) return; | ||
| 794 | if (row_count == 0) { | ||
| 795 | const old_rows = self.rows; | ||
| 796 | if (old_rows.len > 0) { | ||
| 797 | var row_idx: usize = 0; | ||
| 798 | while (row_idx < old_rows.len) : (row_idx += 1) { | ||
| 799 | old_rows[row_idx].deinit(alloc); | ||
| 800 | } | ||
| 801 | alloc.free(old_rows); | ||
| 802 | } | ||
| 803 | self.rows = &.{}; | ||
| 804 | return; | ||
| 805 | } | ||
| 806 | |||
| 807 | const old_rows = self.rows; | ||
| 808 | var new_rows = try alloc.alloc(RowInstanceCache, row_count); | ||
| 809 | for (new_rows) |*row| row.* = .{}; | ||
| 810 | |||
| 811 | const copy_len = @min(old_rows.len, row_count); | ||
| 812 | if (copy_len > 0) { | ||
| 813 | @memcpy(new_rows[0..copy_len], old_rows[0..copy_len]); | ||
| 814 | } | ||
| 815 | |||
| 816 | if (row_count < old_rows.len) { | ||
| 817 | var row_idx = row_count; | ||
| 818 | while (row_idx < old_rows.len) : (row_idx += 1) { | ||
| 819 | old_rows[row_idx].deinit(alloc); | ||
| 820 | } | ||
| 821 | } | ||
| 822 | |||
| 823 | if (old_rows.len > 0) { | ||
| 824 | alloc.free(old_rows); | ||
| 825 | } | ||
| 826 | |||
| 827 | self.rows = new_rows; | ||
| 828 | } | ||
| 829 | |||
| 830 | fn deinit(self: *RenderCache, alloc: std.mem.Allocator) void { | ||
| 831 | for (self.rows) |*row| row.deinit(alloc); | ||
| 832 | if (self.rows.len > 0) { | ||
| 833 | alloc.free(self.rows); | ||
| 834 | } | ||
| 835 | self.cursor_instances.deinit(alloc); | ||
| 836 | self.packed_instances.deinit(alloc); | ||
| 837 | self.* = .{}; | ||
| 729 | } | 838 | } |
| 730 | }; | 839 | }; |
| 731 | 840 | ||