CCPR: Process quadratic flat edges without soft msaa

The artifacts previously thought to require msaa can be handled by
(1) converting near-linear quadratics into lines, and (2) ensuring all
quadratic segments are monotonic with respect to the vector of their
closing edge [P2 -> P0].

No. 1 was already in effect.

No. 2 is implemented by this change.

Now we only fall back on soft msaa for the two corner pixels.

This change also does some generic housekeeping in the quadratic
processor.

Bug: skia:
Change-Id: Ib3309c2ed86d3d8bec5f451125a69326e82eeb1c
Reviewed-on: https://skia-review.googlesource.com/29721
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp b/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp
index 332a64c..05a3242 100644
--- a/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp
@@ -28,8 +28,8 @@
             return "GrCCPRTriangleCornerProcessor";
         case Mode::kQuadraticHulls:
             return "GrCCPRQuadraticHullProcessor";
-        case Mode::kQuadraticFlatEdges:
-            return "GrCCPRQuadraticSharedEdgeProcessor";
+        case Mode::kQuadraticCorners:
+            return "GrCCPRQuadraticCornerProcessor";
         case Mode::kSerpentineInsets:
             return "GrCCPRCubicInsetProcessor (serpentine)";
         case Mode::kSerpentineBorders:
@@ -74,8 +74,8 @@
             return new GrCCPRTriangleCornerProcessor();
         case Mode::kQuadraticHulls:
             return new GrCCPRQuadraticHullProcessor();
-        case Mode::kQuadraticFlatEdges:
-            return new GrCCPRQuadraticSharedEdgeProcessor();
+        case Mode::kQuadraticCorners:
+            return new GrCCPRQuadraticCornerProcessor();
         case Mode::kSerpentineInsets:
             return new GrCCPRCubicInsetProcessor(GrCCPRCubicProcessor::Type::kSerpentine);
         case Mode::kSerpentineBorders:
@@ -300,6 +300,17 @@
     g->codeAppendf("%s = float3(-n, kk[1]) * scale;", outputDistanceEquation);
 }
 
+int PrimitiveProcessor::emitCornerGeometry(GrGLSLGeometryBuilder* g, const char* emitVertexFn,
+                                           const char* pt) const {
+    g->codeAppendf("%s(%s + float2(-bloat.x, -bloat.y), 1);", emitVertexFn, pt);
+    g->codeAppendf("%s(%s + float2(-bloat.x, +bloat.y), 1);", emitVertexFn, pt);
+    g->codeAppendf("%s(%s + float2(+bloat.x, -bloat.y), 1);", emitVertexFn, pt);
+    g->codeAppendf("%s(%s + float2(+bloat.x, +bloat.y), 1);", emitVertexFn, pt);
+    g->codeAppend ("EndPrimitive();");
+
+    return 4;
+}
+
 void PrimitiveProcessor::emitCoverage(const GrCCPRCoverageProcessor& proc, GrGLSLFragmentBuilder* f,
                                       const char* outputColor, const char* outputCoverage) const {
     switch (fCoverageType) {