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)",
"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)",
"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)",
"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)",

View File

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

View File

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

View File

@ -6,9 +6,13 @@ use std::path::Path;
use std::path::PathBuf;
use std::str;
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 crossbeam_channel as channel;
use image;
use image::RgbImage;
use num_cpus;
@ -156,7 +160,7 @@ pub fn opt_hash(opt: &Opt) -> String {
}
pub struct Scene {
pub world: Box<Hit>,
pub world: Box<dyn Hit>,
pub camera: Camera,
pub subsamples: 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.
fn color(
r: Ray,
world: &Hit,
world: &dyn Hit,
depth: usize,
global_illumination: bool,
env_map: &Option<EnvMap>,
@ -255,19 +259,25 @@ fn render_pixel(scene: &Scene, x: usize, y: usize) -> Vec3 {
fn render_worker(
tid: usize,
scene: &Scene,
input_chan: channel::Receiver<Request>,
output_chan: &channel::Sender<Response>,
input_chan: Arc<Mutex<Receiver<Request>>>,
output_chan: &SyncSender<Response>,
) {
for req in input_chan {
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 });
loop {
match input_chan.lock().unwrap().recv() {
Err(err) => {
info!("Shutting down render_worker {}: {}", tid, err);
return;
}
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);
@ -275,10 +285,11 @@ fn render_worker(
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 (pixel_req_tx, pixel_req_rx) = channel::bounded(2 * num_threads);
let (pixel_resp_tx, pixel_resp_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) = 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);
for i in 0..num_threads {
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);
thread::spawn(move || {
let batch_by_line = true;
if batch_by_line {
let batch_line_requests = true;
if batch_line_requests {
for y in 0..h {
pixel_req_tx.send(Request::Line { width: w, y });
}