blob: 0f5fc61068d1a1196b6e970e3d28a164aeb36851 [file] [log] [blame] [edit]
// Copyright 2023 The Vello authors
// SPDX-License-Identifier: Apache-2.0 OR MIT OR Unlicense
use vello_encoding::{Clip, ConfigUniform, DrawMonoid, PathBbox};
use crate::cpu_dispatch::CpuBinding;
struct ClipStackElement {
// index of draw object
parent_ix: u32,
path_ix: u32,
bbox: [f32; 4],
}
const BIG_BBOX: [f32; 4] = [-1e9, -1e9, 1e9, 1e9];
// Note: this implementation doesn't rigorously follow the
// WGSL original. In particular, it just computes the clips
// sequentially rather than using the partition reductions.
fn clip_leaf_main(
config: &ConfigUniform,
clip_inp: &[Clip],
path_bboxes: &[PathBbox],
draw_monoids: &mut [DrawMonoid],
clip_bboxes: &mut [[f32; 4]],
) {
let mut stack: Vec<ClipStackElement> = Vec::new();
for global_ix in 0..config.layout.n_clips {
let clip_el = clip_inp[global_ix as usize];
if clip_el.path_ix >= 0 {
// begin clip
let path_ix = clip_el.path_ix as u32;
let path_bbox = path_bboxes[path_ix as usize];
let p_bbox = [
path_bbox.x0 as f32,
path_bbox.y0 as f32,
path_bbox.x1 as f32,
path_bbox.y1 as f32,
];
let bbox = if let Some(last) = stack.last() {
[
p_bbox[0].max(last.bbox[0]),
p_bbox[1].max(last.bbox[1]),
p_bbox[2].min(last.bbox[2]),
p_bbox[3].min(last.bbox[3]),
]
} else {
p_bbox
};
clip_bboxes[global_ix as usize] = bbox;
let parent_ix = clip_el.ix;
stack.push(ClipStackElement {
parent_ix,
path_ix,
bbox,
});
} else {
// end clip
let tos = stack.pop().unwrap();
let bbox = if let Some(nos) = stack.last() {
nos.bbox
} else {
BIG_BBOX
};
clip_bboxes[global_ix as usize] = bbox;
draw_monoids[clip_el.ix as usize].path_ix = tos.path_ix;
draw_monoids[clip_el.ix as usize].scene_offset =
draw_monoids[tos.parent_ix as usize].scene_offset;
}
}
}
pub fn clip_leaf(_n_wg: u32, resources: &[CpuBinding]) {
let config = resources[0].as_typed();
let clip_inp = resources[1].as_slice();
let path_bboxes = resources[2].as_slice();
let mut draw_monoids = resources[5].as_slice_mut();
let mut clip_bboxes = resources[6].as_slice_mut();
clip_leaf_main(
&config,
&clip_inp,
&path_bboxes,
&mut draw_monoids,
&mut clip_bboxes,
);
}