| /* |
| * Copyright 2020 Google LLC. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef GrTessellateStrokeShader_DEFINED |
| #define GrTessellateStrokeShader_DEFINED |
| |
| #include "src/gpu/tessellate/GrPathShader.h" |
| |
| #include "src/gpu/tessellate/GrTessellationPathRenderer.h" |
| |
| class GrGLSLUniformHandler; |
| |
| // Tessellates a batch of stroke patches directly to the canvas. A patch is either a "cubic" |
| // (single stroked bezier curve with butt caps) or a "join". A patch is defined by 5 points as |
| // follows: |
| // |
| // P0..P3 : Represent the cubic control points. |
| // (P4.x == 0) : The patch is a cubic and the shader decides how many linear segments to produce. |
| // (P4.x < 0) : The patch is still a cubic, but will be linearized into exactly |P4.x| segments. |
| // (P4.x == 1) : The patch is an outer bevel join. |
| // (P4.x == 2) : The patch is an outer miter join. |
| // (P4.x == 3) : The patch is an outer round join. |
| // (P4.x == 4) : The patch is an inner and outer round join. |
| // P4.y : Represents the stroke radius. |
| // |
| // If a patch is a join, P0 must equal P3, P1 must equal the control point coming into the junction, |
| // and P2 must equal the control point going out. It's imperative that a junction's control points |
| // match the control points of their neighbor cubics exactly, or the rasterization might not be |
| // water tight. (Also note that if P1==P0 or P2==P3, the junction needs to be given its neighbor's |
| // opposite cubic control point.) |
| // |
| // To use this shader, construct a GrProgramInfo with a primitiveType of "kPatches" and a |
| // tessellationPatchVertexCount of 5. |
| class GrTessellateStrokeShader : public GrPathShader { |
| public: |
| GrTessellateStrokeShader(const SkMatrix& viewMatrix, float miterLimit, SkPMColor4f color) |
| : GrPathShader(kTessellate_GrTessellateStrokeShader_ClassID, viewMatrix, |
| GrPrimitiveType::kPatches, 5) |
| , fMiterLimit(miterLimit) |
| , fColor(color) { |
| constexpr static Attribute kInputPointAttrib{"inputPoint", kFloat2_GrVertexAttribType, |
| kFloat2_GrSLType}; |
| this->setVertexAttributes(&kInputPointAttrib, 1); |
| } |
| |
| private: |
| const char* name() const override { return "GrTessellateStrokeShader"; } |
| void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override { |
| b->add32(this->viewMatrix().isIdentity()); |
| } |
| GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const final; |
| |
| SkString getTessControlShaderGLSL(const GrGLSLPrimitiveProcessor*, |
| const char* versionAndExtensionDecls, |
| const GrGLSLUniformHandler&, |
| const GrShaderCaps&) const override; |
| SkString getTessEvaluationShaderGLSL(const GrGLSLPrimitiveProcessor*, |
| const char* versionAndExtensionDecls, |
| const GrGLSLUniformHandler&, |
| const GrShaderCaps&) const override; |
| |
| const float fMiterLimit; |
| const SkPMColor4f fColor; |
| |
| class Impl; |
| }; |
| |
| #endif |