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)",
|
"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)",
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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 });
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user