Migrate Wang's Formula logic into Graphite vert module.

This will allow the SkSL compiler to avoid reprocessing it each time
it is used.

Unfortunately, Ganesh also uses this code and appears to inject it
directly into GLSL programs (not SkSL), so we can't remove
`wangs_formula::to_sksl` entirely without making significant Ganesh
changes. (We could probably move it into ganesh, though.)

Change-Id: I4468b22f5ef4d19f2afeaff2d6b4fda5cbcfed9b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/533399
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2022-04-25 11:21:05 -04:00 committed by SkCQ
parent 74b72a9b4a
commit 24d95c7001
5 changed files with 590 additions and 10 deletions

View File

@ -170,10 +170,6 @@ std::string get_sksl_vs(const GraphicsPipelineDesc& desc) {
sksl += emit_SKSL_uniforms(1, "Step", step->uniforms());
}
// TODO: This is only needed for tessellation path renderers and should be handled using a
// helper function injector that the SkSL built-in code snippets can use.
sksl += wangs_formula::as_sksl().c_str();
// Vertex shader function declaration
sksl += "void main() {\n";
// Vertex shader body

View File

@ -78,8 +78,7 @@ TessellateCurvesRenderStep::~TessellateCurvesRenderStep() {}
const char* TessellateCurvesRenderStep::vertexSkSL() const {
// TODO: Share SkSL with GrPathTessellationShader_MiddleOut
// TODO: This SkSL depends on wangs_formula::as_sksl(), which is currently manually added in
// MtlGraphicsPipeline but could be handled nicer.
// TODO: The bulk of this SkSL should migrate into sksl_graphite_vert.
return R"(
float resolveLevel = resolveLevel_and_idx.x;
float idxInResolveLevel = resolveLevel_and_idx.y;

View File

@ -82,8 +82,7 @@ TessellateWedgesRenderStep::~TessellateWedgesRenderStep() {}
const char* TessellateWedgesRenderStep::vertexSkSL() const {
// TODO: Share SkSL with GrPathTessellationShader_MiddleOut
// TODO: This SkSL depends on wangs_formula::as_sksl(), which is currently manually added in
// MtlGraphicsPipeline but could be handled nicer.
// TODO: The bulk of this SkSL should migrate into sksl_graphite_vert.
return R"(
float resolveLevel = resolveLevel_and_idx.x;
float idxInResolveLevel = resolveLevel_and_idx.y;

View File

@ -1,5 +1,521 @@
static uint8_t SKSL_INCLUDE_sksl_graphite_vert[] = {10,0,0,0,
52,1,0,0,0,0,
static uint8_t SKSL_INCLUDE_sksl_graphite_vert[] = {10,0,74,1,
7,36,68,101,103,114,101,101,
5,102,108,111,97,116,
10,36,80,114,101,99,105,115,105,111,110,
11,36,76,101,110,103,116,104,84,101,114,109,
15,36,76,101,110,103,116,104,84,101,114,109,80,111,119,50,
2,112,48,
6,102,108,111,97,116,50,
2,112,49,
2,112,50,
2,112,51,
6,109,97,116,114,105,120,
8,102,108,111,97,116,50,120,50,
28,119,97,110,103,115,95,102,111,114,109,117,108,97,95,109,97,120,95,102,100,105,102,102,95,112,111,119,50,
11,95,112,114,101,99,105,115,105,111,110,95,
19,119,97,110,103,115,95,102,111,114,109,117,108,97,95,99,117,98,105,99,
24,119,97,110,103,115,95,102,111,114,109,117,108,97,95,99,117,98,105,99,95,108,111,103,50,
1,119,
24,119,97,110,103,115,95,102,111,114,109,117,108,97,95,99,111,110,105,99,95,112,111,119,50,
19,119,97,110,103,115,95,102,111,114,109,117,108,97,95,99,111,110,105,99,
24,119,97,110,103,115,95,102,111,114,109,117,108,97,95,99,111,110,105,99,95,108,111,103,50,
2,100,48,
2,100,49,
3,102,109,97,
3,109,97,120,
3,100,111,116,
1,109,
4,99,101,105,108,
4,115,113,114,116,
4,108,111,103,50,
1,67,
2,100,112,
2,100,119,
10,114,112,95,109,105,110,117,115,95,49,
5,110,117,109,101,114,
5,100,101,110,111,109,
3,109,105,110,
3,97,98,115,
6,108,101,110,103,116,104,
2,110,50,
52,1,42,0,
55,1,0,
38,
16,4,2,0,
51,255,255,10,0,0,
55,2,0,
38,
16,4,16,0,
51,255,255,10,0,0,
55,3,0,
38,
16,4,27,0,
51,255,255,10,0,0,
55,4,0,
38,
16,4,39,0,
51,255,255,10,0,0,
55,5,0,
17,55,0,
51,255,255,58,0,3,
55,6,0,
17,65,0,
51,255,255,58,0,3,
55,7,0,
17,68,0,
51,255,255,58,0,3,
55,8,0,
17,71,0,
51,255,255,58,0,3,
55,9,0,
17,74,0,
51,255,255,81,0,3,
28,10,0,
17,90,0,5,5,0,6,0,7,0,8,0,9,0,
51,255,255,10,0,
55,11,0,
17,119,0,
51,255,255,10,0,3,
55,12,0,
17,55,0,
51,255,255,58,0,3,
55,13,0,
17,65,0,
51,255,255,58,0,3,
55,14,0,
17,68,0,
51,255,255,58,0,3,
55,15,0,
17,71,0,
51,255,255,58,0,3,
55,16,0,
17,74,0,
51,255,255,81,0,3,
28,17,0,
17,131,0,6,11,0,12,0,13,0,14,0,15,0,16,0,
51,255,255,10,0,
55,18,0,
17,119,0,
51,255,255,10,0,3,
55,19,0,
17,55,0,
51,255,255,58,0,3,
55,20,0,
17,65,0,
51,255,255,58,0,3,
55,21,0,
17,68,0,
51,255,255,58,0,3,
55,22,0,
17,71,0,
51,255,255,58,0,3,
55,23,0,
17,74,0,
51,255,255,81,0,3,
28,24,0,
17,151,0,6,18,0,19,0,20,0,21,0,22,0,23,0,
51,255,255,10,0,
55,25,0,
17,119,0,
51,255,255,10,0,3,
55,26,0,
17,55,0,
51,255,255,58,0,3,
55,27,0,
17,65,0,
51,255,255,58,0,3,
55,28,0,
17,68,0,
51,255,255,58,0,3,
55,29,0,
17,176,0,
51,255,255,10,0,3,
28,30,0,
17,178,0,5,25,0,26,0,27,0,28,0,29,0,
51,255,255,10,0,
55,31,0,
17,119,0,
51,255,255,10,0,3,
55,32,0,
17,55,0,
51,255,255,58,0,3,
55,33,0,
17,65,0,
51,255,255,58,0,3,
55,34,0,
17,68,0,
51,255,255,58,0,3,
55,35,0,
17,176,0,
51,255,255,10,0,3,
28,36,0,
17,203,0,5,31,0,32,0,33,0,34,0,35,0,
51,255,255,10,0,
55,37,0,
17,119,0,
51,255,255,10,0,3,
55,38,0,
17,55,0,
51,255,255,58,0,3,
55,39,0,
17,65,0,
51,255,255,58,0,3,
55,40,0,
17,68,0,
51,255,255,58,0,3,
55,41,0,
17,176,0,
51,255,255,10,0,3,
28,42,0,
17,223,0,5,37,0,38,0,39,0,40,0,41,0,
51,255,255,10,0,10,0,
0,0,
2,0,
3,0,
1,0,
35,0,
41,0,
29,0,
16,0,
23,0,
9,0,
20,
31,
56,1,0,
51,255,255,10,0,0,
25,
51,255,255,10,0,0,0,64,64,
31,
56,2,0,
51,255,255,10,0,0,
25,
51,255,255,10,0,0,0,128,63,
31,
56,3,0,
51,255,255,10,0,0,
25,
51,255,255,10,0,0,0,64,63,
31,
56,4,0,
51,255,255,10,0,0,
25,
51,255,255,10,0,0,0,16,63,
29,10,0,
2,
52,1,2,0,
55,43,0,
17,248,0,
51,255,255,58,0,2,
55,44,0,
17,251,0,
51,255,255,58,0,2,2,0,
0,0,
1,0,3,
56,43,0,
51,255,255,58,0,0,
1,
57,9,0,0,2,
1,
27,
51,255,255,58,0,255,255,254,0,3,
13,
51,255,255,58,0,1,
25,
51,255,255,10,0,0,0,0,192,
57,6,0,0,
57,7,0,0,0,
57,5,0,0,
56,44,0,
51,255,255,58,0,0,
1,
57,9,0,0,2,
1,
27,
51,255,255,58,0,255,255,254,0,3,
13,
51,255,255,58,0,1,
25,
51,255,255,10,0,0,0,0,192,
57,7,0,0,
57,8,0,0,0,
57,6,0,0,
44,
27,
51,255,255,10,0,255,255,2,1,2,
27,
51,255,255,10,0,255,255,6,1,2,
57,43,0,0,
57,43,0,0,
27,
51,255,255,10,0,255,255,6,1,2,
57,44,0,0,
57,44,0,0,1,
29,17,0,
2,
52,1,1,0,
55,45,0,
17,10,1,
51,255,255,10,0,2,1,0,
0,0,2,
56,45,0,
51,255,255,10,0,0,
27,
51,255,255,10,0,10,0,5,
57,12,0,0,
57,13,0,0,
57,14,0,0,
57,15,0,0,
57,16,0,0,
44,
27,
51,255,255,10,0,255,255,2,1,2,
27,
51,255,255,10,0,255,255,12,1,1,
27,
51,255,255,10,0,255,255,17,1,1,
1,
1,
57,3,0,0,2,
57,11,0,0,2,
27,
51,255,255,10,0,255,255,17,1,1,
57,45,0,0,
25,
51,255,255,10,0,0,0,128,63,1,
29,24,0,
2,
52,1,1,0,
55,46,0,
17,10,1,
51,255,255,10,0,2,1,0,
0,0,2,
56,46,0,
51,255,255,10,0,0,
27,
51,255,255,10,0,10,0,5,
57,19,0,0,
57,20,0,0,
57,21,0,0,
57,22,0,0,
57,23,0,0,
44,
27,
51,255,255,10,0,255,255,12,1,1,
1,
27,
51,255,255,10,0,255,255,22,1,1,
27,
51,255,255,10,0,255,255,2,1,2,
1,
1,
1,
57,4,0,0,2,
57,18,0,0,2,
57,18,0,0,2,
57,46,0,0,
25,
51,255,255,10,0,0,0,128,63,2,
25,
51,255,255,10,0,0,0,128,62,1,
29,30,0,
2,
52,1,7,0,
55,47,0,
17,27,1,
51,255,255,58,0,2,
55,48,0,
17,10,1,
51,255,255,10,0,2,
55,49,0,
17,29,1,
51,255,255,58,0,2,
55,50,0,
17,32,1,
51,255,255,10,0,2,
55,51,0,
17,35,1,
51,255,255,10,0,2,
55,52,0,
17,46,1,
51,255,255,10,0,2,
55,53,0,
17,52,1,
51,255,255,10,0,2,7,0,
0,0,
6,0,
2,0,
3,0,
1,0,
5,0,
4,0,11,
56,47,0,
51,255,255,58,0,0,
1,
1,
27,
51,255,255,58,0,255,255,58,1,2,
27,
51,255,255,58,0,255,255,58,1,2,
57,26,0,0,
57,27,0,0,
57,28,0,0,0,
27,
51,255,255,58,0,255,255,2,1,2,
27,
51,255,255,58,0,255,255,2,1,2,
57,26,0,0,
57,27,0,0,
57,28,0,0,2,
25,
51,255,255,10,0,0,0,0,63,
22,
1,
57,26,0,2,23,
57,47,0,0,
22,
1,
57,27,0,2,23,
57,47,0,0,
22,
1,
57,28,0,2,23,
57,47,0,0,
56,48,0,
51,255,255,10,0,0,
27,
51,255,255,10,0,255,255,17,1,1,
27,
51,255,255,10,0,255,255,2,1,2,
27,
51,255,255,10,0,255,255,2,1,2,
27,
51,255,255,10,0,255,255,6,1,2,
57,26,0,0,
57,26,0,0,
27,
51,255,255,10,0,255,255,6,1,2,
57,27,0,0,
57,27,0,0,
27,
51,255,255,10,0,255,255,6,1,2,
57,28,0,0,
57,28,0,0,
56,49,0,
51,255,255,58,0,0,
1,
27,
51,255,255,58,0,255,255,254,0,3,
13,
51,255,255,58,0,1,
1,
25,
51,255,255,10,0,0,0,0,192,2,
57,29,0,0,
57,27,0,0,
57,26,0,0,0,
57,28,0,0,
56,50,0,
51,255,255,10,0,0,
27,
51,255,255,10,0,255,255,62,1,1,
27,
51,255,255,10,0,255,255,254,0,3,
25,
51,255,255,10,0,0,0,0,192,
57,29,0,0,
25,
51,255,255,10,0,0,0,0,64,
56,51,0,
51,255,255,10,0,0,
27,
51,255,255,10,0,255,255,2,1,2,
25,
51,255,255,10,0,0,0,0,0,
27,
51,255,255,10,0,255,255,254,0,3,
57,48,0,0,
57,25,0,0,
25,
51,255,255,10,0,0,0,128,191,
56,52,0,
51,255,255,10,0,0,
1,
1,
27,
51,255,255,10,0,255,255,66,1,1,
57,49,0,0,2,
57,25,0,0,0,
1,
57,51,0,0,2,
57,50,0,0,
56,53,0,
51,255,255,10,0,0,
1,
25,
51,255,255,10,0,0,0,128,64,2,
27,
51,255,255,10,0,255,255,58,1,2,
57,29,0,0,
25,
51,255,255,10,0,0,0,128,63,
44,
1,
57,52,0,0,3,
57,53,0,0,1,
29,36,0,
2,
52,1,1,0,
55,54,0,
17,73,1,
51,255,255,10,0,2,1,0,
0,0,2,
56,54,0,
51,255,255,10,0,0,
27,
51,255,255,10,0,30,0,5,
57,31,0,0,
57,32,0,0,
57,33,0,0,
57,34,0,0,
57,35,0,0,
44,
27,
51,255,255,10,0,255,255,2,1,2,
27,
51,255,255,10,0,255,255,12,1,1,
27,
51,255,255,10,0,255,255,17,1,1,
57,54,0,0,
25,
51,255,255,10,0,0,0,128,63,1,
29,42,0,
2,
52,1,1,0,
55,55,0,
17,73,1,
51,255,255,10,0,2,1,0,
0,0,2,
56,55,0,
51,255,255,10,0,0,
27,
51,255,255,10,0,30,0,5,
57,37,0,0,
57,38,0,0,
57,39,0,0,
57,40,0,0,
57,41,0,0,
44,
27,
51,255,255,10,0,255,255,12,1,1,
1,
27,
51,255,255,10,0,255,255,22,1,1,
27,
51,255,255,10,0,255,255,2,1,2,
57,55,0,0,
25,
51,255,255,10,0,0,0,128,63,2,
25,
51,255,255,10,0,0,0,0,63,1,
21,};
static constexpr size_t SKSL_INCLUDE_sksl_graphite_vert_LENGTH = sizeof(SKSL_INCLUDE_sksl_graphite_vert);

View File

@ -1 +1,71 @@
// Graphite-specific vertex shader code
// Wang's formula gives the minimum number of evenly spaced (in the parametric sense) line segments
// that a bezier curve must be chopped into in order to guarantee all lines stay within a distance
// of "1/precision" pixels from the true curve. Its definition for a bezier curve of degree "n" is
// as follows:
//
// maxLength = max([length(p[i+2] - 2p[i+1] + p[i]) for (0 <= i <= n-2)])
// numParametricSegments = sqrt(maxLength * precision * n*(n - 1)/8)
//
// (Goldman, Ron. (2003). 5.6.3 Wang's Formula. "Pyramid Algorithms: A Dynamic Programming Approach
// to Curves and Surfaces for Geometric Modeling". Morgan Kaufmann Publishers.)
const float $Degree = 3;
const float $Precision = 1;
const float $LengthTerm = ($Degree * ($Degree - 1) / 8.0) * $Precision;
const float $LengthTermPow2 = (($Degree * $Degree) * (($Degree - 1) * ($Degree - 1)) / 64.0) *
($Precision * $Precision);
// Returns the length squared of the largest forward difference from Wang's cubic formula.
float wangs_formula_max_fdiff_pow2(float2 p0, float2 p1, float2 p2, float2 p3,
float2x2 matrix) {
float2 d0 = matrix * (fma(float2(-2), p1, p2) + p0);
float2 d1 = matrix * (fma(float2(-2), p2, p3) + p1);
return max(dot(d0,d0), dot(d1,d1));
}
float wangs_formula_cubic(float _precision_, float2 p0, float2 p1, float2 p2, float2 p3,
float2x2 matrix) {
float m = wangs_formula_max_fdiff_pow2(p0, p1, p2, p3, matrix);
return max(ceil(sqrt($LengthTerm * _precision_ * sqrt(m))), 1.0);
}
float wangs_formula_cubic_log2(float _precision_, float2 p0, float2 p1, float2 p2, float2 p3,
float2x2 matrix) {
float m = wangs_formula_max_fdiff_pow2(p0, p1, p2, p3, matrix);
return ceil(log2(max($LengthTermPow2 * _precision_ * _precision_ * m, 1.0)) * .25);
}
float wangs_formula_conic_pow2(float _precision_, float2 p0, float2 p1, float2 p2, float w) {
// Translate the bounding box center to the origin.
float2 C = (min(min(p0, p1), p2) + max(max(p0, p1), p2)) * 0.5;
p0 -= C;
p1 -= C;
p2 -= C;
// Compute max length.
float m = sqrt(max(max(dot(p0,p0), dot(p1,p1)), dot(p2,p2)));
// Compute forward differences.
float2 dp = fma(float2(-2.0 * w), p1, p0) + p2;
float dw = abs(fma(-2.0, w, 2.0));
// Compute numerator and denominator for parametric step size of linearization. Here, the
// epsilon referenced from the cited paper is 1/precision.
float rp_minus_1 = max(0.0, fma(m, _precision_, -1.0));
float numer = length(dp) * _precision_ + rp_minus_1 * dw;
float denom = 4 * min(w, 1.0);
return numer/denom;
}
float wangs_formula_conic(float _precision_, float2 p0, float2 p1, float2 p2, float w) {
float n2 = wangs_formula_conic_pow2(_precision_, p0, p1, p2, w);
return max(ceil(sqrt(n2)), 1.0);
}
float wangs_formula_conic_log2(float _precision_, float2 p0, float2 p1, float2 p2, float w) {
float n2 = wangs_formula_conic_pow2(_precision_, p0, p1, p2, w);
return ceil(log2(max(n2, 1.0)) * .5);
}