Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port recent GPU stroke expansion changes in flatten to CPU version #415

Merged
merged 6 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/encoding/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ pub(crate) fn f32_to_f16(val: f32) -> u16 {
}

/// Convertes a 16-bit precision IEEE-754 binary16 float to a f32.
/// This implementation was adapted from Fabian Giesen's `half_to_float`()
/// This implementation was adapted from Fabian Giesen's `half_to_float()`
/// function which can be found at <https://gist.github.com/rygorous/2156668#file-gistfile1-cpp-L574>
pub fn f16_to_f32(bits: u16) -> f32 {
let bits = bits as u32;
Expand Down
19 changes: 9 additions & 10 deletions shader/flatten.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -297,17 +297,16 @@ fn flatten_arc(
var p0 = transform_apply(transform, begin);
var r = begin - center;

let EPS = 1e-9;
let tol = 0.5;
let MIN_THETA = 0.0001;
let tol = 0.1;
let radius = max(tol, length(p0 - transform_apply(transform, center)));
let x = 1. - tol / radius;
let theta = acos(clamp(2. * x * x - 1., -1., 1.));
let MAX_LINES = 1000u;
let n_lines = select(min(MAX_LINES, u32(ceil(6.2831853 / theta))), MAX_LINES, theta <= EPS);

let th = angle / f32(n_lines);
let c = cos(th);
let s = sin(th);
let theta = max(MIN_THETA, 2. * acos(1. - tol / radius));

// Always output at least one line so that we always draw the chord.
let n_lines = max(1u, u32(ceil(angle / theta)));

let c = cos(theta);
let s = sin(theta);
let rot = mat2x2(c, -s, s, c);

let line_ix = atomicAdd(&bump.lines, n_lines);
Expand Down
27 changes: 15 additions & 12 deletions src/cpu_shader/flatten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ fn write_line(
bbox: &mut IntBbox,
lines: &mut [LineSoup],
) {
assert!(
!p0.is_nan() && !p1.is_nan(),
"wrote line segment with NaN: p0: {:?}, p1: {:?}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can say {p0:?} here, as of Rust 1.58.

p0,
p1
);
bbox.add_pt(p0);
bbox.add_pt(p1);
lines[line_ix] = LineSoup {
Expand Down Expand Up @@ -322,22 +328,19 @@ fn flatten_arc(
lines: &mut [LineSoup],
bbox: &mut IntBbox,
) {
const MIN_THETA: f32 = 0.0001;

let mut p0 = transform.apply(begin);
let mut r = begin - center;
let tol: f32 = 0.5;
let tol: f32 = 0.1;
let radius = tol.max((p0 - transform.apply(center)).length());
let x = 1. - tol / radius;
let theta = (2. * x * x - 1.).clamp(-1., 1.).acos();
const MAX_LINES: u32 = 1000;
let n_lines = if theta <= ROBUST_EPSILON {
MAX_LINES
} else {
MAX_LINES.min((std::f32::consts::TAU / theta).ceil() as u32)
};
let theta = (2. * (1. - tol / radius).acos()).max(MIN_THETA);

// Always output at least one line so that we always draw the chord.
let n_lines = ((angle / theta).ceil() as u32).max(1);

let th = angle / (n_lines as f32);
let c = th.cos();
let s = th.sin();
let c = theta.cos();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can write let (s, c) = theta.sin_cos() but I'm not sure it's a significant improvement, and in any case the function is not available in WGSL.

let s = theta.sin();
let rot = Transform([c, -s, s, c, 0., 0.]);

for _ in 0..(n_lines - 1) {
Expand Down
4 changes: 4 additions & 0 deletions src/cpu_shader/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ impl Vec2 {
pub fn normalize(self) -> Vec2 {
self / self.length()
}

pub fn is_nan(&self) -> bool {
self.x.is_nan() || self.y.is_nan()
}
}

#[derive(Clone)]
Expand Down