Coverage counting path renderer

Initial implementation of a GPU path renderer that draws antialiased
paths by counting coverage in an offscreen buffer.

Initially disabled until it has had time to soak.

Bug: skia:
Change-Id: I003d8cfdf8dc62641581b5ea2dc4f0aa00108df6
Reviewed-on: https://skia-review.googlesource.com/21541
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/ccpr/GrCCPRTriangleProcessor.h b/src/gpu/ccpr/GrCCPRTriangleProcessor.h
new file mode 100644
index 0000000..1e52d51
--- /dev/null
+++ b/src/gpu/ccpr/GrCCPRTriangleProcessor.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrCCPRTriangleProcessor_DEFINED
+#define GrCCPRTriangleProcessor_DEFINED
+
+#include "ccpr/GrCCPRCoverageProcessor.h"
+
+/**
+ * This class renders the coverage of triangles.
+ *
+ * Triangles are rendered in three passes:
+ *
+ * Pass 1: Draw the triangle's conservative raster hull with a coverage of 1. (Conservative raster
+ *         is drawn by considering 3 pixel size boxes, one centered at each vertex, and drawing the
+ *         convex hull of those boxes.)
+ *
+ * Pass 2: Smooth the edges that were over-rendered during Pass 1. Draw the conservative raster of
+ *         each edge (i.e. convex hull of two pixel-size boxes at the endpoints), interpolating from
+ *         coverage=-1 on the outside edge to coverage=0 on the inside edge.
+ *
+ * Pass 3: Touch up the corner pixels to have the correct coverage.
+ */
+class GrCCPRTriangleProcessor : public GrCCPRCoverageProcessor::PrimitiveProcessor {
+public:
+    GrCCPRTriangleProcessor(CoverageType initialCoverage) : INHERITED(initialCoverage) {}
+
+    void onEmitVertexShader(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder*,
+                            const TexelBufferHandle& pointsBuffer, const char* atlasOffset,
+                            const char* rtAdjust, GrGPArgs*) const override;
+    void emitWind(GrGLSLGeometryBuilder*, const char* rtAdjust, const char* outputWind) const final;
+
+protected:
+    void defineInputVertices(GrGLSLGeometryBuilder*) const;
+
+private:
+    typedef GrCCPRCoverageProcessor::PrimitiveProcessor INHERITED;
+};
+
+class GrCCPRTriangleHullAndEdgeProcessor : public GrCCPRTriangleProcessor {
+public:
+    enum class GeometryType {
+        kHulls,
+        kEdges,
+        kHullsAndEdges
+    };
+
+    GrCCPRTriangleHullAndEdgeProcessor(GeometryType geometryType)
+            : INHERITED(GeometryType::kHulls == geometryType ?
+                        CoverageType::kOne : CoverageType::kInterpolated)
+            , fGeometryType(geometryType) {}
+
+    void onEmitGeometryShader(GrGLSLGeometryBuilder*, const char* emitVertexFn, const char* wind,
+                              const char* rtAdjust) const override;
+
+private:
+    const GeometryType fGeometryType;
+
+    typedef GrCCPRTriangleProcessor INHERITED;
+};
+
+/**
+ * This pass fixes the corner pixels of a triangle. It erases the (incorrect) coverage that was
+ * written at the corners during the previous hull and edge passes, and then approximates the true
+ * coverage by sampling the triangle with horizontal lines.
+ */
+class GrCCPRTriangleCornerProcessor : public GrCCPRTriangleProcessor {
+public:
+    GrCCPRTriangleCornerProcessor()
+            : INHERITED(CoverageType::kShader)
+            , fEdgeDistance(kVec3f_GrSLType)
+            , fDevCoord(kVec2f_GrSLType)
+            , fNeighbors(kVec4f_GrSLType)
+            , fEdgeDistances(kMat33f_GrSLType)
+            , fCornerIdx(kInt_GrSLType) {}
+
+    void resetVaryings(GrGLSLVaryingHandler* varyingHandler) override {
+        this->INHERITED::resetVaryings(varyingHandler);
+        varyingHandler->addFlatVarying("edge_distance", &fEdgeDistance, kHigh_GrSLPrecision);
+        varyingHandler->addFlatVarying("devcoord", &fDevCoord, kHigh_GrSLPrecision);
+        varyingHandler->addFlatVarying("neighbors", &fNeighbors, kHigh_GrSLPrecision);
+        varyingHandler->addFlatVarying("edge_distances", &fEdgeDistances, kHigh_GrSLPrecision);
+        varyingHandler->addFlatVarying("corner_idx", &fCornerIdx, kLow_GrSLPrecision);
+    }
+
+    void onEmitVertexShader(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder*,
+                            const TexelBufferHandle& pointsBuffer, const char* atlasOffset,
+                            const char* rtAdjust, GrGPArgs*) const override;
+    void onEmitGeometryShader(GrGLSLGeometryBuilder*, const char* emitVertexFn, const char* wind,
+                              const char* rtAdjust) const override;
+    void emitPerVertexGeometryCode(SkString* fnBody, const char* position, const char* coverage,
+                                   const char* wind) const override;
+    void emitShaderCoverage(GrGLSLFragmentBuilder*, const char* outputCoverage) const override;
+
+private:
+    GrGLSLVertToGeo fEdgeDistance;
+    GrGLSLVertToGeo fDevCoord;
+    GrGLSLGeoToFrag fNeighbors;
+    GrGLSLGeoToFrag fEdgeDistances;
+    GrGLSLGeoToFrag fCornerIdx;
+
+    typedef GrCCPRTriangleProcessor INHERITED;
+};
+
+#endif