diff options
Diffstat (limited to 'src/gpu/ccpr/GrCCCoverageProcessor.cpp')
-rw-r--r-- | src/gpu/ccpr/GrCCCoverageProcessor.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.cpp b/src/gpu/ccpr/GrCCCoverageProcessor.cpp index d38db27a19..75d0667b09 100644 --- a/src/gpu/ccpr/GrCCCoverageProcessor.cpp +++ b/src/gpu/ccpr/GrCCCoverageProcessor.cpp @@ -44,6 +44,36 @@ class GrCCCoverageProcessor::TriangleShader : public GrCCCoverageProcessor::Shad GrGLSLVarying fCoverages; }; +void GrCCCoverageProcessor::Shader::CalcWind(const GrCCCoverageProcessor& proc, + GrGLSLVertexGeoBuilder* s, const char* pts, + const char* outputWind) { + if (3 == proc.numInputPoints()) { + s->codeAppendf("float2 a = %s[0] - %s[1], " + "b = %s[0] - %s[2];", pts, pts, pts, pts); + } else { + // All inputs are convex, so it's sufficient to just average the middle two input points. + SkASSERT(4 == proc.numInputPoints()); + s->codeAppendf("float2 p12 = (%s[1] + %s[2]) * .5;", pts, pts); + s->codeAppendf("float2 a = %s[0] - p12, " + "b = %s[0] - %s[3];", pts, pts, pts); + } + + s->codeAppend ("float area_x2 = determinant(float2x2(a, b));"); + if (proc.isTriangles()) { + // We cull extremely thin triangles by zeroing wind. When a triangle gets too thin it's + // possible for FP round-off error to actually give us the wrong winding direction, causing + // rendering artifacts. The criteria we choose is "height <~ 1/1024". So we drop a triangle + // if the max effect it can have on any single pixel is <~ 1/1024, or 1/4 of a bit in 8888. + s->codeAppend ("float2 bbox_size = max(abs(a), abs(b));"); + s->codeAppend ("float basewidth = max(bbox_size.x + bbox_size.y, 1);"); + s->codeAppendf("%s = (abs(area_x2 * 1024) > basewidth) ? sign(area_x2) : 0;", outputWind); + } else { + // We already converted nearly-flat curves to lines on the CPU, so no need to worry about + // thin curve hulls at this point. + s->codeAppendf("%s = sign(area_x2);", outputWind); + } +} + void GrCCCoverageProcessor::Shader::EmitEdgeDistanceEquation(GrGLSLVertexGeoBuilder* s, const char* leftPt, const char* rightPt, |