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