Make main rendering loop multithreaded again.

This commit is contained in:
Matthew Gordon 2020-02-28 20:51:06 -05:00
parent 254957c5c3
commit a04f51998c
4 changed files with 45 additions and 35 deletions

View File

@ -12,6 +12,7 @@ itertools = "0.8"
obj = "0.9" obj = "0.9"
quickcheck = "0.9" quickcheck = "0.9"
quickcheck_macros = "0.8" quickcheck_macros = "0.8"
rayon = "1.3"
sdl2 = "0.32" sdl2 = "0.32"
[dependencies.nalgebra] [dependencies.nalgebra]

View File

@ -1,3 +1,5 @@
use rayon::prelude::*;
use sdl2::event::Event; use sdl2::event::Event;
use sdl2::keyboard::Keycode; use sdl2::keyboard::Keycode;
use sdl2::pixels::PixelFormatEnum; use sdl2::pixels::PixelFormatEnum;
@ -8,6 +10,7 @@ use std::time::Duration;
use nalgebra::{Point3, Vector3}; use nalgebra::{Point3, Vector3};
use std::path::Path; use std::path::Path;
use std::sync::mpsc;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use vanrijn::camera::partial_render_scene; use vanrijn::camera::partial_render_scene;
@ -47,8 +50,8 @@ fn init_canvas(
} }
pub fn main() -> Result<(), Box<dyn std::error::Error>> { pub fn main() -> Result<(), Box<dyn std::error::Error>> {
let image_width = 320usize; let image_width = 640usize;
let image_height = 240usize; let image_height = 480usize;
let (sdl_context, mut canvas) = init_canvas(image_width, image_height)?; let (sdl_context, mut canvas) = init_canvas(image_width, image_height)?;
@ -115,42 +118,46 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut event_pump = sdl_context.event_pump()?; let mut event_pump = sdl_context.event_pump()?;
'running: for tile in TileIterator::new(image_width as usize, image_height as usize, 16) { let (tile_tx, tile_rx) = mpsc::channel();
let image_ptr = output_image.clone(); let mut tile_rx = Some(tile_rx);
let scene_ptr = scene.clone();
partial_render_scene(
image_ptr,
scene_ptr,
tile.start_row,
tile.end_row,
tile.start_column,
tile.end_column,
image_height,
image_width,
);
let locked_image = output_image.lock().unwrap(); let output_image_workers = Arc::clone(&output_image);
let mut output_image_rgbu8 = ImageRgbU8::new(image_width, image_height); let worker_boss = std::thread::spawn(move || {
ClampingToneMapper {}.apply_tone_mapping(&locked_image, &mut output_image_rgbu8); TileIterator::new(image_width as usize, image_height as usize, 16)
update_texture(&output_image_rgbu8, &mut rendered_image_texture); .map(move |tile| (tile, tile_tx.clone()))
canvas.copy(&rendered_image_texture, None, None)?; .par_bridge()
canvas.present(); .try_for_each(|(tile, tx)| {
let image_ptr = Arc::clone(&output_image_workers);
let scene_ptr = scene.clone();
partial_render_scene(
image_ptr,
scene_ptr,
tile.start_row,
tile.end_row,
tile.start_column,
tile.end_column,
image_height,
image_width,
);
for event in event_pump.poll_iter() { // There's nothing we can do if this fails, and we're already
match event { // at the end of the function anyway, so just ignore result.
Event::Quit { .. } tx.send(tile).ok()
| Event::KeyDown { });
keycode: Some(Keycode::Escape), });
..
} => break 'running, 'running: loop {
_ => {} if let Some(ref tile_rx) = tile_rx {
for tile in tile_rx.try_iter() {
let locked_image = output_image.lock().unwrap();
let mut output_image_rgbu8 = ImageRgbU8::new(image_width, image_height);
ClampingToneMapper {}.apply_tone_mapping(&locked_image, &mut output_image_rgbu8);
update_texture(&output_image_rgbu8, &mut rendered_image_texture);
canvas.copy(&rendered_image_texture, None, None).unwrap();
canvas.present();
} }
} }
}
let mut i = 0;
'running: loop {
i = (i + 1) % 255;
for event in event_pump.poll_iter() { for event in event_pump.poll_iter() {
match event { match event {
Event::Quit { .. } Event::Quit { .. }
@ -164,5 +171,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60)); ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
} }
drop(tile_rx.take());
worker_boss.join().expect("Couldn't join worker threads.");
Ok(()) Ok(())
} }

View File

@ -6,4 +6,4 @@ pub mod axis_aligned_bounding_box;
pub mod morton; pub mod morton;
pub mod normalizer; pub mod normalizer;
mod tile_iterator; mod tile_iterator;
pub use tile_iterator::TileIterator; pub use tile_iterator::{Tile, TileIterator};

View File

@ -1,4 +1,4 @@
#[derive(Debug)] #[derive(Copy, Clone, Debug)]
pub struct Tile { pub struct Tile {
pub start_column: usize, pub start_column: usize,
pub end_column: usize, pub end_column: usize,