-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Draft interface for a render pipeline.
- Loading branch information
Showing
2 changed files
with
107 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 +10,5 @@ pub mod error; | |
pub mod headers; | ||
pub mod icc; | ||
pub mod image; | ||
pub mod render; | ||
mod util; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
use crate::{ | ||
error::Result, | ||
image::{ImageDataType, ImageRectMut}, | ||
}; | ||
|
||
// All *_row_chunk functions here take one or two slices of slices. | ||
// The slices have as many entries as the number of used channels for the stage, i.e. the channels | ||
// for which `uses_channel` returns true. | ||
|
||
// These are the only stages that are assumed to have observable effects, i.e. calls to process_row | ||
// for other stages may be omitted if it can be shown they can't affect any Input stage process_row | ||
// call that happens inside image boundaries. | ||
pub trait RenderPipelineInputStage<InputT: ImageDataType> { | ||
fn uses_channel(&self, c: usize) -> bool; | ||
fn process_row_chunk(&mut self, position: (usize, usize), xsize: usize, row: &[&[InputT]]); | ||
} | ||
|
||
// Modifies channels in-place. | ||
pub trait RenderPipelineInPlaceStage<T: ImageDataType> { | ||
fn uses_channel(&self, c: usize) -> bool; | ||
fn process_row_chunk(&mut self, position: (usize, usize), xsize: usize, row: &mut [&mut [T]]); | ||
} | ||
|
||
// Modifies data and writes it to a new buffer, of possibly different type. | ||
pub trait RenderPipelineInOutStage<InputT: ImageDataType, OutputT: ImageDataType> { | ||
// Amount of padding required on the input side. | ||
const BORDER: (usize, usize); | ||
// log2 of the number of rows/columns produced for each row/column of input. | ||
const SHIFT: (usize, usize); | ||
|
||
fn uses_channel(&self, c: usize) -> bool; | ||
|
||
// For each channel: | ||
// - the input slice contains 1 + Self::BORDER.1 * 2 slices, each of length | ||
// xsize + Self::BORDER.0 * 2, i.e. covering one input row and up to BORDER pixels of | ||
// padding on either side. | ||
// - the output slice contains 1 << SHIFT.1 slices, each of length xsize << SHIFT.0, the | ||
// corresponding output pixels. | ||
fn process_row_chunk( | ||
&mut self, | ||
position: (usize, usize), | ||
xsize: usize, | ||
input: &[&[&[InputT]]], | ||
output: &mut [&mut [&mut [OutputT]]], | ||
); | ||
} | ||
|
||
// Does not directly modify the current image pixels, but extends the current image with | ||
// additional data. | ||
pub trait RenderPipelineExtendStage<T: ImageDataType> { | ||
// uses_channel is assumed to be always true | ||
fn new_size(&self) -> (usize, usize); | ||
fn original_data_origin(&self) -> (usize, usize); | ||
// passed buffer must always be entirely outside of the original image. | ||
fn fill_padding_row_chunk( | ||
&mut self, | ||
new_position: (usize, usize), | ||
xsize: usize, | ||
row: &mut [&mut [T]], | ||
); | ||
} | ||
|
||
pub trait RenderPipelineBuilder: Sized { | ||
type RenderPipeline: RenderPipeline; | ||
|
||
fn new(num_channels: usize, size: (usize, usize), group_size: usize) -> Self; | ||
|
||
fn add_input_stage<T: ImageDataType, Stage: RenderPipelineInputStage<T>>( | ||
self, | ||
stage: Stage, | ||
) -> Result<Self>; | ||
|
||
fn add_inplace_stage<T: ImageDataType, Stage: RenderPipelineInPlaceStage<T>>( | ||
self, | ||
stage: Stage, | ||
) -> Result<Self>; | ||
|
||
fn add_inout_stage< | ||
InT: ImageDataType, | ||
OutT: ImageDataType, | ||
Stage: RenderPipelineInOutStage<InT, OutT>, | ||
>( | ||
self, | ||
stage: Stage, | ||
) -> Result<Self>; | ||
|
||
fn add_extend_stage<T: ImageDataType, Stage: RenderPipelineExtendStage<T>>( | ||
self, | ||
stage: Stage, | ||
) -> Result<Self>; | ||
|
||
fn build(self) -> Self::RenderPipeline; | ||
} | ||
|
||
pub trait RenderPipeline { | ||
type Builder: RenderPipelineBuilder<RenderPipeline = Self>; | ||
|
||
// TODO(veluca): figure out a good multithreaded interface. | ||
fn fill_group_input<T: ImageDataType, F: FnMut(ImageRectMut<T>, usize) -> bool>( | ||
&mut self, | ||
_group_id: usize, | ||
_do_fill_group: F, | ||
) { | ||
todo!() | ||
} | ||
} |