Use std lib primitives for cross thread messaging.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
ddb0bd893d
commit
7f28a321e3
1
rtiow/Cargo.lock
generated
1
rtiow/Cargo.lock
generated
@ -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)",
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 });
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user