• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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 skgpu_graphite_KeyHelpers_DEFINED
9 #define skgpu_graphite_KeyHelpers_DEFINED
10 
11 #include "include/core/SkBlendMode.h"
12 #include "include/core/SkM44.h"
13 #include "include/core/SkSamplingOptions.h"
14 #include "include/core/SkShader.h"
15 #include "include/core/SkSpan.h"
16 #include "include/core/SkTileMode.h"
17 #include "include/effects/SkGradientShader.h"
18 #include "include/gpu/graphite/Context.h"
19 #include "include/private/SkColorData.h"
20 #include "src/core/SkColorSpaceXformSteps.h"
21 #include "src/gpu/graphite/TextureProxy.h"
22 #include "src/shaders/SkShaderBase.h"
23 
24 class SkData;
25 class SkRuntimeEffect;
26 
27 namespace skgpu::graphite {
28 
29 class KeyContext;
30 class PaintParamsKeyBuilder;
31 class PipelineDataGatherer;
32 class UniquePaintParamsID;
33 enum class ReadSwizzle;
34 
35 /**
36  * The KeyHelpers can be used to manually construct an SkPaintParamsKey.
37  *
38  * TODO: If we restructure how the keys are made, we can utilize a single block type for the
39  * different blend blocks outlined below. The different Src/Dst pairings could instead be encoded
40  * as parent-child relationships.
41  */
42 
43 struct PassthroughShaderBlock {
44 
45     static void BeginBlock(const KeyContext&,
46                            PaintParamsKeyBuilder*,
47                            PipelineDataGatherer*);
48 
49 };
50 
51 struct PassthroughBlenderBlock {
52 
53     static void BeginBlock(const KeyContext&,
54                            PaintParamsKeyBuilder*,
55                            PipelineDataGatherer*);
56 
57 };
58 
59 struct SolidColorShaderBlock {
60 
61     static void BeginBlock(const KeyContext&,
62                            PaintParamsKeyBuilder*,
63                            PipelineDataGatherer*,
64                            const SkPMColor4f&);
65 
66 };
67 
68 struct GradientShaderBlocks {
69 
70     struct GradientData {
71         // TODO: For the sprint we only support 8 stops in the gradients
72         static constexpr int kMaxStops = 8;
73 
74         // This ctor is used during pre-compilation when we don't have enough information to
75         // extract uniform data. However, we must be able to provide enough data to make all the
76         // relevant decisions about which code snippets to use.
77         GradientData(SkShaderBase::GradientType, int numStops);
78 
79         // This ctor is used when extracting information from PaintParams. It must provide
80         // enough data to generate the uniform data the selected code snippet will require.
81         GradientData(SkShaderBase::GradientType,
82                      SkPoint point0, SkPoint point1,
83                      float radius0, float radius1,
84                      float bias, float scale,
85                      SkTileMode,
86                      int numStops,
87                      const SkPMColor4f* colors,
88                      float* offsets,
89                      const SkGradientShader::Interpolation&);
90 
91         bool operator==(const GradientData& rhs) const {
92             return fType == rhs.fType &&
93                    fPoints[0] == rhs.fPoints[0] &&
94                    fPoints[1] == rhs.fPoints[1] &&
95                    fRadii[0] == rhs.fRadii[0] &&
96                    fRadii[1] == rhs.fRadii[1] &&
97                    fBias == rhs.fBias &&
98                    fScale == rhs.fScale &&
99                    fTM == rhs.fTM &&
100                    fNumStops == rhs.fNumStops &&
101                    !memcmp(fColors, rhs.fColors, sizeof(fColors)) &&
102                    !memcmp(fOffsets, rhs.fOffsets, sizeof(fOffsets));
103         }
104         bool operator!=(const GradientData& rhs) const { return !(*this == rhs); }
105 
106         // Layout options.
107         SkShaderBase::GradientType fType;
108         SkPoint                    fPoints[2];
109         float                      fRadii[2];
110 
111         // Layout options for sweep gradient.
112         float                  fBias;
113         float                  fScale;
114 
115         SkTileMode             fTM;
116         int                    fNumStops;
117         SkPMColor4f            fColors[kMaxStops];
118         float                  fOffsets[kMaxStops];
119 
120         SkGradientShader::Interpolation fInterpolation;
121     };
122 
123     static void BeginBlock(const KeyContext&,
124                            PaintParamsKeyBuilder*,
125                            PipelineDataGatherer*,
126                            const GradientData&);
127 
128 };
129 
130 struct LocalMatrixShaderBlock {
131 
132     struct LMShaderData {
LMShaderDataLocalMatrixShaderBlock::LMShaderData133         LMShaderData(const SkMatrix& localMatrix)
134                 : fLocalMatrix(localMatrix) {
135         }
136 
137         const SkM44 fLocalMatrix;
138     };
139 
140     static void BeginBlock(const KeyContext&,
141                            PaintParamsKeyBuilder*,
142                            PipelineDataGatherer*,
143                            const LMShaderData*);
144 
145 };
146 
147 struct ImageShaderBlock {
148 
149     struct ImageData {
150         ImageData(const SkSamplingOptions& sampling,
151                   SkTileMode tileModeX,
152                   SkTileMode tileModeY,
153                   SkRect subset,
154                   ReadSwizzle readSwizzle);
155 
156         SkSamplingOptions fSampling;
157         SkTileMode fTileModes[2];
158         SkRect fSubset;
159         ReadSwizzle fReadSwizzle;
160 
161         SkColorSpaceXformSteps fSteps;
162 
163         // TODO: Currently this is only filled in when we're generating the key from an actual
164         // SkImageShader. In the pre-compile case we will need to create a Graphite promise
165         // image which holds the appropriate data.
166         sk_sp<TextureProxy> fTextureProxy;
167     };
168 
169     // The gatherer and imageData should be null or non-null together
170     static void BeginBlock(const KeyContext&,
171                            PaintParamsKeyBuilder*,
172                            PipelineDataGatherer*,
173                            const ImageData*);
174 
175 };
176 
177 struct PorterDuffBlendShaderBlock {
178     struct PorterDuffBlendShaderData {
179         SkSpan<const float> fPorterDuffConstants;
180     };
181 
182     static void BeginBlock(const KeyContext&,
183                            PaintParamsKeyBuilder*,
184                            PipelineDataGatherer*,
185                            const PorterDuffBlendShaderData&);
186 };
187 
188 struct BlendShaderBlock {
189     /**
190      * Blend shader blocks are used to blend the output of two shaders.
191      */
192     struct BlendShaderData {
193         SkBlendMode fBM;
194     };
195 
196     static void BeginBlock(const KeyContext&,
197                            PaintParamsKeyBuilder*,
198                            PipelineDataGatherer*,
199                            const BlendShaderData&);
200 };
201 
202 struct ColorFilterShaderBlock {
203     static void BeginBlock(const KeyContext&,
204                            PaintParamsKeyBuilder*,
205                            PipelineDataGatherer*);
206 };
207 
208 struct MatrixColorFilterBlock {
209     struct MatrixColorFilterData {
MatrixColorFilterDataMatrixColorFilterBlock::MatrixColorFilterData210         MatrixColorFilterData(const float matrix[20],
211                               bool inHSLA)
212                 : fMatrix(matrix[ 0], matrix[ 1], matrix[ 2], matrix[ 3],
213                           matrix[ 5], matrix[ 6], matrix[ 7], matrix[ 8],
214                           matrix[10], matrix[11], matrix[12], matrix[13],
215                           matrix[15], matrix[16], matrix[17], matrix[18])
216                 , fTranslate{matrix[4], matrix[9], matrix[14], matrix[19]}
217                 , fInHSLA(inHSLA) {
218         }
219 
220         SkM44 fMatrix;
221         SkV4  fTranslate;
222         bool  fInHSLA;
223     };
224 
225     // The gatherer and matrixCFData should be null or non-null together
226     static void BeginBlock(const KeyContext&,
227                            PaintParamsKeyBuilder*,
228                            PipelineDataGatherer*,
229                            const MatrixColorFilterData*);
230 };
231 
232 struct BlendColorFilterBlock {
233     /**
234      * Blend color filter blocks are used to blend the output of a shader with a color uniform.
235      */
236     struct BlendColorFilterData {
BlendColorFilterDataBlendColorFilterBlock::BlendColorFilterData237         BlendColorFilterData(SkBlendMode blendMode, const SkPMColor4f& srcColor)
238                 : fBlendMode(blendMode)
239                 , fSrcColor(srcColor) {
240         }
241 
242         SkBlendMode fBlendMode;
243         SkPMColor4f fSrcColor;
244     };
245 
246     static void BeginBlock(const KeyContext&,
247                            PaintParamsKeyBuilder*,
248                            PipelineDataGatherer*,
249                            const BlendColorFilterData*);
250 };
251 
252 struct ComposeColorFilterBlock {
253     static void BeginBlock(const KeyContext&,
254                            PaintParamsKeyBuilder*,
255                            PipelineDataGatherer*);
256 };
257 
258 struct TableColorFilterBlock {
259     struct TableColorFilterData {
260         TableColorFilterData();
261 
262         sk_sp<TextureProxy> fTextureProxy;
263     };
264 
265     static void BeginBlock(const KeyContext&,
266                            PaintParamsKeyBuilder*,
267                            PipelineDataGatherer*,
268                            const TableColorFilterData&);
269 };
270 
271 struct GaussianColorFilterBlock {
272     static void BeginBlock(const KeyContext&,
273                            PaintParamsKeyBuilder*,
274                            PipelineDataGatherer*);
275 };
276 
277 struct ColorSpaceTransformBlock {
278     struct ColorSpaceTransformData {
279         ColorSpaceTransformData(const SkColorSpace* src,
280                                 SkAlphaType srcAT,
281                                 const SkColorSpace* dst,
282                                 SkAlphaType dstAT);
283         SkColorSpaceXformSteps fSteps;
284     };
285 
286     static void BeginBlock(const KeyContext&,
287                            PaintParamsKeyBuilder*,
288                            PipelineDataGatherer*,
289                            const ColorSpaceTransformData*);
290 };
291 
292 struct BlendModeBlock {
293     /**
294      * Blend mode blocks are used to blend a color attachment with the output of a shader.
295      */
296     static void BeginBlock(const KeyContext&,
297                            PaintParamsKeyBuilder*,
298                            PipelineDataGatherer*,
299                            SkBlendMode);
300 };
301 
302 struct PrimitiveBlendModeBlock {
303     /**
304      * Primitive blend mode blocks are used to blend a primitive color emitted by certain draw
305      * geometry calls (drawVertices, drawAtlas, etc.) with either the paint color or the output of
306      * another shader. Dst: primitiveColor Src: Paint color/shader output
307      */
308     static void BeginBlock(const KeyContext&,
309                            PaintParamsKeyBuilder*,
310                            PipelineDataGatherer*,
311                            SkBlendMode);
312 };
313 
314 struct RuntimeEffectBlock {
315     struct ShaderData {
316         // This ctor is used during pre-compilation when we don't have enough information to
317         // extract uniform data.
318         ShaderData(sk_sp<const SkRuntimeEffect> effect);
319 
320         // This ctor is used when extracting information from PaintParams.
321         ShaderData(sk_sp<const SkRuntimeEffect> effect,
322                    sk_sp<const SkData> uniforms);
323 
324         bool operator==(const ShaderData& rhs) const;
325         bool operator!=(const ShaderData& rhs) const { return !(*this == rhs); }
326 
327         // Runtime shader data.
328         sk_sp<const SkRuntimeEffect> fEffect;
329         sk_sp<const SkData>          fUniforms;
330     };
331 
332     static void BeginBlock(const KeyContext&,
333                            PaintParamsKeyBuilder*,
334                            PipelineDataGatherer*,
335                            const ShaderData&);
336 };
337 
338 } // namespace skgpu::graphite
339 
340 #endif // skgpu_graphite_KeyHelpers_DEFINED
341