aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ccpr/GrCCPRTriangleProcessor.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/ccpr/GrCCPRTriangleProcessor.h')
-rw-r--r--src/gpu/ccpr/GrCCPRTriangleProcessor.h109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/gpu/ccpr/GrCCPRTriangleProcessor.h b/src/gpu/ccpr/GrCCPRTriangleProcessor.h
new file mode 100644
index 0000000000..1e52d51a45
--- /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