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