1use std::{cell::Cell, num::NonZeroU64};
16
17use rayon::prelude::*;
18
19use crate::{
20 composition::InnerLayer,
21 consts,
22 math::AffineTransform,
23 utils::{ExtendTuple10, ExtendTuple3},
24 Path,
25};
26
27const MIN_LEN: usize = 1_024;
28
29fn integers_between(a: f32, b: f32) -> u32 {
30 let min = a.min(b);
31 let max = a.max(b);
32
33 0.max((max.ceil() - min.floor() - 1.0) as u32)
34}
35
36fn manhattan_segment_length(p0x: f32, p1x: f32, p0y: f32, p1y: f32) -> u32 {
62 integers_between(p0x, p1x) + integers_between(p0y, p1y) + 1
63}
64
65fn prefix_sum(vals: &mut [u32]) -> u32 {
66 let mut sum = 0;
67 for val in vals {
68 sum += *val;
69 *val = sum;
70 }
71
72 sum
73}
74
75#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
76#[repr(transparent)]
77pub struct GeomId(NonZeroU64);
78
79impl GeomId {
80 #[cfg(test)]
81 pub fn get(self) -> u64 {
82 self.0.get() - 1
83 }
84
85 #[inline]
86 pub fn next(self) -> Self {
87 Self(
88 NonZeroU64::new(
89 self.0
90 .get()
91 .checked_add(1)
92 .expect("id should never reach u64::MAX"),
93 )
94 .unwrap(),
95 )
96 }
97}
98
99impl Default for GeomId {
100 #[inline]
101 fn default() -> Self {
102 Self(NonZeroU64::new(1).unwrap())
103 }
104}
105
106#[derive(Debug, Default)]
107pub struct SegmentBuffer {
108 view: SegmentBufferView,
109 cached_len: Cell<usize>,
110 cached_until: Cell<usize>,
111}
112
113impl SegmentBuffer {
114 #[allow(clippy::len_without_is_empty)]
116 #[inline]
117 pub fn len(&self) -> usize {
118 if self.view.ids.len() <= self.cached_until.get() {
119 self.cached_len.get()
120 } else {
121 let new_len = self.cached_len.get()
122 + self.view.ids[self.cached_until.get()..]
123 .iter()
124 .filter(|id| id.is_some())
125 .count();
126
127 self.cached_len.set(new_len);
128 self.cached_until.set(self.view.ids.len());
129
130 new_len
131 }
132 }
133
134 #[inline]
135 pub fn push_path(&mut self, id: GeomId, path: &Path) {
136 path.push_segments_to(&mut self.view.x, &mut self.view.y, id, &mut self.view.ids);
137
138 self.view.ids.resize(
139 self.view.x.len().checked_sub(1).unwrap_or_default(),
140 Some(id),
141 );
142
143 if self
144 .view
145 .ids
146 .last()
147 .map(Option::is_some)
148 .unwrap_or_default()
149 {
150 self.view.ids.push(None);
151 }
152 }
153
154 #[cfg(test)]
155 pub fn push(&mut self, id: GeomId, segment: [crate::math::Point; 2]) {
156 let new_point_needed =
157 if let (Some(&x), Some(&y)) = (self.view.x.last(), self.view.y.last()) {
158 let last_point = crate::math::Point { x, y };
159
160 last_point != segment[0]
161 } else {
162 true
163 };
164
165 if new_point_needed {
166 self.view.x.push(segment[0].x);
167 self.view.y.push(segment[0].y);
168 }
169
170 self.view.x.push(segment[1].x);
171 self.view.y.push(segment[1].y);
172
173 if self.view.ids.len() >= 2 {
174 match self.view.ids[self.view.ids.len() - 2] {
175 Some(last_id) if last_id != id => {
176 self.view.ids.push(Some(id));
177 self.view.ids.push(None);
178 }
179 _ => {
180 self.view.ids.pop();
181 self.view.ids.push(Some(id));
182 self.view.ids.push(None);
183 }
184 }
185 } else {
186 self.view.ids.push(Some(id));
187 self.view.ids.push(None);
188 }
189 }
190
191 pub fn retain<F>(&mut self, mut f: F)
192 where
193 F: FnMut(GeomId) -> bool,
194 {
195 let len = self.view.x.len();
196 let mut del = 0;
197 let mut prev_id = None;
198
199 for i in 0..len {
200 let id = self.view.ids[i];
204 let should_retain = id
205 .or(prev_id)
206 .map(&mut f)
207 .expect("consecutive None values should not exist in ids");
208 prev_id = id;
209
210 if !should_retain {
211 del += 1;
212 continue;
213 }
214
215 if del > 0 {
216 self.view.x.swap(i - del, i);
217 self.view.y.swap(i - del, i);
218 self.view.ids.swap(i - del, i);
219 }
220 }
221
222 if del > 0 {
223 self.view.x.truncate(len - del);
224 self.view.y.truncate(len - del);
225 self.view.ids.truncate(len - del);
226 }
227 }
228
229 pub fn fill_cpu_view<F>(mut self, layers: F) -> SegmentBufferView
230 where
231 F: Fn(GeomId) -> Option<InnerLayer> + Send + Sync,
232 {
233 let ps_layers = self.view.x.par_windows(2).with_min_len(MIN_LEN).zip_eq(
234 self.view.y.par_windows(2).with_min_len(MIN_LEN).zip_eq(
235 self.view.ids[..self.view.ids.len().checked_sub(1).unwrap_or_default()]
236 .par_iter()
237 .with_min_len(MIN_LEN),
238 ),
239 );
240 let par_iter = ps_layers.map(|(xs, (ys, &id))| {
241 let empty_line = Default::default();
242
243 let p0x = xs[0];
244 let p0y = ys[0];
245 let p1x = xs[1];
246 let p1y = ys[1];
247
248 if id.is_none() {
249 return empty_line;
252 }
253
254 let layer = match id.and_then(&layers) {
255 Some(layer) => layer,
256 None => return empty_line,
257 };
258
259 if let InnerLayer {
260 is_enabled: false, ..
261 } = layer
262 {
263 return empty_line;
264 }
265
266 let order = match layer.order {
267 Some(order) => order.as_u32(),
268 None => return empty_line,
269 };
270
271 fn transform_point(point: (f32, f32), transform: &AffineTransform) -> (f32, f32) {
272 (
273 transform
274 .ux
275 .mul_add(point.0, transform.vx.mul_add(point.1, transform.tx)),
276 transform
277 .uy
278 .mul_add(point.0, transform.vy.mul_add(point.1, transform.ty)),
279 )
280 }
281
282 let transform = layer
283 .affine_transform
284 .as_ref()
285 .map(|transform| &transform.0);
286
287 let (p0x, p0y, p1x, p1y) = if let Some(transform) = transform {
288 let (p0x, p0y) = transform_point((p0x, p0y), transform);
289 let (p1x, p1y) = transform_point((p1x, p1y), transform);
290
291 (p0x, p0y, p1x, p1y)
292 } else {
293 (p0x, p0y, p1x, p1y)
294 };
295
296 if p0y == p1y {
297 return empty_line;
298 }
299
300 let dx = p1x - p0x;
301 let dy = p1y - p0y;
302 let dx_recip = dx.recip();
303 let dy_recip = dy.recip();
304
305 let t_offset_x = if dx != 0.0 {
308 ((p0x.ceil() - p0x) * dx_recip).max((p0x.floor() - p0x) * dx_recip)
309 } else {
310 0.0
311 };
312 let t_offset_y = if dy != 0.0 {
313 ((p0y.ceil() - p0y) * dy_recip).max((p0y.floor() - p0y) * dy_recip)
314 } else {
315 0.0
316 };
317
318 let a = dx_recip.abs();
319 let b = dy_recip.abs();
320 let c = t_offset_x;
321 let d = t_offset_y;
322
323 let length = manhattan_segment_length(p0x, p1x, p0y, p1y);
324
325 (
327 order,
328 p0x * consts::PIXEL_WIDTH as f32,
329 p0y * consts::PIXEL_WIDTH as f32,
330 dx * consts::PIXEL_WIDTH as f32,
331 dy * consts::PIXEL_WIDTH as f32,
332 a,
333 b,
334 c,
335 d,
336 length,
337 )
338 });
339
340 ExtendTuple10::new((
341 &mut self.view.orders,
342 &mut self.view.x0,
343 &mut self.view.y0,
344 &mut self.view.dx,
345 &mut self.view.dy,
346 &mut self.view.a,
347 &mut self.view.b,
348 &mut self.view.c,
349 &mut self.view.d,
350 &mut self.view.lengths,
351 ))
352 .par_extend(par_iter);
353
354 prefix_sum(&mut self.view.lengths);
355
356 self.view
357 }
358
359 pub fn fill_gpu_view<F>(mut self, layers: F) -> SegmentBufferView
360 where
361 F: Fn(GeomId) -> Option<InnerLayer> + Send + Sync,
362 {
363 fn transform_point(point: (f32, f32), transform: &AffineTransform) -> (f32, f32) {
364 (
365 transform
366 .ux
367 .mul_add(point.0, transform.vx.mul_add(point.1, transform.tx)),
368 transform
369 .uy
370 .mul_add(point.0, transform.vy.mul_add(point.1, transform.ty)),
371 )
372 }
373
374 if !self.view.ids.is_empty() {
375 let point = match self.view.ids[0].and_then(&layers) {
376 None
377 | Some(
378 InnerLayer {
379 is_enabled: false, ..
380 }
381 | InnerLayer { order: None, .. },
382 ) => Default::default(),
383 Some(InnerLayer {
384 affine_transform: None,
385 ..
386 }) => [self.view.x[0], self.view.y[0]],
387 Some(InnerLayer {
388 affine_transform: Some(transform),
389 ..
390 }) => {
391 let (x, y) = transform_point((self.view.x[0], self.view.y[0]), &transform.0);
392 [x, y]
393 }
394 };
395 self.view.points.push(point);
396 }
397
398 let ps_layers = self.view.x.par_windows(2).with_min_len(MIN_LEN).zip_eq(
399 self.view
400 .y
401 .par_windows(2)
402 .with_min_len(MIN_LEN)
403 .zip_eq(self.view.ids.par_windows(2).with_min_len(MIN_LEN)),
404 );
405 let par_iter = ps_layers.map(|(xs, (ys, ids))| {
406 const NONE: u32 = u32::MAX;
407 let p0x = xs[0];
408 let p0y = ys[0];
409 let (p1x, p1y) = match ids[0].or(ids[1]).and_then(&layers) {
410 None
411 | Some(
412 InnerLayer {
413 is_enabled: false, ..
414 }
415 | InnerLayer { order: None, .. },
416 ) => (0.0, 0.0),
417 Some(InnerLayer {
418 affine_transform: None,
419 ..
420 }) => (xs[1], ys[1]),
421 Some(InnerLayer {
422 affine_transform: Some(transform),
423 ..
424 }) => transform_point((xs[1], ys[1]), &transform.0),
425 };
426
427 let layer = match ids[0].and_then(&layers) {
428 Some(layer) => layer,
429 None => return (0, [p1x, p1y], NONE),
431 };
432
433 if let InnerLayer {
434 is_enabled: false, ..
435 } = layer
436 {
437 return (0, [p1x, p1y], NONE);
438 }
439
440 let order = match layer.order {
441 Some(order) => order.as_u32(),
442 None => return (0, [p1x, p1y], NONE),
443 };
444
445 let transform = layer
446 .affine_transform
447 .as_ref()
448 .map(|transform| &transform.0);
449
450 let (p0x, p0y) = if let Some(transform) = transform {
451 transform_point((p0x, p0y), transform)
452 } else {
453 (p0x, p0y)
454 };
455
456 if p0y == p1y {
457 return (0, [p1x, p1y], NONE);
458 }
459 let length = integers_between(p0x, p1x) + integers_between(p0y, p1y) + 1;
460
461 (length, [p1x, p1y], order)
462 });
463
464 ExtendTuple3::new((
465 &mut self.view.lengths,
466 &mut self.view.points,
467 &mut self.view.orders,
468 ))
469 .par_extend(par_iter);
470
471 prefix_sum(&mut self.view.lengths);
472
473 self.view
474 }
475}
476
477#[derive(Debug, Default)]
483pub struct SegmentBufferView {
484 pub x: Vec<f32>,
485 pub y: Vec<f32>,
486 pub ids: Vec<Option<GeomId>>,
487 pub orders: Vec<u32>,
488 pub x0: Vec<f32>,
490 pub y0: Vec<f32>,
492 pub dx: Vec<f32>,
494 pub dy: Vec<f32>,
496 pub a: Vec<f32>,
498 pub b: Vec<f32>,
500 pub c: Vec<f32>,
502 pub d: Vec<f32>,
504 pub points: Vec<[f32; 2]>,
505 pub lengths: Vec<u32>,
508}
509
510impl SegmentBufferView {
511 #[inline]
512 pub fn recycle(mut self) -> SegmentBuffer {
513 self.orders.clear();
514 self.x0.clear();
515 self.y0.clear();
516 self.dx.clear();
517 self.dy.clear();
518 self.a.clear();
519 self.b.clear();
520 self.c.clear();
521 self.d.clear();
522 self.lengths.clear();
523 self.points.clear();
524
525 SegmentBuffer {
526 view: self,
527 ..Default::default()
528 }
529 }
530
531 pub fn len(&self) -> usize {
532 self.lengths.last().copied().unwrap_or_default() as usize
533 }
534
535 pub fn inner_len(&self) -> usize {
536 self.x.len() - 1
537 }
538}