11a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton/*
21a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * Copyright 2017 Google Inc.
31a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton *
41a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * Use of this source code is governed by a BSD-style license that can be
51a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * found in the LICENSE file.
61a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton */
71a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
8383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton#ifndef GrCCCoverageProcessor_DEFINED
9383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton#define GrCCCoverageProcessor_DEFINED
101a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
1127059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton#include "GrCaps.h"
121a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton#include "GrGeometryProcessor.h"
1390e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton#include "GrShaderCaps.h"
14a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton#include "SkNx.h"
151a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton#include "glsl/GrGLSLGeometryProcessor.h"
161a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton#include "glsl/GrGLSLVarying.h"
171a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
18602836138e02935885c77f9dd93dcb51a3ec9a64Chris Daltonclass GrGLSLFPFragmentBuilder;
191fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Daltonclass GrGLSLVertexGeoBuilder;
202326177e3499d96e1e5df68504cc98764d80209aChris Daltonclass GrMesh;
211a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
221a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton/**
231fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton * This is the geometry processor for the simple convex primitive shapes (triangles and closed,
241fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton * convex bezier curves) from which ccpr paths are composed. The output is a single-channel alpha
251fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton * value, positive for clockwise shapes and negative for counter-clockwise, that indicates coverage.
261a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton *
276a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton * The caller is responsible to execute all render passes for all applicable primitives into a
286a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton * cleared, floating point, alpha-only render target using SkBlendMode::kPlus (see RenderPass
296a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton * below). Once all of a path's primitives have been drawn, the render target contains a composite
30383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * coverage count that can then be used to draw the path (see GrCCPathProcessor).
311a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton *
322326177e3499d96e1e5df68504cc98764d80209aChris Dalton * To draw a renderer pass, see appendMesh below.
331a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton */
34383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Daltonclass GrCCCoverageProcessor : public GrGeometryProcessor {
351a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Daltonpublic:
3684403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    // Defines a single primitive shape with 3 input points (i.e. Triangles and Quadratics).
3784403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    // X,Y point values are transposed.
3884403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    struct TriPointInstance {
39a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton        float fX[3];
40a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton        float fY[3];
411a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
42a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton        void set(const SkPoint[3], const Sk2f& trans);
43a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton        void set(const SkPoint&, const SkPoint&, const SkPoint&, const Sk2f& trans);
441a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton    };
451a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
4684403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    // Defines a single primitive shape with 4 input points, or 3 input points plus a W parameter
4784403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    // duplicated in both 4th components (i.e. Cubics or Triangles with a custom winding number).
4884403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    // X,Y point values are transposed.
4984403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    struct QuadPointInstance {
50a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton        float fX[4];
51a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton        float fY[4];
52a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton
53a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton        void set(const SkPoint[4], float dx, float dy);
5484403d7f53d88b2449fd19415538ba1479fe300bChris Dalton        void set(const SkPoint&, const SkPoint&, const SkPoint&, const Sk2f& trans, float w);
55a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    };
561a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
571fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton    // All primitive shapes (triangles and closed, convex bezier curves) require more than one
582326177e3499d96e1e5df68504cc98764d80209aChris Dalton    // render pass. Here we enumerate every render pass needed in order to produce a complete
592326177e3499d96e1e5df68504cc98764d80209aChris Dalton    // coverage count mask. This is an exhaustive list of all ccpr coverage shaders.
601fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton    //
6190e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton    // During a render pass, the "Impl" (GSImpl or VSimpl) generates conservative geometry for
621fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton    // rasterization, and the Shader decides the coverage value at each pixel.
636a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton    enum class RenderPass {
641fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // For a Hull, the Impl generates a "conservative raster hull" around the input points. This
651fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // is the geometry that causes a pixel to be rasterized if it is touched anywhere by the
66f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton        // input polygon. The input coverage values sent to the Shader at each vertex are either
6790e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        // null, or +1 all around if the Impl combines this pass with kTriangleEdges. Logically,
6890e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        // the conservative raster hull is equivalent to the convex hull of pixel size boxes
6990e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        // centered on each input point.
701a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton        kTriangleHulls,
711fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        kQuadraticHulls,
721fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        kCubicHulls,
731fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton
741fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // For Edges, the Impl generates conservative rasters around every input edge (i.e. convex
75f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton        // hulls of two pixel-size boxes centered on both of the edge's endpoints). The input
761fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // coverage values sent to the Shader at each vertex are -1 on the outside border of the
771fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // edge geometry and 0 on the inside. This is the only geometry type that associates
781fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // coverage values with the output vertices. Interpolated, these coverage values convert
791fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // jagged conservative raster edges into a smooth antialiased edge.
8090e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        //
8190e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        // NOTE: The Impl may combine this pass with kTriangleHulls, in which case DoesRenderPass()
8290e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        // will be false for kTriangleEdges and it must not be used.
831a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton        kTriangleEdges,
841a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
851fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // For Corners, the Impl Generates the conservative rasters of corner points (i.e.
861fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // pixel-size boxes). It generates 3 corner boxes for triangles and 2 for curves. The Shader
87f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton        // specifies which corners. Input coverage values sent to the Shader will be null.
881fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        kTriangleCorners,
89b072bb6a5c84fecf652ab5f32a197247219efca2Chris Dalton        kQuadraticCorners,
90be4ffab4e208ec47b4298621b9c9e8456f31717eChris Dalton        kCubicCorners
911a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton    };
922326177e3499d96e1e5df68504cc98764d80209aChris Dalton    static bool RenderPassIsCubic(RenderPass);
932326177e3499d96e1e5df68504cc98764d80209aChris Dalton    static const char* RenderPassName(RenderPass);
941a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
9527059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    constexpr static bool DoesRenderPass(RenderPass renderPass, const GrCaps& caps) {
9627059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton        return RenderPass::kTriangleEdges != renderPass ||
9727059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton               caps.shaderCaps()->geometryShaderSupport();
9890e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton    }
9990e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton
10084403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    enum class WindMethod : bool {
10184403d7f53d88b2449fd19415538ba1479fe300bChris Dalton        kCrossProduct, // Calculate wind = +/-1 by sign of the cross product.
10284403d7f53d88b2449fd19415538ba1479fe300bChris Dalton        kInstanceData // Instance data provides custom, signed wind values of any magnitude.
10384403d7f53d88b2449fd19415538ba1479fe300bChris Dalton                      // (For tightly-wound tessellated triangles.)
10484403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    };
10584403d7f53d88b2449fd19415538ba1479fe300bChris Dalton
10684403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    GrCCCoverageProcessor(GrResourceProvider* rp, RenderPass pass, WindMethod windMethod)
107383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton            : INHERITED(kGrCCCoverageProcessor_ClassID)
10890e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton            , fRenderPass(pass)
10984403d7f53d88b2449fd19415538ba1479fe300bChris Dalton            , fWindMethod(windMethod)
11084403d7f53d88b2449fd19415538ba1479fe300bChris Dalton            , fImpl(rp->caps()->shaderCaps()->geometryShaderSupport() ? Impl::kGeometryShader
11184403d7f53d88b2449fd19415538ba1479fe300bChris Dalton                                                                      : Impl::kVertexShader) {
11284403d7f53d88b2449fd19415538ba1479fe300bChris Dalton        SkASSERT(DoesRenderPass(pass, *rp->caps()));
11390e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        if (Impl::kGeometryShader == fImpl) {
11490e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton            this->initGS();
11590e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        } else {
11684403d7f53d88b2449fd19415538ba1479fe300bChris Dalton            this->initVS(rp);
11790e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        }
118a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    }
119a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton
1202326177e3499d96e1e5df68504cc98764d80209aChris Dalton    // Appends a GrMesh that will draw the provided instances. The instanceBuffer must be an array
12184403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    // of either TriPointInstance or QuadPointInstance, depending on this processor's RendererPass,
12284403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    // with coordinates in the desired shape's final atlas-space position.
1232326177e3499d96e1e5df68504cc98764d80209aChris Dalton    void appendMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
12490e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton                    SkTArray<GrMesh>* out) {
12590e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        if (Impl::kGeometryShader == fImpl) {
12690e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton            this->appendGSMesh(instanceBuffer, instanceCount, baseInstance, out);
12790e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        } else {
12890e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton            this->appendVSMesh(instanceBuffer, instanceCount, baseInstance, out);
12990e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        }
130be4ffab4e208ec47b4298621b9c9e8456f31717eChris Dalton    }
1316a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
1322326177e3499d96e1e5df68504cc98764d80209aChris Dalton    // GrPrimitiveProcessor overrides.
1332326177e3499d96e1e5df68504cc98764d80209aChris Dalton    const char* name() const override { return RenderPassName(fRenderPass); }
1342326177e3499d96e1e5df68504cc98764d80209aChris Dalton    SkString dumpInfo() const override {
1352326177e3499d96e1e5df68504cc98764d80209aChris Dalton        return SkStringPrintf("%s\n%s", this->name(), this->INHERITED::dumpInfo().c_str());
1362326177e3499d96e1e5df68504cc98764d80209aChris Dalton    }
1372326177e3499d96e1e5df68504cc98764d80209aChris Dalton    void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
1382326177e3499d96e1e5df68504cc98764d80209aChris Dalton    GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
1392326177e3499d96e1e5df68504cc98764d80209aChris Dalton
1402326177e3499d96e1e5df68504cc98764d80209aChris Dalton#ifdef SK_DEBUG
1412326177e3499d96e1e5df68504cc98764d80209aChris Dalton    // Increases the 1/2 pixel AA bloat by a factor of debugBloat and outputs color instead of
1422326177e3499d96e1e5df68504cc98764d80209aChris Dalton    // coverage (coverage=+1 -> green, coverage=0 -> black, coverage=-1 -> red).
1432326177e3499d96e1e5df68504cc98764d80209aChris Dalton    void enableDebugVisualizations(float debugBloat) { fDebugBloat = debugBloat; }
1442326177e3499d96e1e5df68504cc98764d80209aChris Dalton    bool debugVisualizationsEnabled() const { return fDebugBloat > 0; }
1452326177e3499d96e1e5df68504cc98764d80209aChris Dalton    float debugBloat() const { SkASSERT(this->debugVisualizationsEnabled()); return fDebugBloat; }
1462326177e3499d96e1e5df68504cc98764d80209aChris Dalton#endif
1472326177e3499d96e1e5df68504cc98764d80209aChris Dalton
1481fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton    // The Shader provides code to calculate each pixel's coverage in a RenderPass. It also
1491fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton    // provides details about shape-specific geometry.
1506a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton    class Shader {
1516a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton    public:
1526a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton        union GeometryVars {
1536a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton            struct {
1546a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton                const char* fAlternatePoints; // floatNx2 (if left null, will use input points).
1556a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton            } fHullVars;
1566a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
1576a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton            struct {
1586a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton                const char* fPoint; // float2
1596a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton            } fCornerVars;
1606a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
1616a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton            GeometryVars() { memset(this, 0, sizeof(*this)); }
1626a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton        };
1636a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
1646a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton        // Called before generating geometry. Subclasses must fill out the applicable fields in
1656a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton        // GeometryVars (if any), and may also use this opportunity to setup internal member
1666a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton        // variables that will be needed during onEmitVaryings (e.g. transformation matrices).
1671fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        //
1681fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // repetitionID is a 0-based index and indicates which edge or corner is being generated.
1691fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // It will be null when generating a hull.
1701fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        virtual void emitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts,
1711fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton                                   const char* repetitionID, const char* wind,
1721fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton                                   GeometryVars*) const {}
1736a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
174f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton        void emitVaryings(GrGLSLVaryingHandler* varyingHandler, GrGLSLVarying::Scope scope,
175f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton                          SkString* code, const char* position, const char* inputCoverage,
176f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton                          const char* wind) {
177f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton            SkASSERT(GrGLSLVarying::Scope::kVertToGeo != scope);
178f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton            this->onEmitVaryings(varyingHandler, scope, code, position, inputCoverage, wind);
179f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton        }
1806a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
181602836138e02935885c77f9dd93dcb51a3ec9a64Chris Dalton        void emitFragmentCode(const GrCCCoverageProcessor& proc, GrGLSLFPFragmentBuilder*,
1826a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton                              const char* skOutputColor, const char* skOutputCoverage) const;
1836a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
1846a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton        // Defines an equation ("dot(float3(pt, 1), distance_equation)") that is -1 on the outside
185cc0ab7e3c1072e131d63d46ac5916aafc177fcfeChris Dalton        // border of a conservative raster edge and 0 on the inside. 'leftPt' and 'rightPt' must be
186cc0ab7e3c1072e131d63d46ac5916aafc177fcfeChris Dalton        // ordered clockwise.
1871fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        static void EmitEdgeDistanceEquation(GrGLSLVertexGeoBuilder*, const char* leftPt,
1886a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton                                             const char* rightPt,
1896a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton                                             const char* outputDistanceEquation);
1906a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
1916a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton        virtual ~Shader() {}
1926a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
1936a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton    protected:
1946a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton        // Here the subclass adds its internal varyings to the handler and produces code to
195f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton        // initialize those varyings from a given position, input coverage value, and wind.
1966a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton        //
197f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton        // NOTE: the coverage input is only relevant for edges (see comments in RenderPass).
1986a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton        // Otherwise it is +1 all around.
199f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton        virtual void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
200f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton                                    const char* position, const char* inputCoverage,
201f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton                                    const char* wind) = 0;
2026a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
203f510e26a070ba3553b4cce3831cc9cd97b58a6bbChris Dalton        // Emits the fragment code that calculates a pixel's signed coverage value.
204602836138e02935885c77f9dd93dcb51a3ec9a64Chris Dalton        virtual void onEmitFragmentCode(GrGLSLFPFragmentBuilder*,
2056a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton                                        const char* outputCoverage) const = 0;
2066a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
20790e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        // Returns the name of a Shader's internal varying at the point where where its value is
20890e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        // assigned. This is intended to work whether called for a vertex or a geometry shader.
20990e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        const char* OutName(const GrGLSLVarying& varying) const {
21090e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton            using Scope = GrGLSLVarying::Scope;
21190e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton            SkASSERT(Scope::kVertToGeo != varying.scope());
21290e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton            return Scope::kGeoToFrag == varying.scope() ? varying.gsOut() : varying.vsOut();
21390e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        }
21490e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton
2151fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // Defines a global float2 array that contains MSAA sample locations as offsets from pixel
2161fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // center. Subclasses can use this for software multisampling.
2171fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        //
2181fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton        // Returns the number of samples.
219602836138e02935885c77f9dd93dcb51a3ec9a64Chris Dalton        static int DefineSoftSampleLocations(GrGLSLFPFragmentBuilder* f, const char* samplesName);
2206a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton    };
2216a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton
2226a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton    class GSImpl;
22390e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton    class VSImpl;
2241a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
2251a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Daltonprivate:
2261a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton    // Slightly undershoot a bloat radius of 0.5 so vertices that fall on integer boundaries don't
2271a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton    // accidentally bleed into neighbor pixels.
2281a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton    static constexpr float kAABloatRadius = 0.491111f;
2291a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
2301fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton    // Number of bezier points for curves, or 3 for triangles.
2311fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton    int numInputPoints() const { return RenderPassIsCubic(fRenderPass) ? 4 : 3; }
2321fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton
23390e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton    enum class Impl : bool {
23490e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        kGeometryShader,
23590e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton        kVertexShader
23690e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton    };
23790e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton
2382326177e3499d96e1e5df68504cc98764d80209aChris Dalton    void initGS();
23984403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    void initVS(GrResourceProvider*);
24090e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton
2412326177e3499d96e1e5df68504cc98764d80209aChris Dalton    void appendGSMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
24290e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton                      SkTArray<GrMesh>* out) const;
24390e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton    void appendVSMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
24490e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton                      SkTArray<GrMesh>* out) const;
24590e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton
2461fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton    GrGLSLPrimitiveProcessor* createGSImpl(std::unique_ptr<Shader>) const;
24790e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton    GrGLSLPrimitiveProcessor* createVSImpl(std::unique_ptr<Shader>) const;
2481a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
249a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    const RenderPass fRenderPass;
25084403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    const WindMethod fWindMethod;
25190e8fb1d98e149643960e5ed27b89cf1fa08e4ccChris Dalton    const Impl fImpl;
252383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton    SkDEBUGCODE(float fDebugBloat = 0);
253d6365e5fb8746d31b564d757297197df5b02a3d0Eric Boren
25427059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    // Used by VSImpl.
25527059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    sk_sp<const GrBuffer> fVertexBuffer;
25627059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    sk_sp<const GrBuffer> fIndexBuffer;
25727059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    int fNumIndicesPerInstance;
25827059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    GrPrimitiveType fPrimitiveType;
25927059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton
2606a3dbeed00fe725099277040e3e2fc7d8ecb9751Chris Dalton    typedef GrGeometryProcessor INHERITED;
2611a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton};
2621a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton
26384403d7f53d88b2449fd19415538ba1479fe300bChris Daltoninline void GrCCCoverageProcessor::TriPointInstance::set(const SkPoint p[3], const Sk2f& trans) {
264a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    this->set(p[0], p[1], p[2], trans);
265a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton}
266a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton
26784403d7f53d88b2449fd19415538ba1479fe300bChris Daltoninline void GrCCCoverageProcessor::TriPointInstance::set(const SkPoint& p0, const SkPoint& p1,
268383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton                                                         const SkPoint& p2, const Sk2f& trans) {
269a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    Sk2f P0 = Sk2f::Load(&p0) + trans;
270a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    Sk2f P1 = Sk2f::Load(&p1) + trans;
271a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    Sk2f P2 = Sk2f::Load(&p2) + trans;
272a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    Sk2f::Store3(this, P0, P1, P2);
273a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton}
274a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton
27584403d7f53d88b2449fd19415538ba1479fe300bChris Daltoninline void GrCCCoverageProcessor::QuadPointInstance::set(const SkPoint p[4], float dx, float dy) {
276a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    Sk4f X,Y;
277a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    Sk4f::Load2(p, &X, &Y);
278a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    (X + dx).store(&fX);
279a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton    (Y + dy).store(&fY);
280a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton}
281a3e9271ec41db6c3b6886e50053f37d345ab1d5cChris Dalton
28284403d7f53d88b2449fd19415538ba1479fe300bChris Daltoninline void GrCCCoverageProcessor::QuadPointInstance::set(const SkPoint& p0, const SkPoint& p1,
28384403d7f53d88b2449fd19415538ba1479fe300bChris Dalton                                                          const SkPoint& p2, const Sk2f& trans,
28484403d7f53d88b2449fd19415538ba1479fe300bChris Dalton                                                          float w) {
28584403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    Sk2f P0 = Sk2f::Load(&p0) + trans;
28684403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    Sk2f P1 = Sk2f::Load(&p1) + trans;
28784403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    Sk2f P2 = Sk2f::Load(&p2) + trans;
28884403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    Sk2f W = Sk2f(w);
28984403d7f53d88b2449fd19415538ba1479fe300bChris Dalton    Sk2f::Store4(this, P0, P1, P2, W);
29084403d7f53d88b2449fd19415538ba1479fe300bChris Dalton}
29184403d7f53d88b2449fd19415538ba1479fe300bChris Dalton
292383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Daltoninline bool GrCCCoverageProcessor::RenderPassIsCubic(RenderPass pass) {
2932326177e3499d96e1e5df68504cc98764d80209aChris Dalton    switch (pass) {
2942326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kTriangleHulls:
2952326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kTriangleEdges:
2962326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kTriangleCorners:
2972326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kQuadraticHulls:
2982326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kQuadraticCorners:
2992326177e3499d96e1e5df68504cc98764d80209aChris Dalton            return false;
3002326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kCubicHulls:
3012326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kCubicCorners:
3022326177e3499d96e1e5df68504cc98764d80209aChris Dalton            return true;
3032326177e3499d96e1e5df68504cc98764d80209aChris Dalton    }
3041fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton    SK_ABORT("Invalid RenderPass");
3052326177e3499d96e1e5df68504cc98764d80209aChris Dalton    return false;
3062326177e3499d96e1e5df68504cc98764d80209aChris Dalton}
3072326177e3499d96e1e5df68504cc98764d80209aChris Dalton
308383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Daltoninline const char* GrCCCoverageProcessor::RenderPassName(RenderPass pass) {
3092326177e3499d96e1e5df68504cc98764d80209aChris Dalton    switch (pass) {
3102326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kTriangleHulls: return "kTriangleHulls";
3112326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kTriangleEdges: return "kTriangleEdges";
3122326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kTriangleCorners: return "kTriangleCorners";
3132326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kQuadraticHulls: return "kQuadraticHulls";
3142326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kQuadraticCorners: return "kQuadraticCorners";
3152326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kCubicHulls: return "kCubicHulls";
3162326177e3499d96e1e5df68504cc98764d80209aChris Dalton        case RenderPass::kCubicCorners: return "kCubicCorners";
3172326177e3499d96e1e5df68504cc98764d80209aChris Dalton    }
3181fbdb61f1389f01ce1cf1b7950e03a84811a9f38Chris Dalton    SK_ABORT("Invalid RenderPass");
3192326177e3499d96e1e5df68504cc98764d80209aChris Dalton    return "";
3202326177e3499d96e1e5df68504cc98764d80209aChris Dalton}
3212326177e3499d96e1e5df68504cc98764d80209aChris Dalton
3221a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton#endif
323