Make render req/response enums.
All checks were successful
continuous-integration/drone/push Build is passing

First step in some optimizations to limit overhead of locking between
threads.
This commit is contained in:
Bill Thiede 2019-10-11 08:03:32 -07:00
parent bcf6b6d5d0
commit 8b99a1f487

View File

@ -219,38 +219,46 @@ fn trace_pixel(x: usize, y: usize, scene: &Scene) -> Vec3 {
) )
} }
struct PixelRequest { enum Request {
x: usize, Pixel { x: usize, y: usize },
y: usize, Line { width: usize, y: usize },
} }
struct PixelResponse { enum Response {
x: usize, Pixel {
y: usize, x: usize,
pixel: Vec3, y: usize,
pixel: Vec3,
},
Line {
width: usize,
y: usize,
pixels: Vec<Vec3>,
},
} }
fn render_worker( fn render_worker(
tid: usize, tid: usize,
scene: &Scene, scene: &Scene,
input_chan: channel::Receiver<PixelRequest>, input_chan: channel::Receiver<Request>,
output_chan: &channel::Sender<PixelResponse>, output_chan: &channel::Sender<Response>,
) { ) {
for req in input_chan { for req in input_chan {
let mut pixel: Vec3 = Default::default(); match req {
for _ in 0..scene.subsamples { Request::Pixel { x, y } => {
pixel = pixel + trace_pixel(req.x, req.y, scene); let mut pixel: Vec3 = Default::default();
} for _ in 0..scene.subsamples {
pixel = pixel / scene.subsamples as f32; pixel = pixel + trace_pixel(x, y, scene);
// Gamma correct, use gamma 2 correction, which is 1/gamma where gamma=2 which is 1/2 or }
// sqrt. pixel = pixel / scene.subsamples as f32;
let pixel = Vec3::new(pixel[0].sqrt(), pixel[1].sqrt(), pixel[2].sqrt()); // Gamma correct, use gamma 2 correction, which is 1/gamma where gamma=2 which is 1/2 or
// sqrt.
let pixel = Vec3::new(pixel[0].sqrt(), pixel[1].sqrt(), pixel[2].sqrt());
output_chan.send(PixelResponse { output_chan.send(Response::Pixel { x, y, pixel });
x: req.x, }
y: req.y, _ => unimplemented!("Only Pixel requests are implemented"),
pixel, }
});
} }
trace!(target: "renderer", "Shutting down worker {}", tid); trace!(target: "renderer", "Shutting down worker {}", tid);
} }
@ -275,9 +283,10 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
let (w, h) = (scene.width, scene.height); let (w, h) = (scene.width, scene.height);
thread::spawn(move || { thread::spawn(move || {
// TODO(wathiede): handle sending Line requests for optimization.
for y in 0..w { for y in 0..w {
for x in 0..h { for x in 0..h {
pixel_req_tx.send(PixelRequest { x, y }); pixel_req_tx.send(Request::Pixel { x, y });
} }
} }
drop(pixel_req_tx); drop(pixel_req_tx);
@ -288,25 +297,30 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
let total = scene.width * scene.height; let total = scene.width * scene.height;
let mut last_progress = 1000; let mut last_progress = 1000;
for (i, resp) in pixel_resp_rx.iter().enumerate() { for (i, resp) in pixel_resp_rx.iter().enumerate() {
let y_inv = scene.height - resp.y - 1; match resp {
img.put_pixel( Response::Pixel { x, y, pixel } => {
resp.x as u32, let y_inv = scene.height - y - 1;
y_inv as u32, img.put_pixel(
image::Rgb([ x as u32,
(resp.pixel[0] * 255.).min(255.) as u8, y_inv as u32,
(resp.pixel[1] * 255.).min(255.) as u8, image::Rgb([
(resp.pixel[2] * 255.).min(255.) as u8, (pixel[0] * 255.).min(255.) as u8,
]), (pixel[1] * 255.).min(255.) as u8,
); (pixel[2] * 255.).min(255.) as u8,
let progress = 100 * i / total; ]),
if progress != last_progress { );
last_progress = progress; let progress = 100 * i / total;
if progress % 10 == 0 { if progress != last_progress {
print!("{}%", progress); last_progress = progress;
} else { if progress % 10 == 0 {
print!("."); print!("{}%", progress);
} else {
print!(".");
}
io::stdout().flush().unwrap();
}
} }
io::stdout().flush().unwrap(); _ => unimplemented!("Only Pixel responses are implemented"),
} }
} }
println!(); println!();