blob: 6627547e51993113c5883eb1c12abac4e28f470f [file] [log] [blame]
// Copyright 2023 the Vello Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT OR Unlicense
use vello_encoding::{Clip, ClipBic, ClipElement, PathBbox};
use crate::cpu_dispatch::CpuBinding;
const WG_SIZE: usize = 256;
fn clip_reduce_main(
n_wg: u32,
clip_inp: &[Clip],
path_bboxes: &[PathBbox],
reduced: &mut [ClipBic],
clip_out: &mut [ClipElement],
) {
let mut scratch = Vec::with_capacity(WG_SIZE);
for wg_ix in 0..n_wg {
scratch.clear();
let mut bic_reduced = ClipBic::default();
// reverse scan
for local_ix in (0..WG_SIZE).rev() {
let global_ix = wg_ix as usize * WG_SIZE + local_ix;
let inp = clip_inp[global_ix].path_ix;
let is_push = inp >= 0;
let bic = ClipBic::new(1 - is_push as u32, is_push as u32);
bic_reduced = bic.combine(bic_reduced);
if is_push && bic_reduced.a == 0 {
scratch.push(global_ix as u32);
}
}
reduced[wg_ix as usize] = bic_reduced;
for (i, parent_ix) in scratch.iter().rev().enumerate() {
let mut clip_el = ClipElement::default();
clip_el.parent_ix = *parent_ix;
let path_ix = clip_inp[*parent_ix as usize].path_ix;
let path_bbox = path_bboxes[path_ix as usize];
clip_el.bbox = [
path_bbox.x0 as f32,
path_bbox.y0 as f32,
path_bbox.x1 as f32,
path_bbox.y1 as f32,
];
let global_ix = wg_ix as usize * WG_SIZE + i;
clip_out[global_ix] = clip_el;
}
}
}
pub fn clip_reduce(n_wg: u32, resources: &[CpuBinding]) {
let clip_inp = resources[0].as_slice();
let path_bboxes = resources[1].as_slice();
let mut reduced = resources[2].as_slice_mut();
let mut clip_out = resources[3].as_slice_mut();
clip_reduce_main(n_wg, &clip_inp, &path_bboxes, &mut reduced, &mut clip_out);
}