this repo has no description

added progress tracking

+45 -7
+45 -7
src/rayray.zig
··· 33 33 const s = spall.trace(@src(), "Render", .{}); 34 34 defer s.end(); 35 35 36 - const rows: usize = try std.Thread.getCpuCount(); 36 + const rows: usize = try std.Thread.getCpuCount() - 1; 37 37 const row_height = @divTrunc(self.camera.image_height, rows); 38 38 const num_threads = blk: { 39 39 if (self.camera.image_height % rows == 0) { ··· 44 44 45 45 log.debug("rows: {}, row_height: {}, num_threads: {}", .{ rows, row_height, num_threads }); 46 46 47 - const threads = try self.allocator.alloc(std.Thread, num_threads); 47 + var threads = try self.allocator.alloc(TaskTracker, num_threads); 48 48 defer self.allocator.free(threads); 49 49 50 + const finished_threads = try self.allocator.alloc(bool, num_threads); 51 + 50 52 for (0..num_threads) |row| { 51 - const t = try std.Thread.spawn(.{}, render_thread, .{ &self.camera, row, row_height }); 52 - threads[row] = t; 53 + const t = try std.Thread.spawn(.{}, render_thread, .{ &self.camera, row, row_height, &threads[row].done }); 54 + threads[row].thread = t; 53 55 } 54 56 55 - for (threads) |t| { 56 - t.join(); 57 + const stderr = std.io.getStdErr(); 58 + defer stderr.close(); 59 + 60 + var progress = std.Progress{ 61 + .terminal = stderr, 62 + .supports_ansi_escape_codes = true, 63 + }; 64 + var node = progress.start("Rendering Completed", num_threads); 65 + node.activate(); 66 + 67 + while (true) { 68 + var done = true; 69 + node.activate(); 70 + 71 + for (0..num_threads) |id| { 72 + if (threads[id].done and !threads[id].marked_as_done) { 73 + threads[id].thread.join(); 74 + threads[id].marked_as_done = true; 75 + finished_threads[id] = true; 76 + node.completeOne(); 77 + } else if (!threads[id].done) { 78 + done = false; 79 + } 80 + } 81 + 82 + if (done) break; 57 83 } 58 84 59 85 return self.camera.image; 60 86 } 61 87 62 - fn render_thread(cam: *Camera, row: usize, height: usize) void { 88 + fn render_thread(cam: *Camera, row: usize, height: usize, done: *bool) void { 63 89 spall.init_thread(); 64 90 defer spall.deinit_thread(); 91 + 92 + log.debug("Started Render Thread {}", .{row}); 65 93 66 94 const s = spall.trace(@src(), "Render Thread {}", .{row}); 67 95 defer s.end(); ··· 79 107 cam.setPixel(i, j, col) catch break; 80 108 } 81 109 } 110 + 111 + done.* = true; 112 + 113 + // log.debug("Render Thread {} is done", .{row}); 82 114 } 115 + }; 116 + 117 + const TaskTracker = struct { 118 + thread: std.Thread, 119 + done: bool = false, 120 + marked_as_done: bool = false, 83 121 }; 84 122 85 123 fn vecToRgba(v: zm.Vec) color.Rgba32 {