1 /* 2 * Copyright 2020 Google LLC. 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 GrFillPathShader_DEFINED 9 #define GrFillPathShader_DEFINED 10 11 #include "src/gpu/tessellate/GrPathShader.h" 12 13 class GrGLSLUniformHandler; 14 class GrGLSLVertexBuilder; 15 16 // This is the base class for shaders that fill a path's pixels in the final render target. 17 class GrFillPathShader : public GrPathShader { 18 public: GrFillPathShader(ClassID classID,const SkMatrix & viewMatrix,SkPMColor4f color,GrPrimitiveType primitiveType)19 GrFillPathShader(ClassID classID, const SkMatrix& viewMatrix, SkPMColor4f color, 20 GrPrimitiveType primitiveType) 21 : GrPathShader(classID, viewMatrix, primitiveType, 0) 22 , fColor(color) { 23 } 24 getGLSLProcessorKey(const GrShaderCaps &,GrProcessorKeyBuilder *)25 void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} 26 GrGLSLGeometryProcessor* createGLSLInstance(const GrShaderCaps&) const final; 27 MakeFillPassPipeline(const GrPathShader::ProgramArgs & args,GrAAType aaType,GrAppliedClip && appliedClip,GrProcessorSet && processors)28 static const GrPipeline* MakeFillPassPipeline(const GrPathShader::ProgramArgs& args, 29 GrAAType aaType, GrAppliedClip&& appliedClip, 30 GrProcessorSet&& processors) { 31 auto pipelineFlags = GrPipeline::InputFlags::kNone; 32 if (aaType != GrAAType::kNone) { 33 pipelineFlags |= GrPipeline::InputFlags::kHWAntialias; 34 } 35 return GrSimpleMeshDrawOpHelper::CreatePipeline( 36 args.fCaps, args.fArena, args.fWriteView.swizzle(), std::move(appliedClip), 37 *args.fDstProxyView, std::move(processors), pipelineFlags); 38 } 39 40 // Allows non-zero stencil values to pass and write a color, and resets the stencil value back 41 // to zero; discards immediately on stencil values of zero. TestAndResetStencilSettings()42 static const GrUserStencilSettings* TestAndResetStencilSettings() { 43 constexpr static GrUserStencilSettings kTestAndResetStencil( 44 GrUserStencilSettings::StaticInit< 45 0x0000, 46 // No need to check the clip because the previous stencil pass will have only 47 // written to samples already inside the clip. 48 GrUserStencilTest::kNotEqual, 49 0xffff, 50 GrUserStencilOp::kZero, 51 GrUserStencilOp::kKeep, 52 0xffff>()); 53 return &kTestAndResetStencil; 54 } 55 56 protected: 57 class Impl; 58 59 virtual void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix, 60 GrGLSLUniformHandler*) const = 0; 61 62 private: 63 const SkPMColor4f fColor; 64 }; 65 66 // Fills a simple array of triangles. 67 class GrFillTriangleShader : public GrFillPathShader { 68 public: GrFillTriangleShader(const SkMatrix & viewMatrix,SkPMColor4f color)69 GrFillTriangleShader(const SkMatrix& viewMatrix, SkPMColor4f color) 70 : GrFillPathShader(kTessellate_GrFillTriangleShader_ClassID, viewMatrix, color, 71 GrPrimitiveType::kTriangles) { 72 static constexpr Attribute kPtAttrib = { 73 "input_point", kFloat2_GrVertexAttribType, kFloat2_GrSLType}; 74 this->setVertexAttributes(&kPtAttrib, 1); 75 } 76 77 private: name()78 const char* name() const override { return "GrFillTriangleShader"; } 79 void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix, 80 GrGLSLUniformHandler*) const override; 81 }; 82 83 // Fills an array of convex hulls surrounding 4-point cubic instances. 84 class GrFillCubicHullShader : public GrFillPathShader { 85 public: GrFillCubicHullShader(const SkMatrix & viewMatrix,SkPMColor4f color)86 GrFillCubicHullShader(const SkMatrix& viewMatrix, SkPMColor4f color) 87 : GrFillPathShader(kTessellate_GrFillCubicHullShader_ClassID, viewMatrix, color, 88 GrPrimitiveType::kTriangleStrip) { 89 static constexpr Attribute kPtsAttribs[] = { 90 {"input_points_0_1", kFloat4_GrVertexAttribType, kFloat4_GrSLType}, 91 {"input_points_2_3", kFloat4_GrVertexAttribType, kFloat4_GrSLType}}; 92 this->setInstanceAttributes(kPtsAttribs, SK_ARRAY_COUNT(kPtsAttribs)); 93 } 94 95 private: name()96 const char* name() const override { return "GrFillCubicHullShader"; } 97 void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix, 98 GrGLSLUniformHandler*) const override; 99 }; 100 101 // Fills a path's bounding box, with subpixel outset to avoid possible T-junctions with extreme 102 // edges of the path. 103 // NOTE: The emitted geometry may not be axis-aligned, depending on the view matrix. 104 class GrFillBoundingBoxShader : public GrFillPathShader { 105 public: GrFillBoundingBoxShader(const SkMatrix & viewMatrix,SkPMColor4f color,const SkRect & pathBounds)106 GrFillBoundingBoxShader(const SkMatrix& viewMatrix, SkPMColor4f color, const SkRect& pathBounds) 107 : GrFillPathShader(kTessellate_GrFillBoundingBoxShader_ClassID, viewMatrix, color, 108 GrPrimitiveType::kTriangleStrip) 109 , fPathBounds(pathBounds) { 110 } 111 pathBounds()112 const SkRect& pathBounds() const { return fPathBounds; } 113 114 private: name()115 const char* name() const override { return "GrFillBoundingBoxShader"; } 116 void emitVertexCode(Impl*, GrGLSLVertexBuilder*, const char* viewMatrix, 117 GrGLSLUniformHandler*) const override; 118 119 const SkRect fPathBounds; 120 }; 121 122 #endif 123