1use crate::fine::COLOR_COMPONENTS;
7use alloc::vec::Vec;
8use vello_common::coarse::WideTile;
9use vello_common::tile::Tile;
10
11#[derive(Debug)]
12pub struct Regions<'a> {
13 regions: Vec<Region<'a>>,
14}
15
16impl<'a> Regions<'a> {
17 pub fn new(width: u16, height: u16, mut buffer: &'a mut [u8]) -> Self {
18 let buf_width = usize::from(width);
19 let buf_height = usize::from(height);
20
21 let row_advance = buf_width * COLOR_COMPONENTS;
22
23 let height_regions = buf_height.div_ceil(usize::from(Tile::HEIGHT));
24 let width_regions = buf_width.div_ceil(usize::from(WideTile::WIDTH));
25
26 let mut regions = Vec::with_capacity(height_regions * width_regions);
27
28 let mut next_lines: [&'a mut [u8]; Tile::HEIGHT as usize] =
29 [&mut [], &mut [], &mut [], &mut []];
30
31 for y in 0..height_regions {
32 let base_y = y * usize::from(Tile::HEIGHT);
33 let region_height = usize::from(Tile::HEIGHT).min(buf_height - base_y);
34
35 for line in next_lines.iter_mut().take(region_height) {
36 let (head, tail) = buffer.split_at_mut(row_advance);
37 *line = head;
38 buffer = tail;
39 }
40
41 for x in 0..width_regions {
42 let mut areas: [&mut [u8]; Tile::HEIGHT as usize] =
43 [&mut [], &mut [], &mut [], &mut []];
44
45 let region_width =
47 (usize::from(WideTile::WIDTH) * COLOR_COMPONENTS).min(next_lines[0].len());
48
49 for h in 0..region_height {
50 let next = core::mem::take(&mut next_lines[h]);
51 let (head, tail) = next.split_at_mut(region_width);
52 areas[h] = head;
53 next_lines[h] = tail;
54 }
55
56 regions.push(Region::new(
57 areas,
58 u16::try_from(x).unwrap(),
59 u16::try_from(y).unwrap(),
60 region_width as u16 / COLOR_COMPONENTS as u16,
61 region_height as u16,
62 ));
63 }
64 }
65
66 Self { regions }
67 }
68
69 #[cfg(feature = "multithreading")]
72 pub fn update_regions_par(&mut self, func: impl Fn(&mut Region<'_>) + Send + Sync) {
73 use rayon::iter::ParallelIterator;
74 use rayon::prelude::IntoParallelRefMutIterator;
75
76 self.regions.par_iter_mut().for_each(func);
77 }
78
79 pub fn update_regions(&mut self, func: impl FnMut(&mut Region<'_>)) {
81 self.regions.iter_mut().for_each(func);
82 }
83}
84
85#[derive(Default, Debug)]
91pub struct Region<'a> {
92 pub(crate) x: u16,
94 pub(crate) y: u16,
96 pub width: u16,
97 pub height: u16,
98 areas: [&'a mut [u8]; Tile::HEIGHT as usize],
99}
100
101impl<'a> Region<'a> {
102 pub(crate) fn new(
103 areas: [&'a mut [u8]; Tile::HEIGHT as usize],
104 x: u16,
105 y: u16,
106 width: u16,
107 height: u16,
108 ) -> Self {
109 Self {
110 areas,
111 x,
112 y,
113 width,
114 height,
115 }
116 }
117
118 pub(crate) fn row_mut(&mut self, y: u16) -> &mut [u8] {
119 self.areas[usize::from(y)]
120 }
121
122 pub fn areas(&mut self) -> &mut [&'a mut [u8]; Tile::HEIGHT as usize] {
123 &mut self.areas
124 }
125}