Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / gpu / ganesh / tessellate / GrPathTessellationShader.h
1 /*
2  * Copyright 2019 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 GrPathTessellationShader_DEFINED
9 #define GrPathTessellationShader_DEFINED
10
11 #include "src/gpu/ganesh/tessellate/GrTessellationShader.h"
12 #include "src/gpu/tessellate/Tessellation.h"
13
14 // This is the base class for shaders in the GPU tessellator that fill paths.
15 class GrPathTessellationShader : public GrTessellationShader {
16 protected:
17     using PatchAttribs = skgpu::tess::PatchAttribs;
18
19 public:
20     // Draws a simple array of triangles.
21     static GrPathTessellationShader* MakeSimpleTriangleShader(SkArenaAlloc*,
22                                                               const SkMatrix& viewMatrix,
23                                                               const SkPMColor4f&);
24
25     // Uses instanced draws to triangulate curves with a "middle-out" topology. Middle-out draws a
26     // triangle with vertices at T=[0, 1/2, 1] and then recurses breadth first:
27     //
28     //   depth=0: T=[0, 1/2, 1]
29     //   depth=1: T=[0, 1/4, 2/4], T=[2/4, 3/4, 1]
30     //   depth=2: T=[0, 1/8, 2/8], T=[2/8, 3/8, 4/8], T=[4/8, 5/8, 6/8], T=[6/8, 7/8, 1]
31     //   ...
32     //
33     // The shader determines how many segments are required to render each individual curve
34     // smoothly, and emits empty triangles at any vertices whose sk_VertexIDs are higher than
35     // necessary. It is the caller's responsibility to draw enough vertices per instance for the
36     // most complex curve in the batch to render smoothly (i.e., NumTrianglesAtResolveLevel() * 3).
37     //
38     // If PatchAttribs::kFanPoint is set, an additional triangle is added, connecting the base of
39     // the curve to the fan point.
40     static GrPathTessellationShader* Make(const GrShaderCaps&,
41                                           SkArenaAlloc*,
42                                           const SkMatrix& viewMatrix,
43                                           const SkPMColor4f&,
44                                           PatchAttribs);
45
46     // Returns the stencil settings to use for a standard Redbook "stencil" pass.
47     static const GrUserStencilSettings* StencilPathSettings(GrFillRule fillRule) {
48         // Increments clockwise triangles and decrements counterclockwise. Used for "winding" fill.
49         constexpr static GrUserStencilSettings kIncrDecrStencil(
50             GrUserStencilSettings::StaticInitSeparate<
51                 0x0000,                                0x0000,
52                 GrUserStencilTest::kAlwaysIfInClip,    GrUserStencilTest::kAlwaysIfInClip,
53                 0xffff,                                0xffff,
54                 GrUserStencilOp::kIncWrap,             GrUserStencilOp::kDecWrap,
55                 GrUserStencilOp::kKeep,                GrUserStencilOp::kKeep,
56                 0xffff,                                0xffff>());
57
58         // Inverts the bottom stencil bit. Used for "even/odd" fill.
59         constexpr static GrUserStencilSettings kInvertStencil(
60             GrUserStencilSettings::StaticInit<
61                 0x0000,
62                 GrUserStencilTest::kAlwaysIfInClip,
63                 0xffff,
64                 GrUserStencilOp::kInvert,
65                 GrUserStencilOp::kKeep,
66                 0x0001>());
67
68         return (fillRule == GrFillRule::kNonzero) ? &kIncrDecrStencil : &kInvertStencil;
69     }
70
71     // Returns the stencil settings to use for a standard Redbook "fill" pass. Allows non-zero
72     // stencil values to pass and write a color, and resets the stencil value back to zero; discards
73     // immediately on stencil values of zero.
74     static const GrUserStencilSettings* TestAndResetStencilSettings(bool isInverseFill = false) {
75         constexpr static GrUserStencilSettings kTestAndResetStencil(
76             GrUserStencilSettings::StaticInit<
77                 0x0000,
78                 // No need to check the clip because the previous stencil pass will have only
79                 // written to samples already inside the clip.
80                 GrUserStencilTest::kNotEqual,
81                 0xffff,
82                 GrUserStencilOp::kZero,
83                 GrUserStencilOp::kKeep,
84                 0xffff>());
85
86         constexpr static GrUserStencilSettings kTestAndResetStencilInverted(
87             GrUserStencilSettings::StaticInit<
88                 0x0000,
89                 // No need to check the clip because the previous stencil pass will have only
90                 // written to samples already inside the clip.
91                 GrUserStencilTest::kEqual,
92                 0xffff,
93                 GrUserStencilOp::kKeep,
94                 GrUserStencilOp::kZero,
95                 0xffff>());
96
97         return isInverseFill ? &kTestAndResetStencilInverted : &kTestAndResetStencil;
98     }
99
100     // Creates a pipeline that does not write to the color buffer.
101     static const GrPipeline* MakeStencilOnlyPipeline(
102             const ProgramArgs&,
103             GrAAType,
104             const GrAppliedHardClip&,
105             GrPipeline::InputFlags = GrPipeline::InputFlags::kNone);
106
107 protected:
108     constexpr static size_t kMiddleOutVertexStride = 2 * sizeof(float);
109
110     GrPathTessellationShader(ClassID classID,
111                              GrPrimitiveType primitiveType,
112                              const SkMatrix& viewMatrix,
113                              const SkPMColor4f& color,
114                              PatchAttribs attribs)
115             : GrTessellationShader(classID, primitiveType, viewMatrix, color)
116             , fAttribs(attribs) {
117     }
118
119     // Default path tessellation shader implementation that manages a uniform matrix and color.
120     class Impl : public ProgramImpl {
121     public:
122         void onEmitCode(EmitArgs&, GrGPArgs*) final;
123         void setData(const GrGLSLProgramDataManager&, const GrShaderCaps&,
124                      const GrGeometryProcessor&) override;
125
126     protected:
127         // float4x3 unpack_rational_cubic(float2 p0, float2 p1, float2 p2, float2 p3) { ...
128         //
129         // Evaluate our point of interest using numerically stable linear interpolations. We add our
130         // own "safe_mix" method to guarantee we get exactly "b" when T=1. The builtin mix()
131         // function seems spec'd to behave this way, but empirical results results have shown it
132         // does not always.
133         static const char* kEvalRationalCubicFn;
134
135         virtual void emitVertexCode(const GrShaderCaps&,
136                                     const GrPathTessellationShader&,
137                                     GrGLSLVertexBuilder*,
138                                     GrGLSLVaryingHandler*,
139                                     GrGPArgs*) = 0;
140
141         GrGLSLUniformHandler::UniformHandle fAffineMatrixUniform;
142         GrGLSLUniformHandler::UniformHandle fTranslateUniform;
143         GrGLSLUniformHandler::UniformHandle fColorUniform;
144         SkString fVaryingColorName;
145     };
146
147     const PatchAttribs fAttribs;
148 };
149
150 #endif