ccpr: Cull extremely thin triangles

When triangles get too thin it's possible for FP round-off error to
actually give us the wrong winding direction, causing rendering
artifacts. This change also allows us to unblacklist ANGLE.

Bug: skia:7805
Bug: skia:7820
Change-Id: Ibaa0f033eba625d720e3a594c4515d8264cc413d
Reviewed-on: https://skia-review.googlesource.com/123262
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.cpp b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
index d38db27..75d0667 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
@@ -44,6 +44,36 @@
     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,