Use std lib primitives for cross thread messaging.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Bill Thiede 2019-10-12 15:22:43 -07:00
parent ddb0bd893d
commit 7f28a321e3
4 changed files with 30 additions and 22 deletions

1
rtiow/Cargo.lock generated
View File

@ -1606,7 +1606,6 @@ dependencies = [
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"cpuprofiler 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "cpuprofiler 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"criterion 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "criterion 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -13,7 +13,6 @@ actix-web = "0.7.8"
askama = "0.7.1" askama = "0.7.1"
chrono = "*" chrono = "*"
cpuprofiler = { version = "0.0.3", optional = true } cpuprofiler = { version = "0.0.3", optional = true }
crossbeam-channel = "0.3"
image = "0.19.0" image = "0.19.0"
lazy_static = "1.1.0" lazy_static = "1.1.0"
log = "0.4.5" log = "0.4.5"

View File

@ -20,7 +20,6 @@ pub mod texture;
pub mod translate; pub mod translate;
pub mod vec3; pub mod vec3;
extern crate crossbeam_channel;
extern crate image; extern crate image;
#[macro_use] #[macro_use]
extern crate log; extern crate log;

View File

@ -6,9 +6,13 @@ use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::str; use std::str;
use std::sync; use std::sync;
use std::sync::mpsc::sync_channel;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::SyncSender;
use std::sync::Arc;
use std::sync::Mutex;
use std::thread; use std::thread;
use crossbeam_channel as channel;
use image; use image;
use image::RgbImage; use image::RgbImage;
use num_cpus; use num_cpus;
@ -156,7 +160,7 @@ pub fn opt_hash(opt: &Opt) -> String {
} }
pub struct Scene { pub struct Scene {
pub world: Box<Hit>, pub world: Box<dyn Hit>,
pub camera: Camera, pub camera: Camera,
pub subsamples: usize, pub subsamples: usize,
pub num_threads: Option<usize>, pub num_threads: Option<usize>,
@ -171,7 +175,7 @@ pub struct Scene {
// world. If false, it is expected the scene has emissive light sources. // world. If false, it is expected the scene has emissive light sources.
fn color( fn color(
r: Ray, r: Ray,
world: &Hit, world: &dyn Hit,
depth: usize, depth: usize,
global_illumination: bool, global_illumination: bool,
env_map: &Option<EnvMap>, env_map: &Option<EnvMap>,
@ -255,19 +259,25 @@ fn render_pixel(scene: &Scene, x: usize, y: usize) -> Vec3 {
fn render_worker( fn render_worker(
tid: usize, tid: usize,
scene: &Scene, scene: &Scene,
input_chan: channel::Receiver<Request>, input_chan: Arc<Mutex<Receiver<Request>>>,
output_chan: &channel::Sender<Response>, output_chan: &SyncSender<Response>,
) { ) {
for req in input_chan { loop {
match req { match input_chan.lock().unwrap().recv() {
Request::Line { width, y } => { Err(err) => {
let pixels = (0..width).map(|x| render_pixel(scene, x, y)).collect(); info!("Shutting down render_worker {}: {}", tid, err);
output_chan.send(Response::Line { width, y, pixels }); return;
}
Request::Pixel { x, y } => {
let pixel = render_pixel(scene, x, y);
output_chan.send(Response::Pixel { x, y, pixel });
} }
Ok(req) => match req {
Request::Line { width, y } => {
let pixels = (0..width).map(|x| render_pixel(scene, x, y)).collect();
output_chan.send(Response::Line { width, y, pixels });
}
Request::Pixel { x, y } => {
let pixel = render_pixel(scene, x, y);
output_chan.send(Response::Pixel { x, y, pixel });
}
},
} }
} }
trace!(target: "renderer", "Shutting down worker {}", tid); trace!(target: "renderer", "Shutting down worker {}", tid);
@ -275,10 +285,11 @@ fn render_worker(
pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::io::Error> { pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::io::Error> {
let num_threads = scene.num_threads.unwrap_or_else(num_cpus::get); let num_threads = scene.num_threads.unwrap_or_else(num_cpus::get);
let (pixel_req_tx, pixel_req_rx) = channel::bounded(2 * num_threads); let (pixel_req_tx, pixel_req_rx) = sync_channel(2 * num_threads);
let (pixel_resp_tx, pixel_resp_rx) = channel::bounded(2 * num_threads); let (pixel_resp_tx, pixel_resp_rx) = sync_channel(2 * num_threads);
let scene = sync::Arc::new(scene); let scene = Arc::new(scene);
let pixel_req_rx = Arc::new(Mutex::new(pixel_req_rx));
println!("Creating {} render threads", num_threads); println!("Creating {} render threads", num_threads);
for i in 0..num_threads { for i in 0..num_threads {
let s = sync::Arc::clone(&scene); let s = sync::Arc::clone(&scene);
@ -293,8 +304,8 @@ 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 || {
let batch_by_line = true; let batch_line_requests = true;
if batch_by_line { if batch_line_requests {
for y in 0..h { for y in 0..h {
pixel_req_tx.send(Request::Line { width: w, y }); pixel_req_tx.send(Request::Line { width: w, y });
} }