blob: 1e52d51a45e6b87ed7c695093e9453ec311e41d7 [file] [log] [blame]
Chris Dalton1a325d22017-07-14 15:17:41 -06001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrCCPRTriangleProcessor_DEFINED
9#define GrCCPRTriangleProcessor_DEFINED
10
11#include "ccpr/GrCCPRCoverageProcessor.h"
12
13/**
14 * This class renders the coverage of triangles.
15 *
16 * Triangles are rendered in three passes:
17 *
18 * Pass 1: Draw the triangle's conservative raster hull with a coverage of 1. (Conservative raster
19 * is drawn by considering 3 pixel size boxes, one centered at each vertex, and drawing the
20 * convex hull of those boxes.)
21 *
22 * Pass 2: Smooth the edges that were over-rendered during Pass 1. Draw the conservative raster of
23 * each edge (i.e. convex hull of two pixel-size boxes at the endpoints), interpolating from
24 * coverage=-1 on the outside edge to coverage=0 on the inside edge.
25 *
26 * Pass 3: Touch up the corner pixels to have the correct coverage.
27 */
28class GrCCPRTriangleProcessor : public GrCCPRCoverageProcessor::PrimitiveProcessor {
29public:
30 GrCCPRTriangleProcessor(CoverageType initialCoverage) : INHERITED(initialCoverage) {}
31
32 void onEmitVertexShader(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder*,
33 const TexelBufferHandle& pointsBuffer, const char* atlasOffset,
34 const char* rtAdjust, GrGPArgs*) const override;
35 void emitWind(GrGLSLGeometryBuilder*, const char* rtAdjust, const char* outputWind) const final;
36
37protected:
38 void defineInputVertices(GrGLSLGeometryBuilder*) const;
39
40private:
41 typedef GrCCPRCoverageProcessor::PrimitiveProcessor INHERITED;
42};
43
44class GrCCPRTriangleHullAndEdgeProcessor : public GrCCPRTriangleProcessor {
45public:
46 enum class GeometryType {
47 kHulls,
48 kEdges,
49 kHullsAndEdges
50 };
51
52 GrCCPRTriangleHullAndEdgeProcessor(GeometryType geometryType)
53 : INHERITED(GeometryType::kHulls == geometryType ?
54 CoverageType::kOne : CoverageType::kInterpolated)
55 , fGeometryType(geometryType) {}
56
57 void onEmitGeometryShader(GrGLSLGeometryBuilder*, const char* emitVertexFn, const char* wind,
58 const char* rtAdjust) const override;
59
60private:
61 const GeometryType fGeometryType;
62
63 typedef GrCCPRTriangleProcessor INHERITED;
64};
65
66/**
67 * This pass fixes the corner pixels of a triangle. It erases the (incorrect) coverage that was
68 * written at the corners during the previous hull and edge passes, and then approximates the true
69 * coverage by sampling the triangle with horizontal lines.
70 */
71class GrCCPRTriangleCornerProcessor : public GrCCPRTriangleProcessor {
72public:
73 GrCCPRTriangleCornerProcessor()
74 : INHERITED(CoverageType::kShader)
Brian Salomon1d816b92017-08-17 11:07:59 -040075 , fEdgeDistance(kVec3f_GrSLType)
76 , fDevCoord(kVec2f_GrSLType)
77 , fNeighbors(kVec4f_GrSLType)
78 , fEdgeDistances(kMat33f_GrSLType)
79 , fCornerIdx(kInt_GrSLType) {}
Chris Dalton1a325d22017-07-14 15:17:41 -060080
81 void resetVaryings(GrGLSLVaryingHandler* varyingHandler) override {
82 this->INHERITED::resetVaryings(varyingHandler);
83 varyingHandler->addFlatVarying("edge_distance", &fEdgeDistance, kHigh_GrSLPrecision);
84 varyingHandler->addFlatVarying("devcoord", &fDevCoord, kHigh_GrSLPrecision);
85 varyingHandler->addFlatVarying("neighbors", &fNeighbors, kHigh_GrSLPrecision);
86 varyingHandler->addFlatVarying("edge_distances", &fEdgeDistances, kHigh_GrSLPrecision);
87 varyingHandler->addFlatVarying("corner_idx", &fCornerIdx, kLow_GrSLPrecision);
88 }
89
90 void onEmitVertexShader(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder*,
91 const TexelBufferHandle& pointsBuffer, const char* atlasOffset,
92 const char* rtAdjust, GrGPArgs*) const override;
93 void onEmitGeometryShader(GrGLSLGeometryBuilder*, const char* emitVertexFn, const char* wind,
94 const char* rtAdjust) const override;
95 void emitPerVertexGeometryCode(SkString* fnBody, const char* position, const char* coverage,
96 const char* wind) const override;
97 void emitShaderCoverage(GrGLSLFragmentBuilder*, const char* outputCoverage) const override;
98
99private:
100 GrGLSLVertToGeo fEdgeDistance;
101 GrGLSLVertToGeo fDevCoord;
102 GrGLSLGeoToFrag fNeighbors;
103 GrGLSLGeoToFrag fEdgeDistances;
104 GrGLSLGeoToFrag fCornerIdx;
105
106 typedef GrCCPRTriangleProcessor INHERITED;
107};
108
109#endif