librashader_runtime/
framebuffer.rs1use crate::binding::{BindingRequirements, BindingUtil};
2use librashader_reflect::reflect::semantics::BindingMeta;
3use std::collections::VecDeque;
4
5pub struct FramebufferInit<'a, F, I, E> {
7    owned_generator: &'a dyn Fn() -> Result<F, E>,
8    input_generator: &'a dyn Fn() -> I,
9    requirements: BindingRequirements,
10    filters_count: usize,
11}
12
13impl<'a, F, I, E> FramebufferInit<'a, F, I, E> {
14    pub fn new(
17        filters: impl Iterator<Item = &'a BindingMeta> + ExactSizeIterator,
18        owned_generator: &'a dyn Fn() -> Result<F, E>,
19        input_generator: &'a dyn Fn() -> I,
20    ) -> Self {
21        let filters_count = filters.len();
22        let requirements = BindingMeta::calculate_requirements(filters);
23
24        Self {
25            owned_generator,
26            input_generator,
27            filters_count,
28            requirements,
29        }
30    }
31
32    pub fn init_history(&self) -> Result<(VecDeque<F>, Box<[I]>), E> {
34        init_history(
35            self.requirements.required_history,
36            self.owned_generator,
37            self.input_generator,
38        )
39    }
40
41    pub fn init_output_framebuffers(&self) -> Result<(Box<[F]>, Box<[I]>), E> {
43        init_output_framebuffers(
44            self.filters_count,
45            self.owned_generator,
46            self.input_generator,
47        )
48    }
49
50    pub const fn uses_final_pass_as_feedback(&self) -> bool {
52        self.requirements.uses_final_pass_as_feedback
53    }
54}
55
56fn init_history<'a, F, I, E>(
57    required_images: usize,
58    owned_generator: impl Fn() -> Result<F, E>,
59    input_generator: impl Fn() -> I,
60) -> Result<(VecDeque<F>, Box<[I]>), E> {
61    if required_images < 1 {
65        return Ok((VecDeque::new(), Box::new([])));
66    }
67
68    let mut framebuffers = VecDeque::with_capacity(required_images);
69    framebuffers.resize_with(required_images, owned_generator);
70
71    let framebuffers = framebuffers
72        .into_iter()
73        .collect::<Result<VecDeque<F>, E>>()?;
74
75    let mut history_textures = Vec::new();
76    history_textures.resize_with(required_images, input_generator);
77
78    Ok((framebuffers, history_textures.into_boxed_slice()))
79}
80
81fn init_output_framebuffers<F, I, E>(
82    len: usize,
83    owned_generator: impl Fn() -> Result<F, E>,
84    input_generator: impl Fn() -> I,
85) -> Result<(Box<[F]>, Box<[I]>), E> {
86    let mut output_framebuffers = Vec::new();
87    output_framebuffers.resize_with(len, owned_generator);
88
89    let output_framebuffers = output_framebuffers
91        .into_iter()
92        .collect::<Result<Vec<F>, E>>()?;
93
94    let mut output_textures = Vec::new();
95    output_textures.resize_with(len, input_generator);
96
97    Ok((
98        output_framebuffers.into_boxed_slice(),
99        output_textures.into_boxed_slice(),
100    ))
101}