Flutter Engine
The Flutter Engine
Classes | Functions
skgpu::wangs_formula Namespace Reference

Classes

class  VectorXform
 

Functions

template<int Degree>
constexpr float length_term (float precision)
 
template<int Degree>
constexpr float length_term_p2 (float precision)
 
AI float root4 (float x)
 
AI int nextlog2 (float x)
 
AI int nextlog4 (float x)
 
AI int nextlog16 (float x)
 
AI float quadratic_p4 (float precision, skvx::float2 p0, skvx::float2 p1, skvx::float2 p2, const VectorXform &vectorXform=VectorXform())
 
AI float quadratic_p4 (float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
 
AI float quadratic (float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
 
AI int quadratic_log2 (float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
 
AI float cubic_p4 (float precision, skvx::float2 p0, skvx::float2 p1, skvx::float2 p2, skvx::float2 p3, const VectorXform &vectorXform=VectorXform())
 
AI float cubic_p4 (float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
 
AI float cubic (float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
 
AI int cubic_log2 (float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
 
AI float worst_case_cubic_p4 (float precision, float devWidth, float devHeight)
 
AI float worst_case_cubic (float precision, float devWidth, float devHeight)
 
AI int worst_case_cubic_log2 (float precision, float devWidth, float devHeight)
 
AI float conic_p2 (float precision, skvx::float2 p0, skvx::float2 p1, skvx::float2 p2, float w, const VectorXform &vectorXform=VectorXform())
 
AI float conic_p2 (float precision, const SkPoint pts[], float w, const VectorXform &vectorXform=VectorXform())
 
AI float conic (float tolerance, const SkPoint pts[], float w, const VectorXform &vectorXform=VectorXform())
 
AI int conic_log2 (float tolerance, const SkPoint pts[], float w, const VectorXform &vectorXform=VectorXform())
 

Function Documentation

◆ conic()

AI float skgpu::wangs_formula::conic ( float  tolerance,
const SkPoint  pts[],
float  w,
const VectorXform vectorXform = VectorXform() 
)

Definition at line 287 of file WangsFormula.h.

290 {
291 return sqrtf(conic_p2(tolerance, pts, w, vectorXform));
292}
AI float conic_p2(float precision, const SkPoint pts[], float w, const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:274
SkScalar w

◆ conic_log2()

AI int skgpu::wangs_formula::conic_log2 ( float  tolerance,
const SkPoint  pts[],
float  w,
const VectorXform vectorXform = VectorXform() 
)

Definition at line 296 of file WangsFormula.h.

299 {
300 // nextlog4(x) == ceil(log2(sqrt(x)))
301 return nextlog4(conic_p2(tolerance, pts, w, vectorXform));
302}
AI int nextlog4(float x)
Definition: WangsFormula.h:89

◆ conic_p2() [1/2]

AI float skgpu::wangs_formula::conic_p2 ( float  precision,
const SkPoint  pts[],
float  w,
const VectorXform vectorXform = VectorXform() 
)

Definition at line 274 of file WangsFormula.h.

277 {
278 return conic_p2(precision,
279 sk_bit_cast<skvx::float2>(pts[0]),
280 sk_bit_cast<skvx::float2>(pts[1]),
281 sk_bit_cast<skvx::float2>(pts[2]),
282 w,
283 vectorXform);
284}

◆ conic_p2() [2/2]

AI float skgpu::wangs_formula::conic_p2 ( float  precision,
skvx::float2  p0,
skvx::float2  p1,
skvx::float2  p2,
float  w,
const VectorXform vectorXform = VectorXform() 
)

Definition at line 238 of file WangsFormula.h.

241 {
242 p0 = vectorXform(p0);
243 p1 = vectorXform(p1);
244 p2 = vectorXform(p2);
245
246 // Compute center of bounding box in projected space
247 const skvx::float2 C = 0.5f * (min(min(p0, p1), p2) + max(max(p0, p1), p2));
248
249 // Translate by -C. This improves translation-invariance of the formula,
250 // see Sec. 3.3 of cited paper
251 p0 -= C;
252 p1 -= C;
253 p2 -= C;
254
255 // Compute max length
256 const float max_len = sqrtf(std::max(dot(p0, p0), std::max(dot(p1, p1), dot(p2, p2))));
257
258
259 // Compute forward differences
260 const skvx::float2 dp = -2*w*p1 + p0 + p2;
261 const float dw = fabsf(-2 * w + 2);
262
263 // Compute numerator and denominator for parametric step size of linearization. Here, the
264 // epsilon referenced from the cited paper is 1/precision.
265 const float rp_minus_1 = std::max(0.f, max_len * precision - 1);
266 const float numer = sqrtf(dot(dp, dp)) * precision + rp_minus_1 * dw;
267 const float denom = 4 * std::min(w, 1.f);
268
269 // Number of segments = sqrt(numer / denom).
270 // This assumes parametric interval of curve being linearized is [t0,t1] = [0, 1].
271 // If not, the number of segments is (tmax - tmin) / sqrt(denom / numer).
272 return numer / denom;
273}
#define C(TEST_CATEGORY)
Definition: colrv1.cpp:248
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
SINT T dot(const Vec< N, T > &a, const Vec< N, T > &b)
Definition: SkVx.h:964
Definition: SkVx.h:83

◆ cubic()

AI float skgpu::wangs_formula::cubic ( float  precision,
const SkPoint  pts[],
const VectorXform vectorXform = VectorXform() 
)

Definition at line 195 of file WangsFormula.h.

197 {
198 return root4(cubic_p4(precision, pts, vectorXform));
199}
AI float cubic_p4(float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:183
AI float root4(float x)
Definition: WangsFormula.h:46

◆ cubic_log2()

AI int skgpu::wangs_formula::cubic_log2 ( float  precision,
const SkPoint  pts[],
const VectorXform vectorXform = VectorXform() 
)

Definition at line 203 of file WangsFormula.h.

205 {
206 // nextlog16(x) == ceil(log2(sqrt(sqrt(x))))
207 return nextlog16(cubic_p4(precision, pts, vectorXform));
208}
AI int nextlog16(float x)
Definition: WangsFormula.h:97

◆ cubic_p4() [1/2]

AI float skgpu::wangs_formula::cubic_p4 ( float  precision,
const SkPoint  pts[],
const VectorXform vectorXform = VectorXform() 
)

Definition at line 183 of file WangsFormula.h.

185 {
186 return cubic_p4(precision,
187 sk_bit_cast<skvx::float2>(pts[0]),
188 sk_bit_cast<skvx::float2>(pts[1]),
189 sk_bit_cast<skvx::float2>(pts[2]),
190 sk_bit_cast<skvx::float2>(pts[3]),
191 vectorXform);
192}

◆ cubic_p4() [2/2]

AI float skgpu::wangs_formula::cubic_p4 ( float  precision,
skvx::float2  p0,
skvx::float2  p1,
skvx::float2  p2,
skvx::float2  p3,
const VectorXform vectorXform = VectorXform() 
)

Definition at line 172 of file WangsFormula.h.

174 {
175 skvx::float4 p01{p0, p1};
176 skvx::float4 p12{p1, p2};
177 skvx::float4 p23{p2, p3};
178 skvx::float4 v = -2*p12 + p01 + p23;
179 v = vectorXform(v);
180 skvx::float4 vv = v*v;
181 return std::max(vv[0] + vv[1], vv[2] + vv[3]) * length_term_p2<3>(precision);
182}

◆ length_term()

template<int Degree>
constexpr float skgpu::wangs_formula::length_term ( float  precision)
constexpr

Definition at line 39 of file WangsFormula.h.

39 {
40 return (Degree * (Degree - 1) / 8.f) * precision;
41}

◆ length_term_p2()

template<int Degree>
constexpr float skgpu::wangs_formula::length_term_p2 ( float  precision)
constexpr

Definition at line 42 of file WangsFormula.h.

42 {
43 return ((Degree * Degree) * ((Degree - 1) * (Degree - 1)) / 64.f) * (precision * precision);
44}

◆ nextlog16()

AI int skgpu::wangs_formula::nextlog16 ( float  x)

Definition at line 97 of file WangsFormula.h.

97 {
98 return (nextlog2(x) + 3) >> 2;
99}
double x
AI int nextlog2(float x)
Definition: WangsFormula.h:60

◆ nextlog2()

AI int skgpu::wangs_formula::nextlog2 ( float  x)

Definition at line 60 of file WangsFormula.h.

60 {
61 if (x <= 1) {
62 return 0;
63 }
64
65 uint32_t bits = SkFloat2Bits(x);
66 static constexpr uint32_t kDigitsAfterBinaryPoint = std::numeric_limits<float>::digits - 1;
67
68 // The constant is a significand of all 1s -- 0b0'00000000'111'1111111111'111111111. So, if
69 // the significand of x is all 0s (and therefore an integer power of two) this will not
70 // increment the exponent, but if it is just one ULP above the power of two the carry will
71 // ripple into the exponent incrementing the exponent by 1.
72 bits += (1u << kDigitsAfterBinaryPoint) - 1u;
73
74 // Shift the exponent down, and adjust it by the exponent offset so that 2^0 is really 0 instead
75 // of 127. Remember that 1 was added to the exponent, if x is NaN, then the exponent will
76 // carry a 1 into the sign bit during the addition to bits. Be sure to strip off the sign bit.
77 // In addition, infinity is an exponent of all 1's, and a significand of all 0, so
78 // the exponent is not affected during the addition to bits, and the exponent remains all 1's.
79 const int exp = ((bits >> kDigitsAfterBinaryPoint) & 0b1111'1111) - 127;
80
81 // Return 0 for x <= 1.
82 return exp > 0 ? exp : 0;
83}
static uint32_t SkFloat2Bits(float value)
Definition: SkFloatBits.h:41

◆ nextlog4()

AI int skgpu::wangs_formula::nextlog4 ( float  x)

Definition at line 89 of file WangsFormula.h.

89 {
90 return (nextlog2(x) + 1) >> 1;
91}

◆ quadratic()

AI float skgpu::wangs_formula::quadratic ( float  precision,
const SkPoint  pts[],
const VectorXform vectorXform = VectorXform() 
)

Definition at line 156 of file WangsFormula.h.

158 {
159 return root4(quadratic_p4(precision, pts, vectorXform));
160}
AI float quadratic_p4(float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:145

◆ quadratic_log2()

AI int skgpu::wangs_formula::quadratic_log2 ( float  precision,
const SkPoint  pts[],
const VectorXform vectorXform = VectorXform() 
)

Definition at line 164 of file WangsFormula.h.

166 {
167 // nextlog16(x) == ceil(log2(sqrt(sqrt(x))))
168 return nextlog16(quadratic_p4(precision, pts, vectorXform));
169}

◆ quadratic_p4() [1/2]

AI float skgpu::wangs_formula::quadratic_p4 ( float  precision,
const SkPoint  pts[],
const VectorXform vectorXform = VectorXform() 
)

Definition at line 145 of file WangsFormula.h.

147 {
148 return quadratic_p4(precision,
149 sk_bit_cast<skvx::float2>(pts[0]),
150 sk_bit_cast<skvx::float2>(pts[1]),
151 sk_bit_cast<skvx::float2>(pts[2]),
152 vectorXform);
153}

◆ quadratic_p4() [2/2]

AI float skgpu::wangs_formula::quadratic_p4 ( float  precision,
skvx::float2  p0,
skvx::float2  p1,
skvx::float2  p2,
const VectorXform vectorXform = VectorXform() 
)

Definition at line 137 of file WangsFormula.h.

139 {
140 skvx::float2 v = -2*p1 + p0 + p2;
141 v = vectorXform(v);
142 skvx::float2 vv = v*v;
143 return (vv[0] + vv[1]) * length_term_p2<2>(precision);
144}

◆ root4()

AI float skgpu::wangs_formula::root4 ( float  x)

Definition at line 46 of file WangsFormula.h.

46 {
47 return sqrtf(sqrtf(x));
48}

◆ worst_case_cubic()

AI float skgpu::wangs_formula::worst_case_cubic ( float  precision,
float  devWidth,
float  devHeight 
)

Definition at line 221 of file WangsFormula.h.

221 {
222 return root4(worst_case_cubic_p4(precision, devWidth, devHeight));
223}
AI float worst_case_cubic_p4(float precision, float devWidth, float devHeight)
Definition: WangsFormula.h:214

◆ worst_case_cubic_log2()

AI int skgpu::wangs_formula::worst_case_cubic_log2 ( float  precision,
float  devWidth,
float  devHeight 
)

Definition at line 227 of file WangsFormula.h.

227 {
228 // nextlog16(x) == ceil(log2(sqrt(sqrt(x))))
229 return nextlog16(worst_case_cubic_p4(precision, devWidth, devHeight));
230}

◆ worst_case_cubic_p4()

AI float skgpu::wangs_formula::worst_case_cubic_p4 ( float  precision,
float  devWidth,
float  devHeight 
)

Definition at line 214 of file WangsFormula.h.

214 {
215 float kk = length_term_p2<3>(precision);
216 return 4*kk * (devWidth * devWidth + devHeight * devHeight);
217}