• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 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_precompile_PrecompileShader_DEFINED
9 #define skgpu_graphite_precompile_PrecompileShader_DEFINED
10 
11 #include "include/gpu/graphite/precompile/PrecompileBase.h"
12 
13 #include "include/core/SkBlendMode.h"
14 
15 class SkColorSpace;
16 
17 namespace skgpu::graphite {
18 
19 class PrecompileBlender;
20 class PrecompileColorFilter;
21 class PrecompileShaderPriv;
22 
23 /** \class PrecompileShader
24     This class corresponds to the SkShader class in the main API.
25 */
26 class SK_API PrecompileShader : public PrecompileBase {
27 public:
28     /**
29      *  This is the Precompile correlate to SkShader::makeWithLocalMatrix. The actual matrix
30      *  involved is abstracted away since it doesn't impact the generated shader.
31      *  The PrecompileShaders::LocalMatrix factory can be used to generate a set of shaders
32      *  that would've been generated via multiple makeWithLocalMatrix calls. That is, rather than
33      *  performing:
34      *     sk_sp<PrecompileShader> option1 = source1->makeWithLocalMatrix();
35      *     sk_sp<PrecompileShader> option2 = source2->makeWithLocalMatrix();
36      *  one could call:
37      *     sk_sp<PrecompileShader> combinedOptions = LocalMatrix({ source1, source2 });
38      */
39     sk_sp<PrecompileShader> makeWithLocalMatrix();
40 
41     /**
42      *  This is the Precompile correlate to SkShader::makeWithColorFilter.
43      *  The PrecompileShaders::ColorFilter factory can be used to generate a set of shaders that
44      *  would've been generated via multiple makeWithColorFilter calls. That is, rather than
45      *  performing:
46      *     sk_sp<PrecompileShader> option1 = source->makeWithColorFilter(colorFilter1);
47      *     sk_sp<PrecompileShader> option2 = source->makeWithColorFilter(colorFilter2);
48      *  one could call:
49      *     sk_sp<PrecompileShader> combinedOptions = ColorFilter({ source },
50      *                                                           { colorFilter1, colorFilter2 });
51      *  With an alternative use case one could also use the ColorFilter factory thusly:
52      *     sk_sp<PrecompileShader> combinedOptions = ColorFilter({ source1, source2 },
53      *                                                           { colorFilter });
54      */
55     sk_sp<PrecompileShader> makeWithColorFilter(sk_sp<PrecompileColorFilter>);
56 
57     /**
58      *  This is the Precompile correlate to SkShader::makeWithWorkingColorSpace.
59      *  The PrecompileShaders::WorkingColorSpace factory can be used to generate a set of shaders
60      *  that would've been generated via multiple makeWithWorkingColorSpace calls. That is, rather
61      *  than performing:
62      *     sk_sp<PrecompileShader> option1 = source->makeWithWorkingColorSpace(colorSpace1);
63      *     sk_sp<PrecompileShader> option2 = source->makeWithWorkingColorSpace(colorSpace2);
64      *  one could call:
65      *     sk_sp<PrecompileShader> combinedOptions = WorkingColorSpace({ source },
66      *                                                                 { colorSpace1,
67      *                                                                   colorSpace2 });
68      *  With an alternative use case one could also use the WorkingColorSpace factory thusly:
69      *     sk_sp<PrecompileShader> combinedOptions = WorkingColorSpace({ source1, source2 },
70      *                                                                 { colorSpace });
71      */
72     sk_sp<PrecompileShader> makeWithWorkingColorSpace(sk_sp<SkColorSpace>);
73 
74     // Provides access to functions that aren't part of the public API.
75     PrecompileShaderPriv priv();
76     const PrecompileShaderPriv priv() const;  // NOLINT(readability-const-return-type)
77 
78 protected:
79     friend class PrecompileShaderPriv;
80 
PrecompileShader()81     PrecompileShader() : PrecompileBase(Type::kShader) {}
82     ~PrecompileShader() override;
83 
isConstant(int)84     virtual bool isConstant(int /* desiredCombination */) const { return false; }
85 
isALocalMatrixShader()86     virtual bool isALocalMatrixShader() const { return false; }
87 };
88 
89 //--------------------------------------------------------------------------------------------------
90 // This is the Precompile correlate to the SkShaders namespace in the main API
91 namespace PrecompileShaders {
92     // --- This block of eight matches the SkShaders factories in SkShader.h
93     // Note that some of the details of the main API have been elided since they don't impact
94     // the generated shader (e.g., the color parameter to the Color() factories).
95     SK_API sk_sp<PrecompileShader> Empty();
96     SK_API sk_sp<PrecompileShader> Color();
97     SK_API sk_sp<PrecompileShader> Color(sk_sp<SkColorSpace>);
98     SK_API sk_sp<PrecompileShader> Blend(SkSpan<const SkBlendMode> blendModes,
99                                          SkSpan<const sk_sp<PrecompileShader>> dsts,
100                                          SkSpan<const sk_sp<PrecompileShader>> srcs);
101     SK_API sk_sp<PrecompileShader> Blend(SkSpan<const sk_sp<PrecompileBlender>> blenders,
102                                          SkSpan<const sk_sp<PrecompileShader>> dsts,
103                                          SkSpan<const sk_sp<PrecompileShader>> srcs);
104     SK_API sk_sp<PrecompileShader> CoordClamp(SkSpan<const sk_sp<PrecompileShader>>);
105 
106     // In the main Skia API ImageShaders are usually created via a SkImage::makeShader call.
107     // Since the SkImage used to create the ImageShader is unlikely to be present at precompilation
108     // time this entry point allows the equivalent precompilation program structure to be created.
109     SK_API sk_sp<PrecompileShader> Image();
110     // As with the above Image call, raw ImageShaders are usually created via an
111     // SkImage::makeRawShader call. The RawImage call allows the equivalent precompilation
112     // program structure to be created without needing the SkImage.
113     SK_API sk_sp<PrecompileShader> RawImage();
114 
115     // --- This block of two matches the SkShaders factories in SkPerlinNoiseShader.h
116     // Again, most of the details have been elided.
117     SK_API sk_sp<PrecompileShader> MakeFractalNoise();
118     SK_API sk_sp<PrecompileShader> MakeTurbulence();
119 
120     // --- This block of four matches all the factories in SkGradientShader (SkGradientShader.h)
121     SK_API sk_sp<PrecompileShader> LinearGradient();
122     SK_API sk_sp<PrecompileShader> RadialGradient();
123     SK_API sk_sp<PrecompileShader> TwoPointConicalGradient();
124     SK_API sk_sp<PrecompileShader> SweepGradient();
125 
126     // Normally, SkPicture shaders are only created via SkPicture::makeShader. Since the
127     // SkPicture to be drawn, most likely, won't be available at precompilation time, this
128     // entry point can be used to create a precompilation equivalent.
129     // Note: this will precompile the program that draws the SkPicture. It, obviously, won't
130     // precompile any SkPaints within the SkPicture.
131     SK_API sk_sp<PrecompileShader> Picture();
132 
133     // Normally, LocalMatrixShaders are only created via SkShader::makeWithLocalMatrix.
134     // However, in the combination API, clients may want to create a set of precompile
135     // LocalMatrixShaders (i.e., pass an SkSpan to the factory function vs just creating a
136     // single option). This entry point allows that use case.
137     // Note: PrecompileShader::makeWithLocalMatrix() can still be used and works as expected.
138     SK_API sk_sp<PrecompileShader> LocalMatrix(SkSpan<const sk_sp<PrecompileShader>> wrapped);
139 
140     // Normally, ColorFilterShaders are only created via SkShader::makeWithColorFilter.
141     // However, in the combination API, clients may want to create a set of precompile
142     // ColorFilterShaders (i.e., pass SkSpans to the factory function vs just creating a
143     // single option). This entry point allows that use case.
144     // Note: PrecompileShader::makeWithColorFilter can still be used and works as expected.
145     SK_API sk_sp<PrecompileShader> ColorFilter(
146             SkSpan<const sk_sp<PrecompileShader>> shaders,
147             SkSpan<const sk_sp<PrecompileColorFilter>> colorFilters);
148 
149     // Normally, WorkingColorSpaceShaders are only created via SkShader::makeWithWorkingColorSpace.
150     // However, in the combination API, clients may want to create a set of precompile
151     // WorkingColorSpaceShaders (i.e., pass SkSpans to the factory function vs just creating a
152     // single option). This entry point allows that use case.
153     // Note: PrecompileShader::makeWithWorkingColorSpace can still be used and works as expected.
154     SK_API sk_sp<PrecompileShader> WorkingColorSpace(SkSpan<const sk_sp<PrecompileShader>> shaders,
155                                                      SkSpan<const sk_sp<SkColorSpace>> colorSpaces);
156 
157 } // namespace PrecompileShaders
158 
159 } // namespace skgpu::graphite
160 
161 #endif // skgpu_graphite_precompile_PrecompileShader_DEFINED
162