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