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 15 class 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 */ 34 class GrCCPRCoverageProcessor : public GrGeometryProcessor { 35 public: 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 instanceAttrib()90 const char* instanceAttrib() const { return fInstanceAttrib.fName; } name()91 const char* name() const override { return GetProcessorName(fMode); } dumpInfo()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). enableDebugVisualizations()104 void enableDebugVisualizations() { fDebugVisualizations = true; } debugVisualizations()105 bool debugVisualizations() const { return fDebugVisualizations; } 106 107 static void Validate(GrRenderTarget* atlasTexture); 108 #endif 109 110 class PrimitiveProcessor; 111 112 private: 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 */ 125 class GrCCPRCoverageProcessor::PrimitiveProcessor : public GrGLSLGeometryProcessor { 126 protected: 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 PrimitiveProcessor(CoverageType coverageType)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. resetVaryings(GrGLSLVaryingHandler *)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. emitPerVertexGeometryCode(SkString * fnBody,const char * position,const char * coverage,const char * wind)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. emitShaderCoverage(GrGLSLFragmentBuilder *,const char * outputCoverage)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 229 private: setData(const GrGLSLProgramDataManager & pdman,const GrPrimitiveProcessor &,FPCoordTransformIter && transformIter)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