SIMD-ify cubic curve flattening

This commit is contained in:
Patrick Walton 2019-01-07 16:10:46 -08:00
parent 12d5e7c678
commit 1ee1eaee4d
1 changed files with 23 additions and 10 deletions

View File

@ -2322,24 +2322,37 @@ impl Iterator for CubicCurveFlattener {
type Item = Point2DF32; type Item = Point2DF32;
fn next(&mut self) -> Option<Point2DF32> { fn next(&mut self) -> Option<Point2DF32> {
let v01 = self.curve.ctrl.from() - self.curve.baseline.from(); let s2inv;
let v02 = self.curve.ctrl.to() - self.curve.baseline.from(); unsafe {
let (baseline, ctrl) = (self.curve.baseline.0, self.curve.ctrl.0);
let from_from = Sse41::shuffle_ps(baseline, baseline, 0b01000100);
let v02_cross_v01: f32 = v02.det(&v01); let v0102 = Sse41::sub_ps(ctrl, from_from);
if v02_cross_v01 == 0.0 {
// v01.x v01.y v02.x v02.y
// * v01.x v01.y v01.y v01.x
// -------------------------
// v01.x^2 v01.y^2 ad bc
// | | | |
// +-------+ +-----+
// + -
// v01 len^2 determinant
let products = Sse41::mul_ps(v0102, Sse41::shuffle_ps(v0102, v0102, 0b00010100));
let det = products[2] - products[3];
if det == 0.0 {
return None; return None;
} }
let s2inv = v01.x().hypot(v01.y()) / v02_cross_v01; s2inv = (products[0] + products[1]).sqrt() / det;
}
let t = 2.0 * (FLATTENING_TOLERANCE * s2inv.abs() * (1.0 / 3.0)).sqrt(); let t = 2.0 * ((FLATTENING_TOLERANCE / 3.0) * s2inv.abs()).sqrt();
if t >= 1.0 - EPSILON || t == 0.0 { if t >= 1.0 - EPSILON || t == 0.0 {
return None; return None;
} }
//println!("split t={} {:#?}", t, self.curve);
self.curve = self.curve.as_cubic_segment().split_after(t); self.curve = self.curve.as_cubic_segment().split_after(t);
//println!("... {:#?}", self.curve);
return Some(self.curve.baseline.from()); return Some(self.curve.baseline.from());
const EPSILON: f32 = 0.005; const EPSILON: f32 = 0.005;