1/*
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 GrCCPRCoverageProcessor_DEFINED
9#define GrCCPRCoverageProcessor_DEFINED
10
11#include "GrGeometryProcessor.h"
12#include "glsl/GrGLSLGeometryProcessor.h"
13#include "glsl/GrGLSLVarying.h"
14
15class GrGLSLFragmentBuilder;
16
17/**
18 * This is the geometry processor for the simple convex primitive shapes (triangles and closed curve
19 * segments) from which ccpr paths are composed. The output is a single-channel alpha value,
20 * positive for clockwise primitives and negative for counter-clockwise, that indicates coverage.
21 *
22 * The caller is responsible to render all modes for all applicable primitives into a cleared,
23 * floating point, alpha-only render target using SkBlendMode::kPlus. Once all of a path's
24 * primitives have been drawn, the render target contains a composite coverage count that can then
25 * be used to draw the path (see GrCCPRPathProcessor).
26 *
27 * Caller provides the primitives' (x,y) points in an fp32x2 (RG) texel buffer, and an instance
28 * buffer with a single int32x4 attrib for each primitive (defined below). There are no vertex
29 * attribs.
30 *
31 * Draw calls are instanced, with one vertex per bezier point (3 for triangles). They use the
32 * corresponding GrPrimitiveType as defined below.
33 */
34class GrCCPRCoverageProcessor : public GrGeometryProcessor {
35public:
36    // Use top-left to avoid a uniform access in the fragment shader.
37    static constexpr GrSurfaceOrigin kAtlasOrigin = kTopLeft_GrSurfaceOrigin;
38
39    static constexpr GrPrimitiveType kTrianglesGrPrimitiveType = GrPrimitiveType::kTriangles;
40    static constexpr GrPrimitiveType kQuadraticsGrPrimitiveType = GrPrimitiveType::kTriangles;
41    static constexpr GrPrimitiveType kCubicsGrPrimitiveType = GrPrimitiveType::kLinesAdjacency;
42
43    struct PrimitiveInstance {
44        union {
45            struct {
46                int32_t fPt0Idx;
47                int32_t fPt1Idx;
48                int32_t fPt2Idx;
49            } fTriangleData;
50
51            struct {
52                int32_t fControlPtIdx;
53                int32_t fEndPtsIdx; // The endpoints (P0 and P2) are adjacent in the texel buffer.
54            } fQuadraticData;
55
56            struct {
57                int32_t fControlPtsKLMRootsIdx; // The control points (P1 and P2) are adjacent in
58                                                // the texel buffer, followed immediately by the
59                                                // homogenous KLM roots ({tl,sl}, {tm,sm}).
60                int32_t fEndPtsIdx; // The endpoints (P0 and P3) are adjacent in the texel buffer.
61            } fCubicData;
62        };
63
64        int32_t fPackedAtlasOffset; // (offsetY << 16) | (offsetX & 0xffff)
65    };
66
67    GR_STATIC_ASSERT(4 * 4 == sizeof(PrimitiveInstance));
68
69    enum class Mode {
70        // Triangles.
71        kTriangleHulls,
72        kTriangleEdges,
73        kCombinedTriangleHullsAndEdges,
74        kTriangleCorners,
75
76        // Quadratics.
77        kQuadraticHulls,
78        kQuadraticFlatEdges,
79
80        // Cubics.
81        kSerpentineInsets,
82        kSerpentineBorders,
83        kLoopInsets,
84        kLoopBorders
85    };
86    static const char* GetProcessorName(Mode);
87
88    GrCCPRCoverageProcessor(Mode, GrBuffer* pointsBuffer);
89
90    const char* instanceAttrib() const { return fInstanceAttrib.fName; }
91    const char* name() const override { return GetProcessorName(fMode); }
92    SkString dumpInfo() const override {
93        return SkStringPrintf("%s\n%s", this->name(), this->INHERITED::dumpInfo().c_str());
94    }
95
96    void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
97    GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
98
99#ifdef SK_DEBUG
100    static constexpr float kDebugBloat = 50;
101
102    // Increases the 1/2 pixel AA bloat by a factor of kDebugBloat and outputs color instead of
103    // coverage (coverage=+1 -> green, coverage=0 -> black, coverage=-1 -> red).
104    void enableDebugVisualizations() { fDebugVisualizations = true; }
105    bool debugVisualizations() const { return fDebugVisualizations; }
106
107    static void Validate(GrRenderTarget* atlasTexture);
108#endif
109
110    class PrimitiveProcessor;
111
112private:
113    const Mode         fMode;
114    const Attribute&   fInstanceAttrib;
115    BufferAccess       fPointsBufferAccess;
116    SkDEBUGCODE(bool   fDebugVisualizations = false;)
117
118    typedef GrGeometryProcessor INHERITED;
119};
120
121/**
122 * This class represents the actual SKSL implementation for the various primitives and modes of
123 * GrCCPRCoverageProcessor.
124 */
125class GrCCPRCoverageProcessor::PrimitiveProcessor : public GrGLSLGeometryProcessor {
126protected:
127    // Slightly undershoot a bloat radius of 0.5 so vertices that fall on integer boundaries don't
128    // accidentally bleed into neighbor pixels.
129    static constexpr float kAABloatRadius = 0.491111f;
130
131    // Specifies how the fragment shader should calculate sk_FragColor.a.
132    enum class CoverageType {
133        kOne, // Output +1 all around, modulated by wind.
134        kInterpolated, // Interpolate the coverage values that the geometry shader associates with
135                       // each point, modulated by wind.
136        kShader // Call emitShaderCoverage and let the subclass decide, then a modulate by wind.
137    };
138
139    PrimitiveProcessor(CoverageType coverageType)
140            : fCoverageType(coverageType)
141            , fGeomWind("wind", kFloat_GrSLType, GrShaderVar::kNonArray, kLow_GrSLPrecision)
142            , fFragWind(kFloat_GrSLType)
143            , fFragCoverageTimesWind(kFloat_GrSLType) {}
144
145    // Called before generating shader code. Subclass should add its custom varyings to the handler
146    // and update its corresponding internal member variables.
147    virtual void resetVaryings(GrGLSLVaryingHandler*) {}
148
149    // Here the subclass fetches its vertex from the texel buffer, translates by atlasOffset, and
150    // sets "fPositionVar" in the GrGPArgs.
151    virtual void onEmitVertexShader(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder*,
152                                    const TexelBufferHandle& pointsBuffer, const char* atlasOffset,
153                                    const char* rtAdjust, GrGPArgs*) const = 0;
154
155    // Here the subclass determines the winding direction of its primitive. It must write a value of
156    // either -1, 0, or +1 to "outputWind" (e.g. "sign(area)"). Fractional values are not valid.
157    virtual void emitWind(GrGLSLGeometryBuilder*, const char* rtAdjust,
158                          const char* outputWind) const = 0;
159
160    // This is where the subclass generates the actual geometry to be rasterized by hardware:
161    //
162    //   emitVertexFn(point1, coverage);
163    //   emitVertexFn(point2, coverage);
164    //   ...
165    //   EndPrimitive();
166    //
167    // Generally a subclass will want to use emitHullGeometry and/or emitEdgeGeometry rather than
168    // calling emitVertexFn directly.
169    //
170    // Subclass must also call GrGLSLGeometryBuilder::configure.
171    virtual void onEmitGeometryShader(GrGLSLGeometryBuilder*, const char* emitVertexFn,
172                                      const char* wind, const char* rtAdjust) const = 0;
173
174    // This is a hook to inject code in the geometry shader's "emitVertex" function. Subclass
175    // should use this to write values to its custom varyings.
176    // NOTE: even flat varyings should be rewritten at each vertex.
177    virtual void emitPerVertexGeometryCode(SkString* fnBody, const char* position,
178                                           const char* coverage, const char* wind) const {}
179
180    // Called when the subclass has selected CoverageType::kShader. Primitives should produce
181    // coverage values between +0..1. Base class modulates the sign for wind.
182    // TODO: subclasses might have good spots to stuff the winding information without burning a
183    // whole new varying slot. Consider requiring them to generate the correct coverage sign.
184    virtual void emitShaderCoverage(GrGLSLFragmentBuilder*, const char* outputCoverage) const {
185        SkFAIL("Shader coverage not implemented when using CoverageType::kShader.");
186    }
187
188    // Emits one wedge of the conservative raster hull of a convex polygon. The complete hull has
189    // one wedge for each side of the polygon (i.e. call this N times, generally from different
190    // geometry shader invocations). Coverage is +1 all around.
191    //
192    // Logically, the conservative raster hull is equivalent to the convex hull of pixel-size boxes
193    // centered on the vertices.
194    //
195    // If an optional inset polygon is provided, then this emits a border from the inset to the
196    // hull, rather than the entire hull.
197    //
198    // Geometry shader must be configured to output triangle strips.
199    //
200    // Returns the maximum number of vertices that will be emitted.
201    int emitHullGeometry(GrGLSLGeometryBuilder*, const char* emitVertexFn, const char* polygonPts,
202                         int numSides, const char* wedgeIdx, const char* insetPts = nullptr) const;
203
204    // Emits the conservative raster of an edge (i.e. convex hull of two pixel-size boxes centered
205    // on the endpoints). Coverage is -1 on the outside border of the edge geometry and 0 on the
206    // inside. This effectively converts a jagged conservative raster edge into a smooth antialiased
207    // edge when using CoverageType::kInterpolated.
208    //
209    // If the subclass has already called emitEdgeDistanceEquation, then provide the distance
210    // equation. Otherwise this function will call emitEdgeDistanceEquation implicitly.
211    //
212    // Geometry shader must be configured to output triangle strips.
213    //
214    // Returns the maximum number of vertices that will be emitted.
215    int emitEdgeGeometry(GrGLSLGeometryBuilder*, const char* emitVertexFn, const char* leftPt,
216                         const char* rightPt, const char* distanceEquation = nullptr) const;
217
218    // Defines an equation ("dot(vec3(pt, 1), distance_equation)") that is -1 on the outside border
219    // of a conservative raster edge and 0 on the inside (see emitEdgeGeometry).
220    void emitEdgeDistanceEquation(GrGLSLGeometryBuilder*, const char* leftPt, const char* rightPt,
221                                  const char* outputDistanceEquation) const;
222
223    // Defines a global vec2 array that contains MSAA sample locations as offsets from pixel center.
224    // Subclasses can use this for software multisampling.
225    //
226    // Returns the number of samples.
227    int defineSoftSampleLocations(GrGLSLFragmentBuilder*, const char* samplesName) const;
228
229private:
230    void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
231                 FPCoordTransformIter&& transformIter) final {
232        this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
233    }
234
235    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final;
236
237    void emitVertexShader(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder*,
238                          const TexelBufferHandle& pointsBuffer, const char* rtAdjust,
239                          GrGPArgs* gpArgs) const;
240    void emitGeometryShader(const GrCCPRCoverageProcessor&, GrGLSLGeometryBuilder*,
241                            const char* rtAdjust) const;
242    void emitCoverage(const GrCCPRCoverageProcessor&, GrGLSLFragmentBuilder*,
243                      const char* outputColor, const char* outputCoverage) const;
244
245    const CoverageType   fCoverageType;
246    GrShaderVar          fGeomWind;
247    GrGLSLGeoToFrag      fFragWind;
248    GrGLSLGeoToFrag      fFragCoverageTimesWind;
249
250    typedef GrGLSLGeometryProcessor INHERITED;
251};
252
253#endif
254