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}