aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2018-04-15 21:58:19 -0600
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-16 16:00:35 +0000
commit6fdbf6161bcb299f855fd467ac4cdbf38c14a5cb (patch)
treee2c25b43aba155c3ad485b92dca99a2d25a9a4d3 /src/gpu
parent209a5f3bea5ea4ca22060b8e44c6f63397a1b492 (diff)
ccpr: Normalize the cubic inflection function instead of its roots
When solving for KLM, switches back to normalizing the cubic's inflection function rather than both individual roots. Also performs some general code clean up for SkClassifyCubic. Bug: skia: Change-Id: Id513e7e02c50a8709f3eccf92fad9e5134d73d83 Reviewed-on: https://skia-review.googlesource.com/121201 Reviewed-by: Cary Clark <caryclark@skia.org> Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/ccpr/GrCCCubicShader.cpp44
1 files changed, 18 insertions, 26 deletions
diff --git a/src/gpu/ccpr/GrCCCubicShader.cpp b/src/gpu/ccpr/GrCCCubicShader.cpp
index f8a8352383..9a57c1cd44 100644
--- a/src/gpu/ccpr/GrCCCubicShader.cpp
+++ b/src/gpu/ccpr/GrCCCubicShader.cpp
@@ -15,28 +15,6 @@ using Shader = GrCCCoverageProcessor::Shader;
void GrCCCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* wind, const char** /*outHull4*/) const {
- // Define a function that normalizes the homogeneous coordinates T=t/s in order to avoid
- // exponent overflow.
- SkString normalizeHomogCoordFn;
- GrShaderVar coord("coord", kFloat2_GrSLType);
- s->emitFunction(kFloat2_GrSLType, "normalize_homogeneous_coord", 1, &coord,
- s->getProgramBuilder()->shaderCaps()->fpManipulationSupport()
- // Exponent manipulation version: Scale the exponents so the larger
- // component has a magnitude in 1..2.
- // (Neither component should be infinity because ccpr crops big paths.)
- ? "int exp;"
- "frexp(max(abs(coord.t), abs(coord.s)), exp);"
- "return coord * ldexp(1, 1 - exp);"
-
- // Division version: Divide by the component with the larger magnitude.
- // (Both should not be 0 because ccpr catches degenerate cubics.)
- : "bool swap = abs(coord.t) > abs(coord.s);"
- "coord = swap ? coord.ts : coord;"
- "coord = float2(1, coord.t/coord.s);"
- "return swap ? coord.ts : coord;",
-
- &normalizeHomogCoordFn);
-
// Find the cubic's power basis coefficients.
s->codeAppendf("float2x4 C = float4x4(-1, 3, -3, 1, "
" 3, -6, 3, 0, "
@@ -48,6 +26,21 @@ void GrCCCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
s->codeAppend ("float D2 = -determinant(float2x2(C[0].xz, C[1].xz));");
s->codeAppend ("float D1 = +determinant(float2x2(C));");
+ // Shift the exponents in D so the largest magnitude falls somewhere in 1..2. This protects us
+ // from overflow while solving for roots and KLM functionals.
+ s->codeAppend ("float Dmax = max(max(abs(D1), abs(D2)), abs(D3));");
+ s->codeAppend ("float norm;");
+ if (s->getProgramBuilder()->shaderCaps()->fpManipulationSupport()) {
+ s->codeAppend ("int exp;");
+ s->codeAppend ("frexp(Dmax, exp);");
+ s->codeAppend ("norm = ldexp(1, 1 - exp);");
+ } else {
+ s->codeAppend ("norm = 1/Dmax;"); // Dmax will not be 0 because we cull line cubics on CPU.
+ }
+ s->codeAppend ("D3 *= norm;");
+ s->codeAppend ("D2 *= norm;");
+ s->codeAppend ("D1 *= norm;");
+
// Calculate the KLM matrix.
s->declareGlobal(fKLMMatrix);
s->codeAppend ("float discr = 3*D2*D2 - 4*D1*D3;");
@@ -56,10 +49,9 @@ void GrCCCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
s->codeAppend ("q = x*D2 + (D2 >= 0 ? q : -q);");
s->codeAppend ("float2 l, m;");
- s->codeAppendf("l.ts = %s(float2(q, 2*x * D1));", normalizeHomogCoordFn.c_str());
- s->codeAppendf("m.ts = %s(float2(2, q) * (discr >= 0 ? float2(D3, 1) "
- ": float2(D2*D2 - D3*D1, D1)));",
- normalizeHomogCoordFn.c_str());
+ s->codeAppend ("l.ts = float2(q, 2*x * D1);");
+ s->codeAppend ("m.ts = float2(2, q) * (discr >= 0 ? float2(D3, 1) "
+ ": float2(D2*D2 - D3*D1, D1));");
s->codeAppend ("float4 K;");
s->codeAppend ("float4 lm = l.sstt * m.stst;");