summaryrefslogtreecommitdiff
path: root/racer-tracer/src/render.rs
diff options
context:
space:
mode:
authorSakarias Johansson <sakarias.johansson@goodbyekansas.com>2023-03-03 15:56:26 +0100
committerSakarias Johansson <sakariasjohansson@hotmail.com>2023-03-03 20:12:05 +0100
commit548011ba6316e83c95b327768581d7d53d49a63e (patch)
tree3307873a1337f5688eb29e514c04fe0ed6345a97 /racer-tracer/src/render.rs
parent971372cf6350533e36db0404afedb1a36817037c (diff)
downloadracer-tracer-548011ba6316e83c95b327768581d7d53d49a63e.tar.gz
racer-tracer-548011ba6316e83c95b327768581d7d53d49a63e.tar.xz
racer-tracer-548011ba6316e83c95b327768581d7d53d49a63e.zip
🛠 Cleanup error handling & functionalize
Diffstat (limited to 'racer-tracer/src/render.rs')
-rw-r--r--racer-tracer/src/render.rs220
1 files changed, 122 insertions, 98 deletions
diff --git a/racer-tracer/src/render.rs b/racer-tracer/src/render.rs
index 8e01acb..fefafce 100644
--- a/racer-tracer/src/render.rs
+++ b/racer-tracer/src/render.rs
@@ -6,6 +6,7 @@ use synchronoise::SignalEvent;
use crate::{
camera::Camera,
config::RenderData,
+ error::TracerError,
geometry::Hittable,
image::{Image, SubImage},
ray::Ray,
@@ -41,7 +42,7 @@ pub fn raytrace_scaled(
image: &SubImage,
data: &RenderData,
scale: (usize, usize),
-) {
+) -> Result<(), TracerError> {
let (scale_width, scale_height) = scale;
let scaled_width = image.width / scale_width;
let scaled_height = image.height / scale_height;
@@ -63,33 +64,36 @@ pub fn raytrace_scaled(
}
if do_cancel(cancel_event) {
- return;
+ return Ok(());
}
}
- if do_cancel(cancel_event) {
- return;
- }
-
- let mut buf = buffer
- .write()
- .expect("Failed to get write guard when flushing data.");
-
- let offset = image.y * image.screen_width + image.x;
- for scaled_row in 0..scaled_height {
- for scaled_col in 0..scaled_width {
- let color = colors[scaled_row * scaled_width + scaled_col]
- .scale_sqrt(data.samples)
- .as_color();
- let row = scaled_row * scale_height;
- let col = scaled_col * scale_width;
- for scale_h in 0..scale_height {
- for scale_w in 0..scale_width {
- buf[offset + (row + scale_h) * image.screen_width + col + scale_w] = color;
+ (!do_cancel(cancel_event))
+ .then_some(|| ())
+ .ok_or(TracerError::CancelEvent)
+ .and_then(|_| {
+ buffer
+ .write()
+ .map_err(|e| TracerError::FailedToAcquireLock(e.to_string()))
+ })
+ .map(|mut buf| {
+ let offset = image.y * image.screen_width + image.x;
+ for scaled_row in 0..scaled_height {
+ for scaled_col in 0..scaled_width {
+ let color = colors[scaled_row * scaled_width + scaled_col]
+ .scale_sqrt(data.samples)
+ .as_color();
+ let row = scaled_row * scale_height;
+ let col = scaled_col * scale_width;
+ for scale_h in 0..scale_height {
+ for scale_w in 0..scale_width {
+ buf[offset + (row + scale_h) * image.screen_width + col + scale_w] =
+ color;
+ }
+ }
}
}
- }
- }
+ })
}
pub fn raytrace(
@@ -99,7 +103,7 @@ pub fn raytrace(
camera: Camera,
image: &SubImage,
data: &RenderData,
-) {
+) -> Result<(), TracerError> {
let mut colors: Vec<Vec3> = vec![Vec3::default(); image.height * image.width];
for row in 0..image.height {
for column in 0..image.width {
@@ -117,27 +121,29 @@ pub fn raytrace(
}
if do_cancel(cancel_event) {
- return;
+ return Ok(());
}
}
- if do_cancel(cancel_event) {
- return;
- }
-
- let mut buf = buffer
- .write()
- .expect("Failed to get write guard when flushing data.");
-
- let offset = image.y * image.screen_width + image.x;
- for row in 0..image.height {
- for col in 0..image.width {
- let color = colors[row * image.width + col]
- .scale_sqrt(data.samples)
- .as_color();
- buf[offset + row * image.screen_width + col] = color;
- }
- }
+ (!do_cancel(cancel_event))
+ .then_some(|| ())
+ .ok_or(TracerError::CancelEvent)
+ .and_then(|_| {
+ buffer
+ .write()
+ .map_err(|e| TracerError::FailedToAcquireLock(e.to_string()))
+ })
+ .map(|mut buf| {
+ let offset = image.y * image.screen_width + image.x;
+ for row in 0..image.height {
+ for col in 0..image.width {
+ let color = colors[row * image.width + col]
+ .scale_sqrt(data.samples)
+ .as_color();
+ buf[offset + row * image.screen_width + col] = color;
+ }
+ }
+ })
}
fn do_cancel(cancel_event: Option<&SignalEvent>) -> bool {
@@ -163,70 +169,88 @@ pub fn render(
data: &RenderData,
cancel_event: Option<&SignalEvent>,
scale: Option<usize>,
-) {
+) -> Result<(), TracerError> {
if do_cancel(cancel_event) {
- return;
+ return Ok(());
}
- let cam = camera.read().expect("TODO").clone();
+
let width_step = image.width / data.num_threads_width;
let height_step = image.height / data.num_threads_height;
-
let scaled_width = scale.map_or(1, |s| get_highest_divdable(width_step, s));
let scaled_height = scale.map_or(1, |s| get_highest_divdable(height_step, s));
- (0..data.num_threads_width)
- .flat_map(|ws| {
- let subs: Vec<SubImage> = (0..data.num_threads_height)
- .map(|hs| SubImage {
- x: width_step * ws,
- y: height_step * hs,
- screen_width: image.width,
- screen_height: image.height,
-
- // Neccesary in case the threads width is not
- // evenly divisible by the image width.
- width: if ws == data.num_threads_width - 1 {
- image.width - width_step * ws
- } else {
- width_step
- },
-
- // Neccesary in case the threads height is not
- // evenly divisible by the image height.
- height: if hs == data.num_threads_height - 1 {
- image.height - height_step * hs
- } else {
- height_step
- },
+ (!do_cancel(cancel_event))
+ .then_some(|| ())
+ .ok_or(TracerError::CancelEvent)
+ .and_then(|_| {
+ camera
+ .read()
+ .map_err(|e| TracerError::FailedToAcquireLock(e.to_string()))
+ // We make a clone of it as it's not very important to
+ // have the latest camera angle etc. Better to keep
+ // the lock to a minimum.
+ .map(|cam| cam.clone())
+ })
+ .map(|cam| {
+ let images = (0..data.num_threads_width)
+ .flat_map(|ws| {
+ (0..data.num_threads_height)
+ .map(|hs| SubImage {
+ x: width_step * ws,
+ y: height_step * hs,
+ screen_width: image.width,
+ screen_height: image.height,
+
+ // Neccesary in case the threads width is not
+ // evenly divisible by the image width.
+ width: if ws == data.num_threads_width - 1 {
+ image.width - width_step * ws
+ } else {
+ width_step
+ },
+
+ // Neccesary in case the threads height is not
+ // evenly divisible by the image height.
+ height: if hs == data.num_threads_height - 1 {
+ image.height - height_step * hs
+ } else {
+ height_step
+ },
+ })
+ .collect::<Vec<SubImage>>()
})
- .collect();
- subs
+ .collect::<Vec<SubImage>>();
+
+ (cam, images)
})
- .collect::<Vec<SubImage>>()
- .into_par_iter()
- .for_each(|image| {
- scale.map_or_else(
- || {
- raytrace(
- buffer,
- cancel_event,
- (*scene).borrow(),
- cam.clone(),
- &image,
- data,
+ .and_then(|(cam, sub_images)| {
+ sub_images
+ .into_par_iter()
+ .map(|image| {
+ scale.map_or_else(
+ || {
+ raytrace(
+ buffer,
+ cancel_event,
+ (*scene).borrow(),
+ cam.clone(),
+ &image,
+ data,
+ )
+ },
+ |_| {
+ raytrace_scaled(
+ buffer,
+ cancel_event,
+ (*scene).borrow(),
+ cam.clone(),
+ &image,
+ data,
+ (scaled_width, scaled_height),
+ )
+ },
)
- },
- |_| {
- raytrace_scaled(
- buffer,
- cancel_event,
- (*scene).borrow(),
- cam.clone(),
- &image,
- data,
- (scaled_width, scaled_height),
- )
- },
- );
- });
+ })
+ .collect::<Result<(), TracerError>>()
+ })
}