diff options
Diffstat (limited to 'src/gpu/ccpr/GrCCPRTriangleProcessor.h')
-rw-r--r-- | src/gpu/ccpr/GrCCPRTriangleProcessor.h | 109 |
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 |