xref: /aosp_15_r20/external/skia/tests/graphite/precompile/PaintParamsKeyTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2021 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 #include "tests/Test.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_GRAPHITE)
11*c8dee2aaSAndroid Build Coastguard Worker 
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlurTypes.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkM44.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMaskFilter.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathBuilder.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPicture.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPictureRecorder.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRRect.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkShader.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextBlob.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkVertices.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkYUVAPixmaps.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkBlenders.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkColorMatrix.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkGradientShader.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkHighContrastFilter.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkImageFilters.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkLumaColorFilter.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkOverdrawColorFilter.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkPerlinNoiseShader.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkRuntimeEffect.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Image.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Recorder.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Surface.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/PrecompileContext.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/Precompile.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileBlender.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileColorFilter.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileImageFilter.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileMaskFilter.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileRuntimeEffect.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileShader.h"
46*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
47*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkBlenderBase.h"
48*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkColorFilterPriv.h"
49*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkRuntimeEffectPriv.h"
50*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ContextPriv.h"
51*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ContextUtils.h"
52*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/GraphicsPipelineDesc.h"
53*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/KeyContext.h"
54*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/KeyHelpers.h"
55*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/PaintParams.h"
56*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/PipelineData.h"
57*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/PrecompileContextPriv.h"
58*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RecorderPriv.h"
59*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RenderPassDesc.h"
60*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Renderer.h"
61*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ResourceProvider.h"
62*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RuntimeEffectDictionary.h"
63*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ShaderCodeDictionary.h"
64*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/UniquePaintParamsID.h"
65*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/geom/Geometry.h"
66*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/precompile/PaintOptionsPriv.h"
67*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/precompile/PrecompileColorFiltersPriv.h"
68*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/precompile/PrecompileShadersPriv.h"
69*c8dee2aaSAndroid Build Coastguard Worker #include "src/shaders/SkImageShader.h"
70*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h"
71*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h"
72*c8dee2aaSAndroid Build Coastguard Worker #include "tools/graphite/GraphiteTestContext.h"
73*c8dee2aaSAndroid Build Coastguard Worker #include "tools/graphite/UniqueKeyUtils.h"
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker // Set this to 1 for more expansive (aka far slower) local testing
76*c8dee2aaSAndroid Build Coastguard Worker #define EXPANDED_SET 0
77*c8dee2aaSAndroid Build Coastguard Worker 
78*c8dee2aaSAndroid Build Coastguard Worker // This flag is set to true if during the PaintOption creation an SkPictureShader is created.
79*c8dee2aaSAndroid Build Coastguard Worker // The SkPictureShader will need an additional program in order to draw the contents of its
80*c8dee2aaSAndroid Build Coastguard Worker // SkPicture.
81*c8dee2aaSAndroid Build Coastguard Worker bool gNeedSKPPaintOption = false;
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker constexpr uint32_t kDefaultSeed = 0;
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker using namespace skgpu::graphite;
86*c8dee2aaSAndroid Build Coastguard Worker 
87*c8dee2aaSAndroid Build Coastguard Worker namespace {
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_random_shader(SkRandom*, Recorder*);
90*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> create_random_blender(SkRandom*);
91*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_random_colorfilter(SkRandom*);
92*c8dee2aaSAndroid Build Coastguard Worker 
93*c8dee2aaSAndroid Build Coastguard Worker [[maybe_unused]] std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>>
94*c8dee2aaSAndroid Build Coastguard Worker create_random_image_filter(Recorder*, SkRandom*);
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
97*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
98*c8dee2aaSAndroid Build Coastguard Worker //    M(Empty)
99*c8dee2aaSAndroid Build Coastguard Worker #define SK_ALL_TEST_SHADERS(M) \
100*c8dee2aaSAndroid Build Coastguard Worker     M(Blend)              \
101*c8dee2aaSAndroid Build Coastguard Worker     M(ColorFilter)        \
102*c8dee2aaSAndroid Build Coastguard Worker     M(CoordClamp)         \
103*c8dee2aaSAndroid Build Coastguard Worker     M(ConicalGradient)    \
104*c8dee2aaSAndroid Build Coastguard Worker     M(Image)              \
105*c8dee2aaSAndroid Build Coastguard Worker     M(LinearGradient)     \
106*c8dee2aaSAndroid Build Coastguard Worker     M(LocalMatrix)        \
107*c8dee2aaSAndroid Build Coastguard Worker     M(None)               \
108*c8dee2aaSAndroid Build Coastguard Worker     M(PerlinNoise)        \
109*c8dee2aaSAndroid Build Coastguard Worker     M(Picture)            \
110*c8dee2aaSAndroid Build Coastguard Worker     M(RadialGradient)     \
111*c8dee2aaSAndroid Build Coastguard Worker     M(Runtime)            \
112*c8dee2aaSAndroid Build Coastguard Worker     M(SolidColor)         \
113*c8dee2aaSAndroid Build Coastguard Worker     M(SweepGradient)      \
114*c8dee2aaSAndroid Build Coastguard Worker     M(YUVImage)           \
115*c8dee2aaSAndroid Build Coastguard Worker     M(WorkingColorSpace)
116*c8dee2aaSAndroid Build Coastguard Worker 
117*c8dee2aaSAndroid Build Coastguard Worker enum class ShaderType {
118*c8dee2aaSAndroid Build Coastguard Worker #define M(type) k##type,
119*c8dee2aaSAndroid Build Coastguard Worker     SK_ALL_TEST_SHADERS(M)
120*c8dee2aaSAndroid Build Coastguard Worker #undef M
121*c8dee2aaSAndroid Build Coastguard Worker 
122*c8dee2aaSAndroid Build Coastguard Worker     kLast          = kWorkingColorSpace
123*c8dee2aaSAndroid Build Coastguard Worker };
124*c8dee2aaSAndroid Build Coastguard Worker 
125*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kShaderTypeCount = static_cast<int>(ShaderType::kLast) + 1;
126*c8dee2aaSAndroid Build Coastguard Worker 
to_str(ShaderType s)127*c8dee2aaSAndroid Build Coastguard Worker const char* to_str(ShaderType s) {
128*c8dee2aaSAndroid Build Coastguard Worker     switch (s) {
129*c8dee2aaSAndroid Build Coastguard Worker #define M(type) case ShaderType::k##type : return "ShaderType::k" #type;
130*c8dee2aaSAndroid Build Coastguard Worker         SK_ALL_TEST_SHADERS(M)
131*c8dee2aaSAndroid Build Coastguard Worker #undef M
132*c8dee2aaSAndroid Build Coastguard Worker     }
133*c8dee2aaSAndroid Build Coastguard Worker 
134*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
135*c8dee2aaSAndroid Build Coastguard Worker }
136*c8dee2aaSAndroid Build Coastguard Worker 
137*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
138*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
139*c8dee2aaSAndroid Build Coastguard Worker #define SK_ALL_TEST_MASKFILTERS(M) \
140*c8dee2aaSAndroid Build Coastguard Worker     M(None)                        \
141*c8dee2aaSAndroid Build Coastguard Worker     M(Blur)
142*c8dee2aaSAndroid Build Coastguard Worker 
143*c8dee2aaSAndroid Build Coastguard Worker enum class MaskFilterType {
144*c8dee2aaSAndroid Build Coastguard Worker #define M(type) k##type,
145*c8dee2aaSAndroid Build Coastguard Worker     SK_ALL_TEST_MASKFILTERS(M)
146*c8dee2aaSAndroid Build Coastguard Worker #undef M
147*c8dee2aaSAndroid Build Coastguard Worker 
148*c8dee2aaSAndroid Build Coastguard Worker     kLast = kBlur
149*c8dee2aaSAndroid Build Coastguard Worker };
150*c8dee2aaSAndroid Build Coastguard Worker 
151*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kMaskFilterTypeCount = static_cast<int>(MaskFilterType::kLast) + 1;
152*c8dee2aaSAndroid Build Coastguard Worker 
to_str(MaskFilterType mf)153*c8dee2aaSAndroid Build Coastguard Worker const char* to_str(MaskFilterType mf) {
154*c8dee2aaSAndroid Build Coastguard Worker     switch (mf) {
155*c8dee2aaSAndroid Build Coastguard Worker #define M(type) case MaskFilterType::k##type : return "MaskFilterType::k" #type;
156*c8dee2aaSAndroid Build Coastguard Worker         SK_ALL_TEST_MASKFILTERS(M)
157*c8dee2aaSAndroid Build Coastguard Worker #undef M
158*c8dee2aaSAndroid Build Coastguard Worker     }
159*c8dee2aaSAndroid Build Coastguard Worker 
160*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
161*c8dee2aaSAndroid Build Coastguard Worker }
162*c8dee2aaSAndroid Build Coastguard Worker 
163*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
164*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
165*c8dee2aaSAndroid Build Coastguard Worker #define SK_ALL_TEST_BLENDERS(M) \
166*c8dee2aaSAndroid Build Coastguard Worker     M(None)        \
167*c8dee2aaSAndroid Build Coastguard Worker     M(PorterDuff)  \
168*c8dee2aaSAndroid Build Coastguard Worker     M(ShaderBased) \
169*c8dee2aaSAndroid Build Coastguard Worker     M(Arithmetic)  \
170*c8dee2aaSAndroid Build Coastguard Worker     M(Runtime)
171*c8dee2aaSAndroid Build Coastguard Worker 
172*c8dee2aaSAndroid Build Coastguard Worker // TODO: do we need to add a separable category and/or a category for dstRead requiring blends?
173*c8dee2aaSAndroid Build Coastguard Worker enum class BlenderType {
174*c8dee2aaSAndroid Build Coastguard Worker #define M(type) k##type,
175*c8dee2aaSAndroid Build Coastguard Worker     SK_ALL_TEST_BLENDERS(M)
176*c8dee2aaSAndroid Build Coastguard Worker #undef M
177*c8dee2aaSAndroid Build Coastguard Worker 
178*c8dee2aaSAndroid Build Coastguard Worker     kLast = kRuntime
179*c8dee2aaSAndroid Build Coastguard Worker };
180*c8dee2aaSAndroid Build Coastguard Worker 
181*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kBlenderTypeCount = static_cast<int>(BlenderType::kLast) + 1;
182*c8dee2aaSAndroid Build Coastguard Worker 
to_str(BlenderType b)183*c8dee2aaSAndroid Build Coastguard Worker const char* to_str(BlenderType b) {
184*c8dee2aaSAndroid Build Coastguard Worker     switch (b) {
185*c8dee2aaSAndroid Build Coastguard Worker #define M(type) case BlenderType::k##type : return "BlenderType::k" #type;
186*c8dee2aaSAndroid Build Coastguard Worker         SK_ALL_TEST_BLENDERS(M)
187*c8dee2aaSAndroid Build Coastguard Worker #undef M
188*c8dee2aaSAndroid Build Coastguard Worker     }
189*c8dee2aaSAndroid Build Coastguard Worker 
190*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
191*c8dee2aaSAndroid Build Coastguard Worker }
192*c8dee2aaSAndroid Build Coastguard Worker 
193*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> create_blender(SkRandom*, BlenderType);
194*c8dee2aaSAndroid Build Coastguard Worker 
195*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
196*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
197*c8dee2aaSAndroid Build Coastguard Worker #define SK_ALL_TEST_COLORFILTERS(M) \
198*c8dee2aaSAndroid Build Coastguard Worker     M(None)            \
199*c8dee2aaSAndroid Build Coastguard Worker     M(BlendMode)       \
200*c8dee2aaSAndroid Build Coastguard Worker     M(ColorSpaceXform) \
201*c8dee2aaSAndroid Build Coastguard Worker     M(Compose)         \
202*c8dee2aaSAndroid Build Coastguard Worker     M(Gaussian)        \
203*c8dee2aaSAndroid Build Coastguard Worker     M(HighContrast)    \
204*c8dee2aaSAndroid Build Coastguard Worker     M(HSLAMatrix)      \
205*c8dee2aaSAndroid Build Coastguard Worker     M(Lerp)            \
206*c8dee2aaSAndroid Build Coastguard Worker     M(Lighting)        \
207*c8dee2aaSAndroid Build Coastguard Worker     M(LinearToSRGB)    \
208*c8dee2aaSAndroid Build Coastguard Worker     M(Luma)            \
209*c8dee2aaSAndroid Build Coastguard Worker     M(Matrix)          \
210*c8dee2aaSAndroid Build Coastguard Worker     M(Overdraw)        \
211*c8dee2aaSAndroid Build Coastguard Worker     M(Runtime)         \
212*c8dee2aaSAndroid Build Coastguard Worker     M(SRGBToLinear)    \
213*c8dee2aaSAndroid Build Coastguard Worker     M(Table)           \
214*c8dee2aaSAndroid Build Coastguard Worker     M(WorkingFormat)
215*c8dee2aaSAndroid Build Coastguard Worker 
216*c8dee2aaSAndroid Build Coastguard Worker enum class ColorFilterType {
217*c8dee2aaSAndroid Build Coastguard Worker #define M(type) k##type,
218*c8dee2aaSAndroid Build Coastguard Worker     SK_ALL_TEST_COLORFILTERS(M)
219*c8dee2aaSAndroid Build Coastguard Worker #undef M
220*c8dee2aaSAndroid Build Coastguard Worker 
221*c8dee2aaSAndroid Build Coastguard Worker     kLast = kWorkingFormat
222*c8dee2aaSAndroid Build Coastguard Worker };
223*c8dee2aaSAndroid Build Coastguard Worker 
224*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kColorFilterTypeCount = static_cast<int>(ColorFilterType::kLast) + 1;
225*c8dee2aaSAndroid Build Coastguard Worker 
to_str(ColorFilterType cf)226*c8dee2aaSAndroid Build Coastguard Worker const char* to_str(ColorFilterType cf) {
227*c8dee2aaSAndroid Build Coastguard Worker     switch (cf) {
228*c8dee2aaSAndroid Build Coastguard Worker #define M(type) case ColorFilterType::k##type : return "ColorFilterType::k" #type;
229*c8dee2aaSAndroid Build Coastguard Worker         SK_ALL_TEST_COLORFILTERS(M)
230*c8dee2aaSAndroid Build Coastguard Worker #undef M
231*c8dee2aaSAndroid Build Coastguard Worker     }
232*c8dee2aaSAndroid Build Coastguard Worker 
233*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
234*c8dee2aaSAndroid Build Coastguard Worker }
235*c8dee2aaSAndroid Build Coastguard Worker 
236*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
237*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
238*c8dee2aaSAndroid Build Coastguard Worker #define SK_ALL_TEST_CLIPS(M) \
239*c8dee2aaSAndroid Build Coastguard Worker     M(None)            \
240*c8dee2aaSAndroid Build Coastguard Worker     M(Shader)          \
241*c8dee2aaSAndroid Build Coastguard Worker     M(Shader_Diff)
242*c8dee2aaSAndroid Build Coastguard Worker 
243*c8dee2aaSAndroid Build Coastguard Worker enum class ClipType {
244*c8dee2aaSAndroid Build Coastguard Worker #define M(type) k##type,
245*c8dee2aaSAndroid Build Coastguard Worker     SK_ALL_TEST_CLIPS(M)
246*c8dee2aaSAndroid Build Coastguard Worker #undef M
247*c8dee2aaSAndroid Build Coastguard Worker 
248*c8dee2aaSAndroid Build Coastguard Worker     kLast = kShader_Diff
249*c8dee2aaSAndroid Build Coastguard Worker };
250*c8dee2aaSAndroid Build Coastguard Worker 
251*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kClipTypeCount = static_cast<int>(ClipType::kLast) + 1;
252*c8dee2aaSAndroid Build Coastguard Worker 
to_str(ClipType c)253*c8dee2aaSAndroid Build Coastguard Worker const char* to_str(ClipType c) {
254*c8dee2aaSAndroid Build Coastguard Worker     switch (c) {
255*c8dee2aaSAndroid Build Coastguard Worker #define M(type) case ClipType::k##type : return "ClipType::k" #type;
256*c8dee2aaSAndroid Build Coastguard Worker         SK_ALL_TEST_CLIPS(M)
257*c8dee2aaSAndroid Build Coastguard Worker #undef M
258*c8dee2aaSAndroid Build Coastguard Worker     }
259*c8dee2aaSAndroid Build Coastguard Worker 
260*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
261*c8dee2aaSAndroid Build Coastguard Worker }
262*c8dee2aaSAndroid Build Coastguard Worker 
263*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
264*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
265*c8dee2aaSAndroid Build Coastguard Worker #define SK_ALL_TEST_IMAGE_FILTERS(M) \
266*c8dee2aaSAndroid Build Coastguard Worker     M(None)              \
267*c8dee2aaSAndroid Build Coastguard Worker     M(Arithmetic)        \
268*c8dee2aaSAndroid Build Coastguard Worker     M(BlendMode)         \
269*c8dee2aaSAndroid Build Coastguard Worker     M(RuntimeBlender)    \
270*c8dee2aaSAndroid Build Coastguard Worker     M(Blur)              \
271*c8dee2aaSAndroid Build Coastguard Worker     M(ColorFilter)       \
272*c8dee2aaSAndroid Build Coastguard Worker     M(Displacement)      \
273*c8dee2aaSAndroid Build Coastguard Worker     M(Lighting)          \
274*c8dee2aaSAndroid Build Coastguard Worker     M(MatrixConvolution) \
275*c8dee2aaSAndroid Build Coastguard Worker     M(Morphology)
276*c8dee2aaSAndroid Build Coastguard Worker 
277*c8dee2aaSAndroid Build Coastguard Worker enum class ImageFilterType {
278*c8dee2aaSAndroid Build Coastguard Worker #define M(type) k##type,
279*c8dee2aaSAndroid Build Coastguard Worker     SK_ALL_TEST_IMAGE_FILTERS(M)
280*c8dee2aaSAndroid Build Coastguard Worker #undef M
281*c8dee2aaSAndroid Build Coastguard Worker     kLast = kMorphology
282*c8dee2aaSAndroid Build Coastguard Worker };
283*c8dee2aaSAndroid Build Coastguard Worker 
284*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kImageFilterTypeCount = static_cast<int>(ImageFilterType::kLast) + 1;
285*c8dee2aaSAndroid Build Coastguard Worker 
to_str(ImageFilterType c)286*c8dee2aaSAndroid Build Coastguard Worker const char* to_str(ImageFilterType c) {
287*c8dee2aaSAndroid Build Coastguard Worker     switch (c) {
288*c8dee2aaSAndroid Build Coastguard Worker #define M(type) case ImageFilterType::k##type : return "ImageFilterType::k" #type;
289*c8dee2aaSAndroid Build Coastguard Worker         SK_ALL_TEST_IMAGE_FILTERS(M)
290*c8dee2aaSAndroid Build Coastguard Worker #undef M
291*c8dee2aaSAndroid Build Coastguard Worker     }
292*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
293*c8dee2aaSAndroid Build Coastguard Worker }
294*c8dee2aaSAndroid Build Coastguard Worker 
to_str(DrawTypeFlags dt)295*c8dee2aaSAndroid Build Coastguard Worker const char* to_str(DrawTypeFlags dt) {
296*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(SkPopCount(static_cast<uint32_t>(dt)) == 1);
297*c8dee2aaSAndroid Build Coastguard Worker 
298*c8dee2aaSAndroid Build Coastguard Worker     switch (dt) {
299*c8dee2aaSAndroid Build Coastguard Worker         case DrawTypeFlags::kBitmapText_Mask:  return "DrawTypeFlags::kBitmapText_Mask";
300*c8dee2aaSAndroid Build Coastguard Worker         case DrawTypeFlags::kBitmapText_LCD:   return "DrawTypeFlags::kBitmapText_LCD";
301*c8dee2aaSAndroid Build Coastguard Worker         case DrawTypeFlags::kBitmapText_Color: return "DrawTypeFlags::kBitmapText_Color";
302*c8dee2aaSAndroid Build Coastguard Worker         case DrawTypeFlags::kSDFText:          return "DrawTypeFlags::kSDFText";
303*c8dee2aaSAndroid Build Coastguard Worker         case DrawTypeFlags::kSDFText_LCD:      return "DrawTypeFlags::kSDFText_LCD";
304*c8dee2aaSAndroid Build Coastguard Worker         case DrawTypeFlags::kDrawVertices:     return "DrawTypeFlags::kDrawVertices";
305*c8dee2aaSAndroid Build Coastguard Worker         case DrawTypeFlags::kSimpleShape:      return "DrawTypeFlags::kSimpleShape";
306*c8dee2aaSAndroid Build Coastguard Worker         case DrawTypeFlags::kNonSimpleShape:   return "DrawTypeFlags::kNonSimpleShape";
307*c8dee2aaSAndroid Build Coastguard Worker         default:                               SkASSERT(0); return "DrawTypeFlags::kNone";
308*c8dee2aaSAndroid Build Coastguard Worker     }
309*c8dee2aaSAndroid Build Coastguard Worker 
310*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
311*c8dee2aaSAndroid Build Coastguard Worker }
312*c8dee2aaSAndroid Build Coastguard Worker 
log_run(const char * label,uint32_t seed,ShaderType s,BlenderType bm,ColorFilterType cf,MaskFilterType mf,ImageFilterType imageFilter,ClipType clip,DrawTypeFlags drawTypeFlags)313*c8dee2aaSAndroid Build Coastguard Worker void log_run(const char* label,
314*c8dee2aaSAndroid Build Coastguard Worker              uint32_t seed,
315*c8dee2aaSAndroid Build Coastguard Worker              ShaderType s,
316*c8dee2aaSAndroid Build Coastguard Worker              BlenderType bm,
317*c8dee2aaSAndroid Build Coastguard Worker              ColorFilterType cf,
318*c8dee2aaSAndroid Build Coastguard Worker              MaskFilterType mf,
319*c8dee2aaSAndroid Build Coastguard Worker              ImageFilterType imageFilter,
320*c8dee2aaSAndroid Build Coastguard Worker              ClipType clip,
321*c8dee2aaSAndroid Build Coastguard Worker              DrawTypeFlags drawTypeFlags) {
322*c8dee2aaSAndroid Build Coastguard Worker     SkDebugf("%s:\n"
323*c8dee2aaSAndroid Build Coastguard Worker              "//------------------------\n"
324*c8dee2aaSAndroid Build Coastguard Worker              "uint32_t seed = %u;\n"
325*c8dee2aaSAndroid Build Coastguard Worker              "ShaderType shaderType = %s;\n"
326*c8dee2aaSAndroid Build Coastguard Worker              "BlenderType blenderType = %s;\n"
327*c8dee2aaSAndroid Build Coastguard Worker              "ColorFilterType colorFilterType = %s;\n"
328*c8dee2aaSAndroid Build Coastguard Worker              "MaskFilterType maskFilterType = %s;\n"
329*c8dee2aaSAndroid Build Coastguard Worker              "ImageFilterType imageFilterType = %s;\n"
330*c8dee2aaSAndroid Build Coastguard Worker              "ClipType clipType = %s;\n"
331*c8dee2aaSAndroid Build Coastguard Worker              "DrawTypeFlags drawTypeFlags = %s;\n"
332*c8dee2aaSAndroid Build Coastguard Worker              "//-----------------------\n",
333*c8dee2aaSAndroid Build Coastguard Worker              label, seed,
334*c8dee2aaSAndroid Build Coastguard Worker              to_str(s), to_str(bm), to_str(cf), to_str(mf), to_str(imageFilter), to_str(clip),
335*c8dee2aaSAndroid Build Coastguard Worker              to_str(drawTypeFlags));
336*c8dee2aaSAndroid Build Coastguard Worker }
337*c8dee2aaSAndroid Build Coastguard Worker 
338*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
339*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
340*c8dee2aaSAndroid Build Coastguard Worker static constexpr skcms_TransferFunction gTransferFunctions[] = {
341*c8dee2aaSAndroid Build Coastguard Worker     SkNamedTransferFn::kSRGB,
342*c8dee2aaSAndroid Build Coastguard Worker     SkNamedTransferFn::k2Dot2,
343*c8dee2aaSAndroid Build Coastguard Worker     SkNamedTransferFn::kLinear,
344*c8dee2aaSAndroid Build Coastguard Worker     SkNamedTransferFn::kRec2020,
345*c8dee2aaSAndroid Build Coastguard Worker     SkNamedTransferFn::kPQ,
346*c8dee2aaSAndroid Build Coastguard Worker     SkNamedTransferFn::kHLG,
347*c8dee2aaSAndroid Build Coastguard Worker };
348*c8dee2aaSAndroid Build Coastguard Worker 
349*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kTransferFunctionCount = std::size(gTransferFunctions);
350*c8dee2aaSAndroid Build Coastguard Worker 
random_xfer_function(SkRandom * rand)351*c8dee2aaSAndroid Build Coastguard Worker const skcms_TransferFunction& random_xfer_function(SkRandom* rand) {
352*c8dee2aaSAndroid Build Coastguard Worker     return gTransferFunctions[rand->nextULessThan(kTransferFunctionCount)];
353*c8dee2aaSAndroid Build Coastguard Worker }
354*c8dee2aaSAndroid Build Coastguard Worker 
355*c8dee2aaSAndroid Build Coastguard Worker static constexpr skcms_Matrix3x3 gGamuts[] = {
356*c8dee2aaSAndroid Build Coastguard Worker     SkNamedGamut::kSRGB,
357*c8dee2aaSAndroid Build Coastguard Worker     SkNamedGamut::kAdobeRGB,
358*c8dee2aaSAndroid Build Coastguard Worker     SkNamedGamut::kDisplayP3,
359*c8dee2aaSAndroid Build Coastguard Worker     SkNamedGamut::kRec2020,
360*c8dee2aaSAndroid Build Coastguard Worker     SkNamedGamut::kXYZ,
361*c8dee2aaSAndroid Build Coastguard Worker };
362*c8dee2aaSAndroid Build Coastguard Worker 
363*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kGamutCount = std::size(gGamuts);
364*c8dee2aaSAndroid Build Coastguard Worker 
random_gamut(SkRandom * rand)365*c8dee2aaSAndroid Build Coastguard Worker const skcms_Matrix3x3& random_gamut(SkRandom* rand) {
366*c8dee2aaSAndroid Build Coastguard Worker     return gGamuts[rand->nextULessThan(kGamutCount)];
367*c8dee2aaSAndroid Build Coastguard Worker }
368*c8dee2aaSAndroid Build Coastguard Worker 
369*c8dee2aaSAndroid Build Coastguard Worker enum class ColorSpaceType {
370*c8dee2aaSAndroid Build Coastguard Worker     kNone,
371*c8dee2aaSAndroid Build Coastguard Worker     kSRGB,
372*c8dee2aaSAndroid Build Coastguard Worker     kSRGBLinear,
373*c8dee2aaSAndroid Build Coastguard Worker     kRGB,
374*c8dee2aaSAndroid Build Coastguard Worker 
375*c8dee2aaSAndroid Build Coastguard Worker     kLast = kRGB
376*c8dee2aaSAndroid Build Coastguard Worker };
377*c8dee2aaSAndroid Build Coastguard Worker 
378*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kColorSpaceTypeCount = static_cast<int>(ColorSpaceType::kLast) + 1;
379*c8dee2aaSAndroid Build Coastguard Worker 
random_colorspacetype(SkRandom * rand)380*c8dee2aaSAndroid Build Coastguard Worker ColorSpaceType random_colorspacetype(SkRandom* rand) {
381*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<ColorSpaceType>(rand->nextULessThan(kColorSpaceTypeCount));
382*c8dee2aaSAndroid Build Coastguard Worker }
383*c8dee2aaSAndroid Build Coastguard Worker 
random_colorspace(SkRandom * rand)384*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorSpace> random_colorspace(SkRandom* rand) {
385*c8dee2aaSAndroid Build Coastguard Worker     ColorSpaceType cs = random_colorspacetype(rand);
386*c8dee2aaSAndroid Build Coastguard Worker 
387*c8dee2aaSAndroid Build Coastguard Worker     switch (cs) {
388*c8dee2aaSAndroid Build Coastguard Worker         case ColorSpaceType::kNone:
389*c8dee2aaSAndroid Build Coastguard Worker             return nullptr;
390*c8dee2aaSAndroid Build Coastguard Worker         case ColorSpaceType::kSRGB:
391*c8dee2aaSAndroid Build Coastguard Worker             return SkColorSpace::MakeSRGB();
392*c8dee2aaSAndroid Build Coastguard Worker         case ColorSpaceType::kSRGBLinear:
393*c8dee2aaSAndroid Build Coastguard Worker             return SkColorSpace::MakeSRGBLinear();
394*c8dee2aaSAndroid Build Coastguard Worker         case ColorSpaceType::kRGB:
395*c8dee2aaSAndroid Build Coastguard Worker             return SkColorSpace::MakeRGB(random_xfer_function(rand), random_gamut(rand));
396*c8dee2aaSAndroid Build Coastguard Worker     }
397*c8dee2aaSAndroid Build Coastguard Worker 
398*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
399*c8dee2aaSAndroid Build Coastguard Worker }
400*c8dee2aaSAndroid Build Coastguard Worker 
401*c8dee2aaSAndroid Build Coastguard Worker enum class ColorConstraint {
402*c8dee2aaSAndroid Build Coastguard Worker     kNone,
403*c8dee2aaSAndroid Build Coastguard Worker     kOpaque,
404*c8dee2aaSAndroid Build Coastguard Worker     kTransparent,
405*c8dee2aaSAndroid Build Coastguard Worker };
406*c8dee2aaSAndroid Build Coastguard Worker 
random_color(SkRandom * rand,ColorConstraint constraint)407*c8dee2aaSAndroid Build Coastguard Worker SkColor random_color(SkRandom* rand, ColorConstraint constraint) {
408*c8dee2aaSAndroid Build Coastguard Worker     uint32_t color = rand->nextU();
409*c8dee2aaSAndroid Build Coastguard Worker 
410*c8dee2aaSAndroid Build Coastguard Worker     switch (constraint) {
411*c8dee2aaSAndroid Build Coastguard Worker         case ColorConstraint::kNone:        return color;
412*c8dee2aaSAndroid Build Coastguard Worker         case ColorConstraint::kOpaque:      return 0xff000000 | color;
413*c8dee2aaSAndroid Build Coastguard Worker         case ColorConstraint::kTransparent: return 0x80000000 | color;
414*c8dee2aaSAndroid Build Coastguard Worker     }
415*c8dee2aaSAndroid Build Coastguard Worker 
416*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
417*c8dee2aaSAndroid Build Coastguard Worker }
418*c8dee2aaSAndroid Build Coastguard Worker 
random_color4f(SkRandom * rand,ColorConstraint constraint)419*c8dee2aaSAndroid Build Coastguard Worker SkColor4f random_color4f(SkRandom* rand, ColorConstraint constraint) {
420*c8dee2aaSAndroid Build Coastguard Worker     SkColor4f result = { rand->nextRangeF(0.0f, 1.0f),
421*c8dee2aaSAndroid Build Coastguard Worker                          rand->nextRangeF(0.0f, 1.0f),
422*c8dee2aaSAndroid Build Coastguard Worker                          rand->nextRangeF(0.0f, 1.0f),
423*c8dee2aaSAndroid Build Coastguard Worker                          rand->nextRangeF(0.0f, 1.0f) };
424*c8dee2aaSAndroid Build Coastguard Worker 
425*c8dee2aaSAndroid Build Coastguard Worker     switch (constraint) {
426*c8dee2aaSAndroid Build Coastguard Worker         case ColorConstraint::kNone:        return result;
427*c8dee2aaSAndroid Build Coastguard Worker         case ColorConstraint::kOpaque:      result.fA = 1.0f; return result;
428*c8dee2aaSAndroid Build Coastguard Worker         case ColorConstraint::kTransparent: result.fA = 0.5f; return result;
429*c8dee2aaSAndroid Build Coastguard Worker     }
430*c8dee2aaSAndroid Build Coastguard Worker 
431*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
432*c8dee2aaSAndroid Build Coastguard Worker }
433*c8dee2aaSAndroid Build Coastguard Worker 
random_tilemode(SkRandom * rand)434*c8dee2aaSAndroid Build Coastguard Worker SkTileMode random_tilemode(SkRandom* rand) {
435*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<SkTileMode>(rand->nextULessThan(kSkTileModeCount));
436*c8dee2aaSAndroid Build Coastguard Worker }
437*c8dee2aaSAndroid Build Coastguard Worker 
random_shadertype(SkRandom * rand)438*c8dee2aaSAndroid Build Coastguard Worker ShaderType random_shadertype(SkRandom* rand) {
439*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<ShaderType>(rand->nextULessThan(kShaderTypeCount));
440*c8dee2aaSAndroid Build Coastguard Worker }
441*c8dee2aaSAndroid Build Coastguard Worker 
random_porter_duff_bm(SkRandom * rand)442*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode random_porter_duff_bm(SkRandom* rand) {
443*c8dee2aaSAndroid Build Coastguard Worker     // NOTE: The porter duff modes refer to being able to be consolidated into a single
444*c8dee2aaSAndroid Build Coastguard Worker     // call to sk_porter_duff_blend(), which has slightly fewer compatible blend modes than the
445*c8dee2aaSAndroid Build Coastguard Worker     // "coefficient" blend mode that supports HW blending.
446*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<SkBlendMode>(rand->nextRangeU((unsigned int) SkBlendMode::kClear,
447*c8dee2aaSAndroid Build Coastguard Worker                                                      (unsigned int) SkBlendMode::kPlus));
448*c8dee2aaSAndroid Build Coastguard Worker }
449*c8dee2aaSAndroid Build Coastguard Worker 
random_complex_bm(SkRandom * rand)450*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode random_complex_bm(SkRandom* rand) {
451*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<SkBlendMode>(rand->nextRangeU((unsigned int) SkBlendMode::kPlus,
452*c8dee2aaSAndroid Build Coastguard Worker                                                      (unsigned int) SkBlendMode::kLastMode));
453*c8dee2aaSAndroid Build Coastguard Worker }
454*c8dee2aaSAndroid Build Coastguard Worker 
random_blend_mode(SkRandom * rand)455*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode random_blend_mode(SkRandom* rand) {
456*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<SkBlendMode>(rand->nextULessThan(kSkBlendModeCount));
457*c8dee2aaSAndroid Build Coastguard Worker }
458*c8dee2aaSAndroid Build Coastguard Worker 
random_maskfiltertype(SkRandom * rand)459*c8dee2aaSAndroid Build Coastguard Worker [[maybe_unused]] MaskFilterType random_maskfiltertype(SkRandom* rand) {
460*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
461*c8dee2aaSAndroid Build Coastguard Worker         return MaskFilterType::kNone; // bias this towards no mask filter
462*c8dee2aaSAndroid Build Coastguard Worker     }
463*c8dee2aaSAndroid Build Coastguard Worker 
464*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<MaskFilterType>(rand->nextULessThan(kMaskFilterTypeCount));
465*c8dee2aaSAndroid Build Coastguard Worker }
466*c8dee2aaSAndroid Build Coastguard Worker 
random_blendertype(SkRandom * rand)467*c8dee2aaSAndroid Build Coastguard Worker BlenderType random_blendertype(SkRandom* rand) {
468*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<BlenderType>(rand->nextULessThan(kBlenderTypeCount));
469*c8dee2aaSAndroid Build Coastguard Worker }
470*c8dee2aaSAndroid Build Coastguard Worker 
random_colorfiltertype(SkRandom * rand)471*c8dee2aaSAndroid Build Coastguard Worker ColorFilterType random_colorfiltertype(SkRandom* rand) {
472*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<ColorFilterType>(rand->nextULessThan(kColorFilterTypeCount));
473*c8dee2aaSAndroid Build Coastguard Worker }
474*c8dee2aaSAndroid Build Coastguard Worker 
random_imagefiltertype(SkRandom * rand)475*c8dee2aaSAndroid Build Coastguard Worker ImageFilterType random_imagefiltertype(SkRandom* rand) {
476*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<ImageFilterType>(rand->nextULessThan(kImageFilterTypeCount));
477*c8dee2aaSAndroid Build Coastguard Worker }
478*c8dee2aaSAndroid Build Coastguard Worker 
random_cliptype(SkRandom * rand)479*c8dee2aaSAndroid Build Coastguard Worker [[maybe_unused]] ClipType random_cliptype(SkRandom* rand) {
480*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
481*c8dee2aaSAndroid Build Coastguard Worker         return ClipType::kNone;  // bias this towards no clip
482*c8dee2aaSAndroid Build Coastguard Worker     }
483*c8dee2aaSAndroid Build Coastguard Worker 
484*c8dee2aaSAndroid Build Coastguard Worker     return static_cast<ClipType>(rand->nextULessThan(kClipTypeCount));
485*c8dee2aaSAndroid Build Coastguard Worker }
486*c8dee2aaSAndroid Build Coastguard Worker 
random_drawtype(SkRandom * rand)487*c8dee2aaSAndroid Build Coastguard Worker [[maybe_unused]] DrawTypeFlags random_drawtype(SkRandom* rand) {
488*c8dee2aaSAndroid Build Coastguard Worker     uint32_t index = rand->nextULessThan(8);
489*c8dee2aaSAndroid Build Coastguard Worker 
490*c8dee2aaSAndroid Build Coastguard Worker     switch (index) {
491*c8dee2aaSAndroid Build Coastguard Worker         case 0: return DrawTypeFlags::kBitmapText_Mask;
492*c8dee2aaSAndroid Build Coastguard Worker         case 1: return DrawTypeFlags::kBitmapText_LCD;
493*c8dee2aaSAndroid Build Coastguard Worker         case 2: return DrawTypeFlags::kBitmapText_Color;
494*c8dee2aaSAndroid Build Coastguard Worker         case 3: return DrawTypeFlags::kSDFText;
495*c8dee2aaSAndroid Build Coastguard Worker         case 4: return DrawTypeFlags::kSDFText_LCD;
496*c8dee2aaSAndroid Build Coastguard Worker         case 5: return DrawTypeFlags::kDrawVertices;
497*c8dee2aaSAndroid Build Coastguard Worker         case 6: return DrawTypeFlags::kSimpleShape;
498*c8dee2aaSAndroid Build Coastguard Worker         case 7: return DrawTypeFlags::kNonSimpleShape;
499*c8dee2aaSAndroid Build Coastguard Worker     }
500*c8dee2aaSAndroid Build Coastguard Worker 
501*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(0);
502*c8dee2aaSAndroid Build Coastguard Worker     return DrawTypeFlags::kNone;
503*c8dee2aaSAndroid Build Coastguard Worker }
504*c8dee2aaSAndroid Build Coastguard Worker 
505*c8dee2aaSAndroid Build Coastguard Worker enum LocalMatrixConstraint {
506*c8dee2aaSAndroid Build Coastguard Worker     kNone,
507*c8dee2aaSAndroid Build Coastguard Worker     kWithPerspective,
508*c8dee2aaSAndroid Build Coastguard Worker };
509*c8dee2aaSAndroid Build Coastguard Worker 
random_local_matrix(SkRandom * rand,SkMatrix * storage,LocalMatrixConstraint constaint=LocalMatrixConstraint::kNone)510*c8dee2aaSAndroid Build Coastguard Worker SkMatrix* random_local_matrix(SkRandom* rand,
511*c8dee2aaSAndroid Build Coastguard Worker                               SkMatrix* storage,
512*c8dee2aaSAndroid Build Coastguard Worker                               LocalMatrixConstraint constaint = LocalMatrixConstraint::kNone) {
513*c8dee2aaSAndroid Build Coastguard Worker     // Only return nullptr if constraint == kNone.
514*c8dee2aaSAndroid Build Coastguard Worker     uint32_t matrix = rand->nextULessThan(constaint == LocalMatrixConstraint::kNone ? 4 : 3);
515*c8dee2aaSAndroid Build Coastguard Worker 
516*c8dee2aaSAndroid Build Coastguard Worker     switch (matrix) {
517*c8dee2aaSAndroid Build Coastguard Worker         case 0:  storage->setTranslate(2.0f, 2.0f); break;
518*c8dee2aaSAndroid Build Coastguard Worker         case 1:  storage->setIdentity(); break;
519*c8dee2aaSAndroid Build Coastguard Worker         case 2:  storage->setScale(0.25f, 0.25f, 0.0f, 0.0f); break;
520*c8dee2aaSAndroid Build Coastguard Worker         case 3:  return nullptr;
521*c8dee2aaSAndroid Build Coastguard Worker     }
522*c8dee2aaSAndroid Build Coastguard Worker 
523*c8dee2aaSAndroid Build Coastguard Worker     if (constaint == LocalMatrixConstraint::kWithPerspective) {
524*c8dee2aaSAndroid Build Coastguard Worker         storage->setPerspX(0.5f);
525*c8dee2aaSAndroid Build Coastguard Worker     }
526*c8dee2aaSAndroid Build Coastguard Worker 
527*c8dee2aaSAndroid Build Coastguard Worker     return storage;
528*c8dee2aaSAndroid Build Coastguard Worker }
529*c8dee2aaSAndroid Build Coastguard Worker 
make_image(SkRandom * rand,Recorder * recorder)530*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> make_image(SkRandom* rand, Recorder* recorder) {
531*c8dee2aaSAndroid Build Coastguard Worker     SkColorType ct = SkColorType::kRGBA_8888_SkColorType;
532*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
533*c8dee2aaSAndroid Build Coastguard Worker         ct = SkColorType::kAlpha_8_SkColorType;
534*c8dee2aaSAndroid Build Coastguard Worker     }
535*c8dee2aaSAndroid Build Coastguard Worker 
536*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo info = SkImageInfo::Make(32, 32, ct, kPremul_SkAlphaType, random_colorspace(rand));
537*c8dee2aaSAndroid Build Coastguard Worker 
538*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap bitmap;
539*c8dee2aaSAndroid Build Coastguard Worker     bitmap.allocPixels(info);
540*c8dee2aaSAndroid Build Coastguard Worker     bitmap.eraseColor(SK_ColorBLACK);
541*c8dee2aaSAndroid Build Coastguard Worker 
542*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImage> img = bitmap.asImage();
543*c8dee2aaSAndroid Build Coastguard Worker 
544*c8dee2aaSAndroid Build Coastguard Worker     // TODO: fuzz mipmappedness
545*c8dee2aaSAndroid Build Coastguard Worker     return SkImages::TextureFromImage(recorder, img, {false});
546*c8dee2aaSAndroid Build Coastguard Worker }
547*c8dee2aaSAndroid Build Coastguard Worker 
make_yuv_image(SkRandom * rand,Recorder * recorder)548*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> make_yuv_image(SkRandom* rand, Recorder* recorder) {
549*c8dee2aaSAndroid Build Coastguard Worker 
550*c8dee2aaSAndroid Build Coastguard Worker     SkYUVAInfo::PlaneConfig planeConfig = SkYUVAInfo::PlaneConfig::kY_UV;
551*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
552*c8dee2aaSAndroid Build Coastguard Worker         planeConfig = SkYUVAInfo::PlaneConfig::kY_U_V_A;
553*c8dee2aaSAndroid Build Coastguard Worker     }
554*c8dee2aaSAndroid Build Coastguard Worker 
555*c8dee2aaSAndroid Build Coastguard Worker     SkYUVAInfo yuvaInfo({ 32, 32, },
556*c8dee2aaSAndroid Build Coastguard Worker                         planeConfig,
557*c8dee2aaSAndroid Build Coastguard Worker                         SkYUVAInfo::Subsampling::k420,
558*c8dee2aaSAndroid Build Coastguard Worker                         kJPEG_Full_SkYUVColorSpace);
559*c8dee2aaSAndroid Build Coastguard Worker 
560*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(yuvaInfo.isValid());
561*c8dee2aaSAndroid Build Coastguard Worker 
562*c8dee2aaSAndroid Build Coastguard Worker     SkYUVAPixmapInfo pmInfo(yuvaInfo, SkYUVAPixmapInfo::DataType::kUnorm8, nullptr);
563*c8dee2aaSAndroid Build Coastguard Worker 
564*c8dee2aaSAndroid Build Coastguard Worker     SkYUVAPixmaps pixmaps = SkYUVAPixmaps::Allocate(pmInfo);
565*c8dee2aaSAndroid Build Coastguard Worker 
566*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < pixmaps.numPlanes(); ++i) {
567*c8dee2aaSAndroid Build Coastguard Worker         pixmaps.plane(i).erase(SK_ColorBLACK);
568*c8dee2aaSAndroid Build Coastguard Worker     }
569*c8dee2aaSAndroid Build Coastguard Worker 
570*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkColorSpace> cs;
571*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
572*c8dee2aaSAndroid Build Coastguard Worker         cs = SkColorSpace::MakeSRGBLinear();
573*c8dee2aaSAndroid Build Coastguard Worker     }
574*c8dee2aaSAndroid Build Coastguard Worker 
575*c8dee2aaSAndroid Build Coastguard Worker     return SkImages::TextureFromYUVAPixmaps(recorder,
576*c8dee2aaSAndroid Build Coastguard Worker                                             pixmaps,
577*c8dee2aaSAndroid Build Coastguard Worker                                             {/* fMipmapped= */ false},
578*c8dee2aaSAndroid Build Coastguard Worker                                             /* limitToMaxTextureSize= */ false,
579*c8dee2aaSAndroid Build Coastguard Worker                                             std::move(cs));
580*c8dee2aaSAndroid Build Coastguard Worker }
581*c8dee2aaSAndroid Build Coastguard Worker 
582*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
make_picture(SkRandom * rand)583*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPicture> make_picture(SkRandom* rand) {
584*c8dee2aaSAndroid Build Coastguard Worker     constexpr SkRect kRect = SkRect::MakeWH(128, 128);
585*c8dee2aaSAndroid Build Coastguard Worker 
586*c8dee2aaSAndroid Build Coastguard Worker     SkPictureRecorder recorder;
587*c8dee2aaSAndroid Build Coastguard Worker 
588*c8dee2aaSAndroid Build Coastguard Worker     SkCanvas* canvas = recorder.beginRecording(kRect);
589*c8dee2aaSAndroid Build Coastguard Worker 
590*c8dee2aaSAndroid Build Coastguard Worker     SkPaint paint; // Explicitly using the default SkPaint here
591*c8dee2aaSAndroid Build Coastguard Worker 
592*c8dee2aaSAndroid Build Coastguard Worker     canvas->drawRect(kRect, paint);
593*c8dee2aaSAndroid Build Coastguard Worker 
594*c8dee2aaSAndroid Build Coastguard Worker     return recorder.finishRecordingAsPicture();
595*c8dee2aaSAndroid Build Coastguard Worker }
596*c8dee2aaSAndroid Build Coastguard Worker 
597*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
create_coord_clamp_shader(SkRandom * rand,Recorder * recorder)598*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_coord_clamp_shader(SkRandom* rand,
599*c8dee2aaSAndroid Build Coastguard Worker                                                                               Recorder* recorder) {
600*c8dee2aaSAndroid Build Coastguard Worker     auto [s, o] = create_random_shader(rand, recorder);
601*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!s == !o);
602*c8dee2aaSAndroid Build Coastguard Worker 
603*c8dee2aaSAndroid Build Coastguard Worker     if (!s) {
604*c8dee2aaSAndroid Build Coastguard Worker         return { nullptr, nullptr };
605*c8dee2aaSAndroid Build Coastguard Worker     }
606*c8dee2aaSAndroid Build Coastguard Worker 
607*c8dee2aaSAndroid Build Coastguard Worker     constexpr SkRect kSubset{0, 0, 256, 256}; // this is somewhat arbitrary but we need some subset
608*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> ccs = SkShaders::CoordClamp(std::move(s), kSubset);
609*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileShader> cco = PrecompileShaders::CoordClamp({ std::move(o) });
610*c8dee2aaSAndroid Build Coastguard Worker 
611*c8dee2aaSAndroid Build Coastguard Worker     return { ccs, cco };
612*c8dee2aaSAndroid Build Coastguard Worker }
613*c8dee2aaSAndroid Build Coastguard Worker 
614*c8dee2aaSAndroid Build Coastguard Worker #if 0
615*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_empty_shader(SkRandom* /* rand */) {
616*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> s = SkShaders::Empty();
617*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileShader> o = PrecompileShaders::Empty();
618*c8dee2aaSAndroid Build Coastguard Worker 
619*c8dee2aaSAndroid Build Coastguard Worker     return { s, o };
620*c8dee2aaSAndroid Build Coastguard Worker }
621*c8dee2aaSAndroid Build Coastguard Worker #endif
622*c8dee2aaSAndroid Build Coastguard Worker 
create_perlin_noise_shader(SkRandom * rand)623*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_perlin_noise_shader(SkRandom* rand) {
624*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> s;
625*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileShader> o;
626*c8dee2aaSAndroid Build Coastguard Worker 
627*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
628*c8dee2aaSAndroid Build Coastguard Worker         s = SkShaders::MakeFractalNoise(/* baseFrequencyX= */ 0.3f,
629*c8dee2aaSAndroid Build Coastguard Worker                                         /* baseFrequencyY= */ 0.3f,
630*c8dee2aaSAndroid Build Coastguard Worker                                         /* numOctaves= */ 2,
631*c8dee2aaSAndroid Build Coastguard Worker                                         /* seed= */ 4);
632*c8dee2aaSAndroid Build Coastguard Worker         o = PrecompileShaders::MakeFractalNoise();
633*c8dee2aaSAndroid Build Coastguard Worker     } else {
634*c8dee2aaSAndroid Build Coastguard Worker         s = SkShaders::MakeTurbulence(/* baseFrequencyX= */ 0.3f,
635*c8dee2aaSAndroid Build Coastguard Worker                                       /* baseFrequencyY= */ 0.3f,
636*c8dee2aaSAndroid Build Coastguard Worker                                       /* numOctaves= */ 2,
637*c8dee2aaSAndroid Build Coastguard Worker                                       /* seed= */ 4);
638*c8dee2aaSAndroid Build Coastguard Worker         o = PrecompileShaders::MakeTurbulence();
639*c8dee2aaSAndroid Build Coastguard Worker     }
640*c8dee2aaSAndroid Build Coastguard Worker 
641*c8dee2aaSAndroid Build Coastguard Worker     return { s, o };
642*c8dee2aaSAndroid Build Coastguard Worker }
643*c8dee2aaSAndroid Build Coastguard Worker 
create_picture_shader(SkRandom * rand)644*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_picture_shader(SkRandom* rand) {
645*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkPicture> picture = make_picture(rand);
646*c8dee2aaSAndroid Build Coastguard Worker 
647*c8dee2aaSAndroid Build Coastguard Worker     gNeedSKPPaintOption = true;
648*c8dee2aaSAndroid Build Coastguard Worker 
649*c8dee2aaSAndroid Build Coastguard Worker     SkMatrix lmStorage;
650*c8dee2aaSAndroid Build Coastguard Worker     SkMatrix* lmPtr = random_local_matrix(rand, &lmStorage);
651*c8dee2aaSAndroid Build Coastguard Worker 
652*c8dee2aaSAndroid Build Coastguard Worker     // TODO: can the clamp, filter mode, or tileRect affect the final program?
653*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> s = picture->makeShader(SkTileMode::kClamp,
654*c8dee2aaSAndroid Build Coastguard Worker                                             SkTileMode::kClamp,
655*c8dee2aaSAndroid Build Coastguard Worker                                             SkFilterMode::kLinear,
656*c8dee2aaSAndroid Build Coastguard Worker                                             lmPtr,
657*c8dee2aaSAndroid Build Coastguard Worker                                             /* tileRect= */ nullptr);
658*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileShader> o = PrecompileShadersPriv::Picture(SkToBool(lmPtr));
659*c8dee2aaSAndroid Build Coastguard Worker 
660*c8dee2aaSAndroid Build Coastguard Worker     return { s, o };
661*c8dee2aaSAndroid Build Coastguard Worker }
662*c8dee2aaSAndroid Build Coastguard Worker 
create_runtime_shader(SkRandom *)663*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_runtime_shader(SkRandom* /* rand */) {
664*c8dee2aaSAndroid Build Coastguard Worker     static SkRuntimeEffect* sEffect = SkMakeRuntimeEffect(
665*c8dee2aaSAndroid Build Coastguard Worker             SkRuntimeEffect::MakeForShader,
666*c8dee2aaSAndroid Build Coastguard Worker             // draw a circle centered at "center" w/ inner and outer radii in "radii"
667*c8dee2aaSAndroid Build Coastguard Worker             "uniform float2 center;"
668*c8dee2aaSAndroid Build Coastguard Worker             "uniform float2 radii;"
669*c8dee2aaSAndroid Build Coastguard Worker             "half4 main(float2 xy) {"
670*c8dee2aaSAndroid Build Coastguard Worker                 "float len = length(xy - center);"
671*c8dee2aaSAndroid Build Coastguard Worker                 "half value = len < radii.x ? 0.0 : (len > radii.y ? 0.0 : 1.0);"
672*c8dee2aaSAndroid Build Coastguard Worker                 "return half4(value);"
673*c8dee2aaSAndroid Build Coastguard Worker             "}"
674*c8dee2aaSAndroid Build Coastguard Worker     );
675*c8dee2aaSAndroid Build Coastguard Worker 
676*c8dee2aaSAndroid Build Coastguard Worker     static const float kUniforms[4] = { 50.0f, 50.0f, 40.0f, 50.0f };
677*c8dee2aaSAndroid Build Coastguard Worker 
678*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkData> uniforms = SkData::MakeWithCopy(kUniforms, sizeof(kUniforms));
679*c8dee2aaSAndroid Build Coastguard Worker 
680*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> s = sEffect->makeShader(std::move(uniforms), /* children= */ {});
681*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileShader> o = PrecompileRuntimeEffects::MakePrecompileShader(sk_ref_sp(sEffect));
682*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(s), std::move(o) };
683*c8dee2aaSAndroid Build Coastguard Worker }
684*c8dee2aaSAndroid Build Coastguard Worker 
create_solid_shader(SkRandom * rand,ColorConstraint constraint=ColorConstraint::kNone)685*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_solid_shader(
686*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand,
687*c8dee2aaSAndroid Build Coastguard Worker         ColorConstraint constraint = ColorConstraint::kNone) {
688*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> s;
689*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileShader> o;
690*c8dee2aaSAndroid Build Coastguard Worker 
691*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
692*c8dee2aaSAndroid Build Coastguard Worker         s = SkShaders::Color(random_color(rand, constraint));
693*c8dee2aaSAndroid Build Coastguard Worker         o = PrecompileShaders::Color();
694*c8dee2aaSAndroid Build Coastguard Worker     } else {
695*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkColorSpace> cs = random_colorspace(rand);
696*c8dee2aaSAndroid Build Coastguard Worker         s = SkShaders::Color(random_color4f(rand, constraint), cs);
697*c8dee2aaSAndroid Build Coastguard Worker         o = PrecompileShaders::Color(std::move(cs));
698*c8dee2aaSAndroid Build Coastguard Worker     }
699*c8dee2aaSAndroid Build Coastguard Worker 
700*c8dee2aaSAndroid Build Coastguard Worker     return { s, o };
701*c8dee2aaSAndroid Build Coastguard Worker }
702*c8dee2aaSAndroid Build Coastguard Worker 
create_gradient_shader(SkRandom * rand,SkShaderBase::GradientType type,ColorConstraint constraint=ColorConstraint::kOpaque)703*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_gradient_shader(
704*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand,
705*c8dee2aaSAndroid Build Coastguard Worker         SkShaderBase::GradientType type,
706*c8dee2aaSAndroid Build Coastguard Worker         ColorConstraint constraint = ColorConstraint::kOpaque) {
707*c8dee2aaSAndroid Build Coastguard Worker     // TODO: fuzz more of the gradient parameters
708*c8dee2aaSAndroid Build Coastguard Worker 
709*c8dee2aaSAndroid Build Coastguard Worker     static constexpr int kMaxNumStops = 9;
710*c8dee2aaSAndroid Build Coastguard Worker     SkColor colors[kMaxNumStops] = {
711*c8dee2aaSAndroid Build Coastguard Worker             random_color(rand, constraint),
712*c8dee2aaSAndroid Build Coastguard Worker             random_color(rand, constraint),
713*c8dee2aaSAndroid Build Coastguard Worker             random_color(rand, constraint),
714*c8dee2aaSAndroid Build Coastguard Worker             random_color(rand, constraint),
715*c8dee2aaSAndroid Build Coastguard Worker             random_color(rand, constraint),
716*c8dee2aaSAndroid Build Coastguard Worker             random_color(rand, constraint),
717*c8dee2aaSAndroid Build Coastguard Worker             random_color(rand, constraint),
718*c8dee2aaSAndroid Build Coastguard Worker             random_color(rand, constraint),
719*c8dee2aaSAndroid Build Coastguard Worker             random_color(rand, constraint)
720*c8dee2aaSAndroid Build Coastguard Worker     };
721*c8dee2aaSAndroid Build Coastguard Worker     static const SkPoint kPts[kMaxNumStops] = {
722*c8dee2aaSAndroid Build Coastguard Worker             { -100.0f, -100.0f },
723*c8dee2aaSAndroid Build Coastguard Worker             { -50.0f, -50.0f },
724*c8dee2aaSAndroid Build Coastguard Worker             { -25.0f, -25.0f },
725*c8dee2aaSAndroid Build Coastguard Worker             { -12.5f, -12.5f },
726*c8dee2aaSAndroid Build Coastguard Worker             { 0.0f, 0.0f },
727*c8dee2aaSAndroid Build Coastguard Worker             { 12.5f, 12.5f },
728*c8dee2aaSAndroid Build Coastguard Worker             { 25.0f, 25.0f },
729*c8dee2aaSAndroid Build Coastguard Worker             { 50.0f, 50.0f },
730*c8dee2aaSAndroid Build Coastguard Worker             { 100.0f, 100.0f }
731*c8dee2aaSAndroid Build Coastguard Worker     };
732*c8dee2aaSAndroid Build Coastguard Worker     static const float kOffsets[kMaxNumStops] =
733*c8dee2aaSAndroid Build Coastguard Worker             { 0.0f, 0.125f, 0.25f, 0.375f, 0.5f, 0.625f, 0.75f, 0.875f, 1.0f };
734*c8dee2aaSAndroid Build Coastguard Worker 
735*c8dee2aaSAndroid Build Coastguard Worker     int numStops;
736*c8dee2aaSAndroid Build Coastguard Worker 
737*c8dee2aaSAndroid Build Coastguard Worker     switch (rand->nextULessThan(3)) {
738*c8dee2aaSAndroid Build Coastguard Worker         case 0:  numStops = 2; break;
739*c8dee2aaSAndroid Build Coastguard Worker         case 1:  numStops = 7; break;
740*c8dee2aaSAndroid Build Coastguard Worker         case 2:  [[fallthrough]];
741*c8dee2aaSAndroid Build Coastguard Worker         default: numStops = kMaxNumStops; break;
742*c8dee2aaSAndroid Build Coastguard Worker     }
743*c8dee2aaSAndroid Build Coastguard Worker 
744*c8dee2aaSAndroid Build Coastguard Worker     SkMatrix lmStorage;
745*c8dee2aaSAndroid Build Coastguard Worker     SkMatrix* lmPtr = random_local_matrix(rand, &lmStorage);
746*c8dee2aaSAndroid Build Coastguard Worker 
747*c8dee2aaSAndroid Build Coastguard Worker     uint32_t flags = rand->nextBool() ? 0x0 : SkGradientShader::kInterpolateColorsInPremul_Flag;
748*c8dee2aaSAndroid Build Coastguard Worker 
749*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> s;
750*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileShader> o;
751*c8dee2aaSAndroid Build Coastguard Worker 
752*c8dee2aaSAndroid Build Coastguard Worker     SkTileMode tm = random_tilemode(rand);
753*c8dee2aaSAndroid Build Coastguard Worker 
754*c8dee2aaSAndroid Build Coastguard Worker     switch (type) {
755*c8dee2aaSAndroid Build Coastguard Worker         case SkShaderBase::GradientType::kLinear:
756*c8dee2aaSAndroid Build Coastguard Worker             s = SkGradientShader::MakeLinear(kPts,
757*c8dee2aaSAndroid Build Coastguard Worker                                              colors, kOffsets, numStops, tm, flags, lmPtr);
758*c8dee2aaSAndroid Build Coastguard Worker             o = PrecompileShaders::LinearGradient();
759*c8dee2aaSAndroid Build Coastguard Worker             break;
760*c8dee2aaSAndroid Build Coastguard Worker         case SkShaderBase::GradientType::kRadial:
761*c8dee2aaSAndroid Build Coastguard Worker             s = SkGradientShader::MakeRadial(/* center= */ {0, 0}, /* radius= */ 100,
762*c8dee2aaSAndroid Build Coastguard Worker                                              colors, kOffsets, numStops, tm, flags, lmPtr);
763*c8dee2aaSAndroid Build Coastguard Worker             o = PrecompileShaders::RadialGradient();
764*c8dee2aaSAndroid Build Coastguard Worker             break;
765*c8dee2aaSAndroid Build Coastguard Worker         case SkShaderBase::GradientType::kSweep:
766*c8dee2aaSAndroid Build Coastguard Worker             s = SkGradientShader::MakeSweep(/* cx= */ 0, /* cy= */ 0,
767*c8dee2aaSAndroid Build Coastguard Worker                                             colors, kOffsets, numStops, tm,
768*c8dee2aaSAndroid Build Coastguard Worker                                             /* startAngle= */ 0, /* endAngle= */ 359,
769*c8dee2aaSAndroid Build Coastguard Worker                                             flags, lmPtr);
770*c8dee2aaSAndroid Build Coastguard Worker             o = PrecompileShaders::SweepGradient();
771*c8dee2aaSAndroid Build Coastguard Worker             break;
772*c8dee2aaSAndroid Build Coastguard Worker         case SkShaderBase::GradientType::kConical:
773*c8dee2aaSAndroid Build Coastguard Worker             s = SkGradientShader::MakeTwoPointConical(/* start= */ {100, 100},
774*c8dee2aaSAndroid Build Coastguard Worker                                                       /* startRadius= */ 100,
775*c8dee2aaSAndroid Build Coastguard Worker                                                       /* end= */ {-100, -100},
776*c8dee2aaSAndroid Build Coastguard Worker                                                       /* endRadius= */ 100,
777*c8dee2aaSAndroid Build Coastguard Worker                                                       colors, kOffsets, numStops, tm, flags, lmPtr);
778*c8dee2aaSAndroid Build Coastguard Worker             o = PrecompileShaders::TwoPointConicalGradient();
779*c8dee2aaSAndroid Build Coastguard Worker             break;
780*c8dee2aaSAndroid Build Coastguard Worker         case SkShaderBase::GradientType::kNone:
781*c8dee2aaSAndroid Build Coastguard Worker             SkDEBUGFAIL("Gradient shader says its type is none");
782*c8dee2aaSAndroid Build Coastguard Worker             break;
783*c8dee2aaSAndroid Build Coastguard Worker     }
784*c8dee2aaSAndroid Build Coastguard Worker 
785*c8dee2aaSAndroid Build Coastguard Worker     return { s, o };
786*c8dee2aaSAndroid Build Coastguard Worker }
787*c8dee2aaSAndroid Build Coastguard Worker 
create_localmatrix_shader(SkRandom * rand,Recorder * recorder)788*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_localmatrix_shader(SkRandom* rand,
789*c8dee2aaSAndroid Build Coastguard Worker                                                                               Recorder* recorder) {
790*c8dee2aaSAndroid Build Coastguard Worker     auto [s, o] = create_random_shader(rand, recorder);
791*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!s == !o);
792*c8dee2aaSAndroid Build Coastguard Worker 
793*c8dee2aaSAndroid Build Coastguard Worker     if (!s) {
794*c8dee2aaSAndroid Build Coastguard Worker         return { nullptr, nullptr };
795*c8dee2aaSAndroid Build Coastguard Worker     }
796*c8dee2aaSAndroid Build Coastguard Worker 
797*c8dee2aaSAndroid Build Coastguard Worker     bool hasPerspective = rand->nextBool();
798*c8dee2aaSAndroid Build Coastguard Worker 
799*c8dee2aaSAndroid Build Coastguard Worker     SkMatrix lmStorage;
800*c8dee2aaSAndroid Build Coastguard Worker     random_local_matrix(rand, &lmStorage, hasPerspective ? LocalMatrixConstraint::kWithPerspective
801*c8dee2aaSAndroid Build Coastguard Worker                                                          : LocalMatrixConstraint::kNone);
802*c8dee2aaSAndroid Build Coastguard Worker 
803*c8dee2aaSAndroid Build Coastguard Worker     return { s->makeWithLocalMatrix(lmStorage), o->makeWithLocalMatrix(hasPerspective) };
804*c8dee2aaSAndroid Build Coastguard Worker }
805*c8dee2aaSAndroid Build Coastguard Worker 
create_colorfilter_shader(SkRandom * rand,Recorder * recorder)806*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_colorfilter_shader(SkRandom* rand,
807*c8dee2aaSAndroid Build Coastguard Worker                                                                               Recorder* recorder) {
808*c8dee2aaSAndroid Build Coastguard Worker     auto [s, o] = create_random_shader(rand, recorder);
809*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!s == !o);
810*c8dee2aaSAndroid Build Coastguard Worker 
811*c8dee2aaSAndroid Build Coastguard Worker     if (!s) {
812*c8dee2aaSAndroid Build Coastguard Worker         return { nullptr, nullptr };
813*c8dee2aaSAndroid Build Coastguard Worker     }
814*c8dee2aaSAndroid Build Coastguard Worker 
815*c8dee2aaSAndroid Build Coastguard Worker     auto [cf, cfO] = create_random_colorfilter(rand);
816*c8dee2aaSAndroid Build Coastguard Worker 
817*c8dee2aaSAndroid Build Coastguard Worker     return { s->makeWithColorFilter(std::move(cf)), o->makeWithColorFilter(std::move(cfO)) };
818*c8dee2aaSAndroid Build Coastguard Worker }
819*c8dee2aaSAndroid Build Coastguard Worker 
820*c8dee2aaSAndroid Build Coastguard Worker // TODO: With the new explicit PrecompileImageFilter API we need to test out complete DAGS of IFs
create_image_shader(SkRandom * rand,Recorder * recorder)821*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_image_shader(SkRandom* rand,
822*c8dee2aaSAndroid Build Coastguard Worker                                                                         Recorder* recorder) {
823*c8dee2aaSAndroid Build Coastguard Worker     SkTileMode tmX = random_tilemode(rand);
824*c8dee2aaSAndroid Build Coastguard Worker     SkTileMode tmY = random_tilemode(rand);
825*c8dee2aaSAndroid Build Coastguard Worker 
826*c8dee2aaSAndroid Build Coastguard Worker     SkMatrix lmStorage;
827*c8dee2aaSAndroid Build Coastguard Worker     SkMatrix* lmPtr = random_local_matrix(rand, &lmStorage);
828*c8dee2aaSAndroid Build Coastguard Worker 
829*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> s;
830*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileShader> o;
831*c8dee2aaSAndroid Build Coastguard Worker 
832*c8dee2aaSAndroid Build Coastguard Worker     // TODO: the combination system accounts for cubic vs. non-cubic sampling and HW vs. non-HW
833*c8dee2aaSAndroid Build Coastguard Worker     // tiling. We should test those combinations in the fuzzer.
834*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
835*c8dee2aaSAndroid Build Coastguard Worker         s = SkShaders::Image(make_image(rand, recorder),
836*c8dee2aaSAndroid Build Coastguard Worker                              tmX, tmY,
837*c8dee2aaSAndroid Build Coastguard Worker                              SkSamplingOptions(),
838*c8dee2aaSAndroid Build Coastguard Worker                              lmPtr);
839*c8dee2aaSAndroid Build Coastguard Worker         o = PrecompileShaders::Image();
840*c8dee2aaSAndroid Build Coastguard Worker     } else {
841*c8dee2aaSAndroid Build Coastguard Worker         s = SkShaders::RawImage(make_image(rand, recorder),
842*c8dee2aaSAndroid Build Coastguard Worker                                 tmX, tmY,
843*c8dee2aaSAndroid Build Coastguard Worker                                 SkSamplingOptions(),
844*c8dee2aaSAndroid Build Coastguard Worker                                 lmPtr);
845*c8dee2aaSAndroid Build Coastguard Worker         o = PrecompileShaders::RawImage();
846*c8dee2aaSAndroid Build Coastguard Worker     }
847*c8dee2aaSAndroid Build Coastguard Worker 
848*c8dee2aaSAndroid Build Coastguard Worker     return { s, o };
849*c8dee2aaSAndroid Build Coastguard Worker }
850*c8dee2aaSAndroid Build Coastguard Worker 
create_yuv_image_shader(SkRandom * rand,Recorder * recorder)851*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_yuv_image_shader(SkRandom* rand,
852*c8dee2aaSAndroid Build Coastguard Worker                                                                             Recorder* recorder) {
853*c8dee2aaSAndroid Build Coastguard Worker     SkTileMode tmX = random_tilemode(rand);
854*c8dee2aaSAndroid Build Coastguard Worker     SkTileMode tmY = random_tilemode(rand);
855*c8dee2aaSAndroid Build Coastguard Worker 
856*c8dee2aaSAndroid Build Coastguard Worker     SkMatrix lmStorage;
857*c8dee2aaSAndroid Build Coastguard Worker     SkMatrix* lmPtr = random_local_matrix(rand, &lmStorage);
858*c8dee2aaSAndroid Build Coastguard Worker 
859*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> s;
860*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileShader> o;
861*c8dee2aaSAndroid Build Coastguard Worker 
862*c8dee2aaSAndroid Build Coastguard Worker     SkSamplingOptions samplingOptions(SkFilterMode::kLinear);
863*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
864*c8dee2aaSAndroid Build Coastguard Worker         samplingOptions = SkCubicResampler::Mitchell();
865*c8dee2aaSAndroid Build Coastguard Worker     }
866*c8dee2aaSAndroid Build Coastguard Worker 
867*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImage> yuvImage = make_yuv_image(rand, recorder);
868*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
869*c8dee2aaSAndroid Build Coastguard Worker         s = SkImageShader::MakeSubset(std::move(yuvImage), SkRect::MakeXYWH(8, 8, 16, 16),
870*c8dee2aaSAndroid Build Coastguard Worker                                       tmX, tmY, samplingOptions, lmPtr);
871*c8dee2aaSAndroid Build Coastguard Worker     } else {
872*c8dee2aaSAndroid Build Coastguard Worker         s = SkShaders::Image(std::move(yuvImage), tmX, tmY, samplingOptions, lmPtr);
873*c8dee2aaSAndroid Build Coastguard Worker     }
874*c8dee2aaSAndroid Build Coastguard Worker 
875*c8dee2aaSAndroid Build Coastguard Worker     o = PrecompileShaders::YUVImage();
876*c8dee2aaSAndroid Build Coastguard Worker 
877*c8dee2aaSAndroid Build Coastguard Worker     return { s, o };
878*c8dee2aaSAndroid Build Coastguard Worker }
879*c8dee2aaSAndroid Build Coastguard Worker 
create_blend_shader(SkRandom * rand,Recorder * recorder)880*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_blend_shader(SkRandom* rand,
881*c8dee2aaSAndroid Build Coastguard Worker                                                                         Recorder* recorder) {
882*c8dee2aaSAndroid Build Coastguard Worker     // TODO: add explicit testing of the kClear, kDst and kSrc blend modes since they short
883*c8dee2aaSAndroid Build Coastguard Worker     // circuit creation of a true blend shader (i.e., in SkShaders::Blend).
884*c8dee2aaSAndroid Build Coastguard Worker     auto [blender, blenderO] = create_random_blender(rand);
885*c8dee2aaSAndroid Build Coastguard Worker 
886*c8dee2aaSAndroid Build Coastguard Worker     auto [dstS, dstO] = create_random_shader(rand, recorder);
887*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!dstS == !dstO);
888*c8dee2aaSAndroid Build Coastguard Worker     if (!dstS) {
889*c8dee2aaSAndroid Build Coastguard Worker         return { nullptr, nullptr };
890*c8dee2aaSAndroid Build Coastguard Worker     }
891*c8dee2aaSAndroid Build Coastguard Worker 
892*c8dee2aaSAndroid Build Coastguard Worker     auto [srcS, srcO] = create_random_shader(rand, recorder);
893*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!srcS == !srcO);
894*c8dee2aaSAndroid Build Coastguard Worker     if (!srcS) {
895*c8dee2aaSAndroid Build Coastguard Worker         return { nullptr, nullptr };
896*c8dee2aaSAndroid Build Coastguard Worker     }
897*c8dee2aaSAndroid Build Coastguard Worker 
898*c8dee2aaSAndroid Build Coastguard Worker     auto s = SkShaders::Blend(std::move(blender), std::move(dstS), std::move(srcS));
899*c8dee2aaSAndroid Build Coastguard Worker     auto o = PrecompileShaders::Blend(SkSpan<const sk_sp<PrecompileBlender>>({ blenderO }),
900*c8dee2aaSAndroid Build Coastguard Worker                                       { dstO }, { srcO });
901*c8dee2aaSAndroid Build Coastguard Worker 
902*c8dee2aaSAndroid Build Coastguard Worker     return { s, o };
903*c8dee2aaSAndroid Build Coastguard Worker }
904*c8dee2aaSAndroid Build Coastguard Worker 
create_workingCS_shader(SkRandom * rand,Recorder * recorder)905*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_workingCS_shader(SkRandom* rand,
906*c8dee2aaSAndroid Build Coastguard Worker                                                                             Recorder* recorder) {
907*c8dee2aaSAndroid Build Coastguard Worker     auto [wrappedS, wrappedO] = create_random_shader(rand, recorder);
908*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!wrappedS == !wrappedO);
909*c8dee2aaSAndroid Build Coastguard Worker     if (!wrappedS) {
910*c8dee2aaSAndroid Build Coastguard Worker         return { nullptr, nullptr };
911*c8dee2aaSAndroid Build Coastguard Worker     }
912*c8dee2aaSAndroid Build Coastguard Worker 
913*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkColorSpace> cs = random_colorspace(rand);
914*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> s = wrappedS->makeWithWorkingColorSpace(cs);
915*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileShader> o = wrappedO->makeWithWorkingColorSpace(std::move(cs));
916*c8dee2aaSAndroid Build Coastguard Worker 
917*c8dee2aaSAndroid Build Coastguard Worker     return { s, o };
918*c8dee2aaSAndroid Build Coastguard Worker }
919*c8dee2aaSAndroid Build Coastguard Worker 
create_shader(SkRandom * rand,Recorder * recorder,ShaderType shaderType)920*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>>  create_shader(SkRandom* rand,
921*c8dee2aaSAndroid Build Coastguard Worker                                                                    Recorder* recorder,
922*c8dee2aaSAndroid Build Coastguard Worker                                                                    ShaderType shaderType) {
923*c8dee2aaSAndroid Build Coastguard Worker 
924*c8dee2aaSAndroid Build Coastguard Worker     switch (shaderType) {
925*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kNone:
926*c8dee2aaSAndroid Build Coastguard Worker             return { nullptr, nullptr };
927*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kBlend:
928*c8dee2aaSAndroid Build Coastguard Worker             return create_blend_shader(rand, recorder);
929*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kColorFilter:
930*c8dee2aaSAndroid Build Coastguard Worker             return create_colorfilter_shader(rand, recorder);
931*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kCoordClamp:
932*c8dee2aaSAndroid Build Coastguard Worker             return create_coord_clamp_shader(rand, recorder);
933*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kConicalGradient:
934*c8dee2aaSAndroid Build Coastguard Worker             return create_gradient_shader(rand, SkShaderBase::GradientType::kConical);
935*c8dee2aaSAndroid Build Coastguard Worker //        case ShaderType::kEmpty:
936*c8dee2aaSAndroid Build Coastguard Worker //            return create_empty_shader(rand);
937*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kImage:
938*c8dee2aaSAndroid Build Coastguard Worker             return create_image_shader(rand, recorder);
939*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kLinearGradient:
940*c8dee2aaSAndroid Build Coastguard Worker             return create_gradient_shader(rand, SkShaderBase::GradientType::kLinear);
941*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kLocalMatrix:
942*c8dee2aaSAndroid Build Coastguard Worker             return create_localmatrix_shader(rand, recorder);
943*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kPerlinNoise:
944*c8dee2aaSAndroid Build Coastguard Worker             return create_perlin_noise_shader(rand);
945*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kPicture:
946*c8dee2aaSAndroid Build Coastguard Worker             return create_picture_shader(rand);
947*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kRadialGradient:
948*c8dee2aaSAndroid Build Coastguard Worker             return create_gradient_shader(rand, SkShaderBase::GradientType::kRadial);
949*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kRuntime:
950*c8dee2aaSAndroid Build Coastguard Worker             return create_runtime_shader(rand);
951*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kSolidColor:
952*c8dee2aaSAndroid Build Coastguard Worker             return create_solid_shader(rand);
953*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kSweepGradient:
954*c8dee2aaSAndroid Build Coastguard Worker             return create_gradient_shader(rand, SkShaderBase::GradientType::kSweep);
955*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kYUVImage:
956*c8dee2aaSAndroid Build Coastguard Worker             return create_yuv_image_shader(rand, recorder);
957*c8dee2aaSAndroid Build Coastguard Worker         case ShaderType::kWorkingColorSpace:
958*c8dee2aaSAndroid Build Coastguard Worker             return create_workingCS_shader(rand, recorder);
959*c8dee2aaSAndroid Build Coastguard Worker     }
960*c8dee2aaSAndroid Build Coastguard Worker 
961*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
962*c8dee2aaSAndroid Build Coastguard Worker }
963*c8dee2aaSAndroid Build Coastguard Worker 
create_random_shader(SkRandom * rand,Recorder * recorder)964*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_random_shader(SkRandom* rand,
965*c8dee2aaSAndroid Build Coastguard Worker                                                                          Recorder* recorder) {
966*c8dee2aaSAndroid Build Coastguard Worker     return create_shader(rand, recorder, random_shadertype(rand));
967*c8dee2aaSAndroid Build Coastguard Worker }
968*c8dee2aaSAndroid Build Coastguard Worker 
create_clip_shader(SkRandom * rand,Recorder * recorder)969*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkShader>, sk_sp<PrecompileShader>> create_clip_shader(SkRandom* rand,
970*c8dee2aaSAndroid Build Coastguard Worker                                                                        Recorder* recorder) {
971*c8dee2aaSAndroid Build Coastguard Worker     // The clip shader has to be transparent to be at all interesting.
972*c8dee2aaSAndroid Build Coastguard Worker     // TODO/Note: an opaque clipShader is eliminated from the SkPaint by the normal Skia API
973*c8dee2aaSAndroid Build Coastguard Worker     // but I'm unsure if we should bother capturing that possibility in the precompile system.
974*c8dee2aaSAndroid Build Coastguard Worker     switch (rand->nextULessThan(5)) {
975*c8dee2aaSAndroid Build Coastguard Worker         case 0: return create_gradient_shader(rand, SkShaderBase::GradientType::kConical,
976*c8dee2aaSAndroid Build Coastguard Worker                                               ColorConstraint::kTransparent);
977*c8dee2aaSAndroid Build Coastguard Worker         case 1: return create_gradient_shader(rand, SkShaderBase::GradientType::kLinear,
978*c8dee2aaSAndroid Build Coastguard Worker                                               ColorConstraint::kTransparent);
979*c8dee2aaSAndroid Build Coastguard Worker         case 2: return create_gradient_shader(rand, SkShaderBase::GradientType::kRadial,
980*c8dee2aaSAndroid Build Coastguard Worker                                               ColorConstraint::kTransparent);
981*c8dee2aaSAndroid Build Coastguard Worker         case 3: return create_solid_shader(rand, ColorConstraint::kTransparent);
982*c8dee2aaSAndroid Build Coastguard Worker         case 4: return create_gradient_shader(rand, SkShaderBase::GradientType::kSweep,
983*c8dee2aaSAndroid Build Coastguard Worker                                               ColorConstraint::kTransparent);
984*c8dee2aaSAndroid Build Coastguard Worker     }
985*c8dee2aaSAndroid Build Coastguard Worker 
986*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
987*c8dee2aaSAndroid Build Coastguard Worker }
988*c8dee2aaSAndroid Build Coastguard Worker 
989*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
src_blender()990*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> src_blender() {
991*c8dee2aaSAndroid Build Coastguard Worker     static SkRuntimeEffect* sSrcEffect = SkMakeRuntimeEffect(
992*c8dee2aaSAndroid Build Coastguard Worker             SkRuntimeEffect::MakeForBlender,
993*c8dee2aaSAndroid Build Coastguard Worker             "half4 main(half4 src, half4 dst) {"
994*c8dee2aaSAndroid Build Coastguard Worker                 "return src;"
995*c8dee2aaSAndroid Build Coastguard Worker             "}"
996*c8dee2aaSAndroid Build Coastguard Worker     );
997*c8dee2aaSAndroid Build Coastguard Worker 
998*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkBlender> b = sSrcEffect->makeBlender(/* uniforms= */ nullptr);
999*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileBlender> o =
1000*c8dee2aaSAndroid Build Coastguard Worker             PrecompileRuntimeEffects::MakePrecompileBlender(sk_ref_sp(sSrcEffect));
1001*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(b) , std::move(o) };
1002*c8dee2aaSAndroid Build Coastguard Worker }
1003*c8dee2aaSAndroid Build Coastguard Worker 
dest_blender()1004*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> dest_blender() {
1005*c8dee2aaSAndroid Build Coastguard Worker     static SkRuntimeEffect* sDestEffect = SkMakeRuntimeEffect(
1006*c8dee2aaSAndroid Build Coastguard Worker             SkRuntimeEffect::MakeForBlender,
1007*c8dee2aaSAndroid Build Coastguard Worker             "half4 main(half4 src, half4 dst) {"
1008*c8dee2aaSAndroid Build Coastguard Worker                 "return dst;"
1009*c8dee2aaSAndroid Build Coastguard Worker             "}"
1010*c8dee2aaSAndroid Build Coastguard Worker     );
1011*c8dee2aaSAndroid Build Coastguard Worker 
1012*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkBlender> b = sDestEffect->makeBlender(/* uniforms= */ nullptr);
1013*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileBlender> o =
1014*c8dee2aaSAndroid Build Coastguard Worker             PrecompileRuntimeEffects::MakePrecompileBlender(sk_ref_sp(sDestEffect));
1015*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(b) , std::move(o) };
1016*c8dee2aaSAndroid Build Coastguard Worker }
1017*c8dee2aaSAndroid Build Coastguard Worker 
1018*c8dee2aaSAndroid Build Coastguard Worker 
combo_blender()1019*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> combo_blender() {
1020*c8dee2aaSAndroid Build Coastguard Worker     static SkRuntimeEffect* sComboEffect = SkMakeRuntimeEffect(
1021*c8dee2aaSAndroid Build Coastguard Worker             SkRuntimeEffect::MakeForBlender,
1022*c8dee2aaSAndroid Build Coastguard Worker             "uniform float blendFrac;"
1023*c8dee2aaSAndroid Build Coastguard Worker             "uniform blender a;"
1024*c8dee2aaSAndroid Build Coastguard Worker             "uniform blender b;"
1025*c8dee2aaSAndroid Build Coastguard Worker             "half4 main(half4 src, half4 dst) {"
1026*c8dee2aaSAndroid Build Coastguard Worker                 "return (blendFrac * a.eval(src, dst)) + ((1 - blendFrac) * b.eval(src, dst));"
1027*c8dee2aaSAndroid Build Coastguard Worker             "}"
1028*c8dee2aaSAndroid Build Coastguard Worker     );
1029*c8dee2aaSAndroid Build Coastguard Worker 
1030*c8dee2aaSAndroid Build Coastguard Worker     auto [src, srcO] = src_blender();
1031*c8dee2aaSAndroid Build Coastguard Worker     auto [dst, dstO] = dest_blender();
1032*c8dee2aaSAndroid Build Coastguard Worker 
1033*c8dee2aaSAndroid Build Coastguard Worker     SkRuntimeEffect::ChildPtr children[] = { src, dst };
1034*c8dee2aaSAndroid Build Coastguard Worker 
1035*c8dee2aaSAndroid Build Coastguard Worker     const float kUniforms[] = { 1.0f };
1036*c8dee2aaSAndroid Build Coastguard Worker 
1037*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkData> uniforms = SkData::MakeWithCopy(kUniforms, sizeof(kUniforms));
1038*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkBlender> b = sComboEffect->makeBlender(std::move(uniforms), children);
1039*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileBlender> o = PrecompileRuntimeEffects::MakePrecompileBlender(
1040*c8dee2aaSAndroid Build Coastguard Worker             sk_ref_sp(sComboEffect),
1041*c8dee2aaSAndroid Build Coastguard Worker             { { srcO }, { dstO } });
1042*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(b) , std::move(o) };
1043*c8dee2aaSAndroid Build Coastguard Worker }
1044*c8dee2aaSAndroid Build Coastguard Worker 
create_bm_blender(SkRandom * rand,SkBlendMode bm)1045*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> create_bm_blender(SkRandom* rand,
1046*c8dee2aaSAndroid Build Coastguard Worker                                                                         SkBlendMode bm) {
1047*c8dee2aaSAndroid Build Coastguard Worker     return { SkBlender::Mode(bm), PrecompileBlenders::Mode(bm) };
1048*c8dee2aaSAndroid Build Coastguard Worker }
1049*c8dee2aaSAndroid Build Coastguard Worker 
create_arithmetic_blender()1050*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> create_arithmetic_blender() {
1051*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkBlender> b = SkBlenders::Arithmetic(/* k1= */ 0.5,
1052*c8dee2aaSAndroid Build Coastguard Worker                                                 /* k2= */ 0.5,
1053*c8dee2aaSAndroid Build Coastguard Worker                                                 /* k3= */ 0.5,
1054*c8dee2aaSAndroid Build Coastguard Worker                                                 /* k4= */ 0.5,
1055*c8dee2aaSAndroid Build Coastguard Worker                                                 /* enforcePremul= */ true);
1056*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileBlender> o = PrecompileBlenders::Arithmetic();
1057*c8dee2aaSAndroid Build Coastguard Worker 
1058*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(b), std::move(o) };
1059*c8dee2aaSAndroid Build Coastguard Worker }
1060*c8dee2aaSAndroid Build Coastguard Worker 
create_rt_blender(SkRandom * rand)1061*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> create_rt_blender(SkRandom* rand) {
1062*c8dee2aaSAndroid Build Coastguard Worker     int option = rand->nextULessThan(3);
1063*c8dee2aaSAndroid Build Coastguard Worker 
1064*c8dee2aaSAndroid Build Coastguard Worker     switch (option) {
1065*c8dee2aaSAndroid Build Coastguard Worker         case 0: return src_blender();
1066*c8dee2aaSAndroid Build Coastguard Worker         case 1: return dest_blender();
1067*c8dee2aaSAndroid Build Coastguard Worker         case 2: return combo_blender();
1068*c8dee2aaSAndroid Build Coastguard Worker     }
1069*c8dee2aaSAndroid Build Coastguard Worker 
1070*c8dee2aaSAndroid Build Coastguard Worker     return { nullptr, nullptr };
1071*c8dee2aaSAndroid Build Coastguard Worker }
1072*c8dee2aaSAndroid Build Coastguard Worker 
create_blender(SkRandom * rand,BlenderType type)1073*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> create_blender(SkRandom* rand,
1074*c8dee2aaSAndroid Build Coastguard Worker                                                                      BlenderType type) {
1075*c8dee2aaSAndroid Build Coastguard Worker     switch (type) {
1076*c8dee2aaSAndroid Build Coastguard Worker         case BlenderType::kNone:
1077*c8dee2aaSAndroid Build Coastguard Worker             return { nullptr, nullptr };
1078*c8dee2aaSAndroid Build Coastguard Worker         case BlenderType::kPorterDuff:
1079*c8dee2aaSAndroid Build Coastguard Worker             return create_bm_blender(rand, random_porter_duff_bm(rand));
1080*c8dee2aaSAndroid Build Coastguard Worker         case BlenderType::kShaderBased:
1081*c8dee2aaSAndroid Build Coastguard Worker             return create_bm_blender(rand, random_complex_bm(rand));
1082*c8dee2aaSAndroid Build Coastguard Worker         case BlenderType::kArithmetic:
1083*c8dee2aaSAndroid Build Coastguard Worker             return create_arithmetic_blender();
1084*c8dee2aaSAndroid Build Coastguard Worker         case BlenderType::kRuntime:
1085*c8dee2aaSAndroid Build Coastguard Worker             return create_rt_blender(rand);
1086*c8dee2aaSAndroid Build Coastguard Worker     }
1087*c8dee2aaSAndroid Build Coastguard Worker 
1088*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
1089*c8dee2aaSAndroid Build Coastguard Worker }
1090*c8dee2aaSAndroid Build Coastguard Worker 
create_random_blender(SkRandom * rand)1091*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkBlender>, sk_sp<PrecompileBlender>> create_random_blender(SkRandom* rand) {
1092*c8dee2aaSAndroid Build Coastguard Worker     return create_blender(rand, random_blendertype(rand));
1093*c8dee2aaSAndroid Build Coastguard Worker }
1094*c8dee2aaSAndroid Build Coastguard Worker 
1095*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
1096*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
double_colorfilter()1097*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> double_colorfilter() {
1098*c8dee2aaSAndroid Build Coastguard Worker     static SkRuntimeEffect* sSrcEffect = SkMakeRuntimeEffect(
1099*c8dee2aaSAndroid Build Coastguard Worker             SkRuntimeEffect::MakeForColorFilter,
1100*c8dee2aaSAndroid Build Coastguard Worker             "half4 main(half4 c) {"
1101*c8dee2aaSAndroid Build Coastguard Worker                 "return 2*c;"
1102*c8dee2aaSAndroid Build Coastguard Worker             "}"
1103*c8dee2aaSAndroid Build Coastguard Worker     );
1104*c8dee2aaSAndroid Build Coastguard Worker 
1105*c8dee2aaSAndroid Build Coastguard Worker     return { sSrcEffect->makeColorFilter(/* uniforms= */ nullptr),
1106*c8dee2aaSAndroid Build Coastguard Worker              PrecompileRuntimeEffects::MakePrecompileColorFilter(sk_ref_sp(sSrcEffect)) };
1107*c8dee2aaSAndroid Build Coastguard Worker }
1108*c8dee2aaSAndroid Build Coastguard Worker 
half_colorfilter()1109*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> half_colorfilter() {
1110*c8dee2aaSAndroid Build Coastguard Worker     static SkRuntimeEffect* sDestEffect = SkMakeRuntimeEffect(
1111*c8dee2aaSAndroid Build Coastguard Worker             SkRuntimeEffect::MakeForColorFilter,
1112*c8dee2aaSAndroid Build Coastguard Worker             "half4 main(half4 c) {"
1113*c8dee2aaSAndroid Build Coastguard Worker                 "return 0.5*c;"
1114*c8dee2aaSAndroid Build Coastguard Worker             "}"
1115*c8dee2aaSAndroid Build Coastguard Worker     );
1116*c8dee2aaSAndroid Build Coastguard Worker 
1117*c8dee2aaSAndroid Build Coastguard Worker     return { sDestEffect->makeColorFilter(/* uniforms= */ nullptr),
1118*c8dee2aaSAndroid Build Coastguard Worker              PrecompileRuntimeEffects::MakePrecompileColorFilter(sk_ref_sp(sDestEffect)) };
1119*c8dee2aaSAndroid Build Coastguard Worker }
1120*c8dee2aaSAndroid Build Coastguard Worker 
combo_colorfilter()1121*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> combo_colorfilter() {
1122*c8dee2aaSAndroid Build Coastguard Worker     static SkRuntimeEffect* sComboEffect = SkMakeRuntimeEffect(
1123*c8dee2aaSAndroid Build Coastguard Worker             SkRuntimeEffect::MakeForColorFilter,
1124*c8dee2aaSAndroid Build Coastguard Worker             "uniform float blendFrac;"
1125*c8dee2aaSAndroid Build Coastguard Worker             "uniform colorFilter a;"
1126*c8dee2aaSAndroid Build Coastguard Worker             "uniform colorFilter b;"
1127*c8dee2aaSAndroid Build Coastguard Worker             "half4 main(half4 c) {"
1128*c8dee2aaSAndroid Build Coastguard Worker                 "return (blendFrac * a.eval(c)) + ((1 - blendFrac) * b.eval(c));"
1129*c8dee2aaSAndroid Build Coastguard Worker             "}"
1130*c8dee2aaSAndroid Build Coastguard Worker     );
1131*c8dee2aaSAndroid Build Coastguard Worker 
1132*c8dee2aaSAndroid Build Coastguard Worker     auto [src, srcO] = double_colorfilter();
1133*c8dee2aaSAndroid Build Coastguard Worker     auto [dst, dstO] = half_colorfilter();
1134*c8dee2aaSAndroid Build Coastguard Worker 
1135*c8dee2aaSAndroid Build Coastguard Worker     SkRuntimeEffect::ChildPtr children[] = { src, dst };
1136*c8dee2aaSAndroid Build Coastguard Worker 
1137*c8dee2aaSAndroid Build Coastguard Worker     const float kUniforms[] = { 0.5f };
1138*c8dee2aaSAndroid Build Coastguard Worker 
1139*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkData> uniforms = SkData::MakeWithCopy(kUniforms, sizeof(kUniforms));
1140*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkColorFilter> cf = sComboEffect->makeColorFilter(std::move(uniforms), children);
1141*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileColorFilter> o =
1142*c8dee2aaSAndroid Build Coastguard Worker             PrecompileRuntimeEffects::MakePrecompileColorFilter(sk_ref_sp(sComboEffect),
1143*c8dee2aaSAndroid Build Coastguard Worker                                                                 { { srcO }, { dstO } });
1144*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(cf) , std::move(o) };
1145*c8dee2aaSAndroid Build Coastguard Worker }
1146*c8dee2aaSAndroid Build Coastguard Worker 
create_rt_colorfilter(SkRandom * rand)1147*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_rt_colorfilter(
1148*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1149*c8dee2aaSAndroid Build Coastguard Worker     int option = rand->nextULessThan(3);
1150*c8dee2aaSAndroid Build Coastguard Worker 
1151*c8dee2aaSAndroid Build Coastguard Worker     switch (option) {
1152*c8dee2aaSAndroid Build Coastguard Worker         case 0: return double_colorfilter();
1153*c8dee2aaSAndroid Build Coastguard Worker         case 1: return half_colorfilter();
1154*c8dee2aaSAndroid Build Coastguard Worker         case 2: return combo_colorfilter();
1155*c8dee2aaSAndroid Build Coastguard Worker     }
1156*c8dee2aaSAndroid Build Coastguard Worker 
1157*c8dee2aaSAndroid Build Coastguard Worker     return { nullptr, nullptr };
1158*c8dee2aaSAndroid Build Coastguard Worker }
1159*c8dee2aaSAndroid Build Coastguard Worker 
create_lerp_colorfilter(SkRandom * rand)1160*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_lerp_colorfilter(
1161*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1162*c8dee2aaSAndroid Build Coastguard Worker 
1163*c8dee2aaSAndroid Build Coastguard Worker     auto [dst, dstO] = create_random_colorfilter(rand);
1164*c8dee2aaSAndroid Build Coastguard Worker     auto [src, srcO] = create_random_colorfilter(rand);
1165*c8dee2aaSAndroid Build Coastguard Worker     // SkColorFilters::Lerp optimizes away the case where src == dst. I don't know if it is worth
1166*c8dee2aaSAndroid Build Coastguard Worker     // capturing it in the precompilation API
1167*c8dee2aaSAndroid Build Coastguard Worker     while (src == dst) {
1168*c8dee2aaSAndroid Build Coastguard Worker         std::tie(src, srcO) = create_random_colorfilter(rand);
1169*c8dee2aaSAndroid Build Coastguard Worker     }
1170*c8dee2aaSAndroid Build Coastguard Worker 
1171*c8dee2aaSAndroid Build Coastguard Worker     // TODO: SkColorFilters::Lerp will return a different colorFilter depending on the
1172*c8dee2aaSAndroid Build Coastguard Worker     // weight value and the child color filters. I don't know if that is worth capturing
1173*c8dee2aaSAndroid Build Coastguard Worker     // in the precompile API.
1174*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkColorFilter> cf = SkColorFilters::Lerp(0.5f, std::move(dst), std::move(src));
1175*c8dee2aaSAndroid Build Coastguard Worker 
1176*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileColorFilter> o = PrecompileColorFilters::Lerp({ dstO }, { srcO });
1177*c8dee2aaSAndroid Build Coastguard Worker 
1178*c8dee2aaSAndroid Build Coastguard Worker     return { cf, o };
1179*c8dee2aaSAndroid Build Coastguard Worker }
1180*c8dee2aaSAndroid Build Coastguard Worker 
create_lighting_colorfilter()1181*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_lighting_colorfilter() {
1182*c8dee2aaSAndroid Build Coastguard Worker     // TODO: the lighting color filter factory special cases when nothing is added and converts it
1183*c8dee2aaSAndroid Build Coastguard Worker     // to a blendmode color filter
1184*c8dee2aaSAndroid Build Coastguard Worker     return { SkColorFilters::Lighting(SK_ColorGREEN, SK_ColorRED),
1185*c8dee2aaSAndroid Build Coastguard Worker              PrecompileColorFilters::Lighting() };
1186*c8dee2aaSAndroid Build Coastguard Worker }
1187*c8dee2aaSAndroid Build Coastguard Worker 
create_blendmode_colorfilter(SkRandom * rand)1188*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_blendmode_colorfilter(
1189*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1190*c8dee2aaSAndroid Build Coastguard Worker 
1191*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkColorFilter> cf;
1192*c8dee2aaSAndroid Build Coastguard Worker 
1193*c8dee2aaSAndroid Build Coastguard Worker     // SkColorFilters::Blend is clever and can weed out noop color filters. Loop until we get
1194*c8dee2aaSAndroid Build Coastguard Worker     // a valid color filter.
1195*c8dee2aaSAndroid Build Coastguard Worker     SkBlendMode blend;
1196*c8dee2aaSAndroid Build Coastguard Worker     while (!cf) {
1197*c8dee2aaSAndroid Build Coastguard Worker         blend = random_blend_mode(rand);
1198*c8dee2aaSAndroid Build Coastguard Worker         cf = SkColorFilters::Blend(random_color4f(rand, ColorConstraint::kNone),
1199*c8dee2aaSAndroid Build Coastguard Worker                                    random_colorspace(rand),
1200*c8dee2aaSAndroid Build Coastguard Worker                                    blend);
1201*c8dee2aaSAndroid Build Coastguard Worker     }
1202*c8dee2aaSAndroid Build Coastguard Worker 
1203*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileColorFilter> o = PrecompileColorFilters::Blend({&blend, 1});
1204*c8dee2aaSAndroid Build Coastguard Worker 
1205*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(cf), std::move(o) };
1206*c8dee2aaSAndroid Build Coastguard Worker }
1207*c8dee2aaSAndroid Build Coastguard Worker 
create_matrix_colorfilter()1208*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_matrix_colorfilter() {
1209*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkColorFilter> cf = SkColorFilters::Matrix(
1210*c8dee2aaSAndroid Build Coastguard Worker             SkColorMatrix::RGBtoYUV(SkYUVColorSpace::kJPEG_Full_SkYUVColorSpace));
1211*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileColorFilter> o = PrecompileColorFilters::Matrix();
1212*c8dee2aaSAndroid Build Coastguard Worker 
1213*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(cf), std::move(o) };
1214*c8dee2aaSAndroid Build Coastguard Worker }
1215*c8dee2aaSAndroid Build Coastguard Worker 
create_color_space_colorfilter(SkRandom * rand)1216*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_color_space_colorfilter(
1217*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1218*c8dee2aaSAndroid Build Coastguard Worker     return { SkColorFilterPriv::MakeColorSpaceXform(random_colorspace(rand),
1219*c8dee2aaSAndroid Build Coastguard Worker                                                     random_colorspace(rand)),
1220*c8dee2aaSAndroid Build Coastguard Worker              PrecompileColorFiltersPriv::ColorSpaceXform() };
1221*c8dee2aaSAndroid Build Coastguard Worker }
1222*c8dee2aaSAndroid Build Coastguard Worker 
create_linear_to_srgb_colorfilter()1223*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_linear_to_srgb_colorfilter() {
1224*c8dee2aaSAndroid Build Coastguard Worker     return { SkColorFilters::LinearToSRGBGamma(), PrecompileColorFilters::LinearToSRGBGamma() };
1225*c8dee2aaSAndroid Build Coastguard Worker }
1226*c8dee2aaSAndroid Build Coastguard Worker 
create_srgb_to_linear_colorfilter()1227*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_srgb_to_linear_colorfilter() {
1228*c8dee2aaSAndroid Build Coastguard Worker     return { SkColorFilters::SRGBToLinearGamma(), PrecompileColorFilters::SRGBToLinearGamma() };
1229*c8dee2aaSAndroid Build Coastguard Worker }
1230*c8dee2aaSAndroid Build Coastguard Worker 
create_high_contrast_colorfilter()1231*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_high_contrast_colorfilter() {
1232*c8dee2aaSAndroid Build Coastguard Worker     SkHighContrastConfig config(/* grayscale= */ false,
1233*c8dee2aaSAndroid Build Coastguard Worker                                 SkHighContrastConfig::InvertStyle::kInvertBrightness,
1234*c8dee2aaSAndroid Build Coastguard Worker                                 /* contrast= */ 0.5f);
1235*c8dee2aaSAndroid Build Coastguard Worker     return { SkHighContrastFilter::Make(config), PrecompileColorFilters::HighContrast() };
1236*c8dee2aaSAndroid Build Coastguard Worker }
1237*c8dee2aaSAndroid Build Coastguard Worker 
create_luma_colorfilter()1238*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_luma_colorfilter() {
1239*c8dee2aaSAndroid Build Coastguard Worker     return { SkLumaColorFilter::Make(), PrecompileColorFilters::Luma() };
1240*c8dee2aaSAndroid Build Coastguard Worker }
1241*c8dee2aaSAndroid Build Coastguard Worker 
create_overdraw_colorfilter()1242*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_overdraw_colorfilter() {
1243*c8dee2aaSAndroid Build Coastguard Worker     // Black to red heat map gradation
1244*c8dee2aaSAndroid Build Coastguard Worker     static const SkColor kColors[SkOverdrawColorFilter::kNumColors] = {
1245*c8dee2aaSAndroid Build Coastguard Worker         SK_ColorBLACK,
1246*c8dee2aaSAndroid Build Coastguard Worker         SK_ColorBLUE,
1247*c8dee2aaSAndroid Build Coastguard Worker         SK_ColorCYAN,
1248*c8dee2aaSAndroid Build Coastguard Worker         SK_ColorGREEN,
1249*c8dee2aaSAndroid Build Coastguard Worker         SK_ColorYELLOW,
1250*c8dee2aaSAndroid Build Coastguard Worker         SK_ColorRED
1251*c8dee2aaSAndroid Build Coastguard Worker     };
1252*c8dee2aaSAndroid Build Coastguard Worker 
1253*c8dee2aaSAndroid Build Coastguard Worker     return { SkOverdrawColorFilter::MakeWithSkColors(kColors), PrecompileColorFilters::Overdraw() };
1254*c8dee2aaSAndroid Build Coastguard Worker }
1255*c8dee2aaSAndroid Build Coastguard Worker 
create_compose_colorfilter(SkRandom * rand)1256*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_compose_colorfilter(
1257*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1258*c8dee2aaSAndroid Build Coastguard Worker     auto [outerCF, outerO] = create_random_colorfilter(rand);
1259*c8dee2aaSAndroid Build Coastguard Worker     auto [innerCF, innerO] = create_random_colorfilter(rand);
1260*c8dee2aaSAndroid Build Coastguard Worker 
1261*c8dee2aaSAndroid Build Coastguard Worker     // TODO: if outerCF is null, innerCF will be returned by Compose. We need a Precompile
1262*c8dee2aaSAndroid Build Coastguard Worker     // list object that can encapsulate innerO if there are no combinations in outerO.
1263*c8dee2aaSAndroid Build Coastguard Worker     return { SkColorFilters::Compose(std::move(outerCF), std::move(innerCF)),
1264*c8dee2aaSAndroid Build Coastguard Worker              PrecompileColorFilters::Compose({ std::move(outerO) }, { std::move(innerO) }) };
1265*c8dee2aaSAndroid Build Coastguard Worker }
1266*c8dee2aaSAndroid Build Coastguard Worker 
create_gaussian_colorfilter()1267*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_gaussian_colorfilter() {
1268*c8dee2aaSAndroid Build Coastguard Worker     return { SkColorFilterPriv::MakeGaussian(), PrecompileColorFiltersPriv::Gaussian() };
1269*c8dee2aaSAndroid Build Coastguard Worker }
1270*c8dee2aaSAndroid Build Coastguard Worker 
create_table_colorfilter()1271*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_table_colorfilter() {
1272*c8dee2aaSAndroid Build Coastguard Worker     static constexpr uint8_t kTable[256] = { 0 };
1273*c8dee2aaSAndroid Build Coastguard Worker 
1274*c8dee2aaSAndroid Build Coastguard Worker     return { SkColorFilters::Table(kTable), PrecompileColorFilters::Table() };
1275*c8dee2aaSAndroid Build Coastguard Worker }
1276*c8dee2aaSAndroid Build Coastguard Worker 
create_workingformat_colorfilter(SkRandom * rand)1277*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_workingformat_colorfilter(
1278*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1279*c8dee2aaSAndroid Build Coastguard Worker     auto [childCF, childO] = create_random_colorfilter(rand);
1280*c8dee2aaSAndroid Build Coastguard Worker 
1281*c8dee2aaSAndroid Build Coastguard Worker     if (!childCF) {
1282*c8dee2aaSAndroid Build Coastguard Worker         return { nullptr, nullptr };
1283*c8dee2aaSAndroid Build Coastguard Worker     }
1284*c8dee2aaSAndroid Build Coastguard Worker 
1285*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(childCF && childO);
1286*c8dee2aaSAndroid Build Coastguard Worker 
1287*c8dee2aaSAndroid Build Coastguard Worker     SkAlphaType unpremul = kUnpremul_SkAlphaType;
1288*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkColorFilter> cf = SkColorFilterPriv::WithWorkingFormat(std::move(childCF),
1289*c8dee2aaSAndroid Build Coastguard Worker                                                                    &random_xfer_function(rand),
1290*c8dee2aaSAndroid Build Coastguard Worker                                                                    &random_gamut(rand),
1291*c8dee2aaSAndroid Build Coastguard Worker                                                                    &unpremul);
1292*c8dee2aaSAndroid Build Coastguard Worker 
1293*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileColorFilter> o = PrecompileColorFiltersPriv::WithWorkingFormat(
1294*c8dee2aaSAndroid Build Coastguard Worker             { std::move(childO) });
1295*c8dee2aaSAndroid Build Coastguard Worker 
1296*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(cf), std::move(o) };
1297*c8dee2aaSAndroid Build Coastguard Worker }
1298*c8dee2aaSAndroid Build Coastguard Worker 
create_hsla_matrix_colorfilter()1299*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_hsla_matrix_colorfilter() {
1300*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkColorFilter> cf = SkColorFilters::HSLAMatrix(
1301*c8dee2aaSAndroid Build Coastguard Worker             SkColorMatrix::RGBtoYUV(SkYUVColorSpace::kJPEG_Full_SkYUVColorSpace));
1302*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileColorFilter> o = PrecompileColorFilters::HSLAMatrix();
1303*c8dee2aaSAndroid Build Coastguard Worker 
1304*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(cf), std::move(o) };
1305*c8dee2aaSAndroid Build Coastguard Worker }
1306*c8dee2aaSAndroid Build Coastguard Worker 
create_colorfilter(SkRandom * rand,ColorFilterType type)1307*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_colorfilter(
1308*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand,
1309*c8dee2aaSAndroid Build Coastguard Worker         ColorFilterType type) {
1310*c8dee2aaSAndroid Build Coastguard Worker 
1311*c8dee2aaSAndroid Build Coastguard Worker     switch (type) {
1312*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kNone:
1313*c8dee2aaSAndroid Build Coastguard Worker             return { nullptr, nullptr };
1314*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kBlendMode:
1315*c8dee2aaSAndroid Build Coastguard Worker             return create_blendmode_colorfilter(rand);
1316*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kColorSpaceXform:
1317*c8dee2aaSAndroid Build Coastguard Worker             return create_color_space_colorfilter(rand);
1318*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kCompose:
1319*c8dee2aaSAndroid Build Coastguard Worker             return create_compose_colorfilter(rand);
1320*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kGaussian:
1321*c8dee2aaSAndroid Build Coastguard Worker             return create_gaussian_colorfilter();
1322*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kHighContrast:
1323*c8dee2aaSAndroid Build Coastguard Worker             return create_high_contrast_colorfilter();
1324*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kHSLAMatrix:
1325*c8dee2aaSAndroid Build Coastguard Worker             return create_hsla_matrix_colorfilter();
1326*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kLerp:
1327*c8dee2aaSAndroid Build Coastguard Worker             return create_lerp_colorfilter(rand);
1328*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kLighting:
1329*c8dee2aaSAndroid Build Coastguard Worker             return create_lighting_colorfilter();
1330*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kLinearToSRGB:
1331*c8dee2aaSAndroid Build Coastguard Worker             return create_linear_to_srgb_colorfilter();
1332*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kLuma:
1333*c8dee2aaSAndroid Build Coastguard Worker             return create_luma_colorfilter();
1334*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kMatrix:
1335*c8dee2aaSAndroid Build Coastguard Worker             return create_matrix_colorfilter();
1336*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kOverdraw:
1337*c8dee2aaSAndroid Build Coastguard Worker             return create_overdraw_colorfilter();
1338*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kRuntime:
1339*c8dee2aaSAndroid Build Coastguard Worker             return create_rt_colorfilter(rand);
1340*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kSRGBToLinear:
1341*c8dee2aaSAndroid Build Coastguard Worker             return create_srgb_to_linear_colorfilter();
1342*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kTable:
1343*c8dee2aaSAndroid Build Coastguard Worker             return create_table_colorfilter();
1344*c8dee2aaSAndroid Build Coastguard Worker         case ColorFilterType::kWorkingFormat:
1345*c8dee2aaSAndroid Build Coastguard Worker             return create_workingformat_colorfilter(rand);
1346*c8dee2aaSAndroid Build Coastguard Worker     }
1347*c8dee2aaSAndroid Build Coastguard Worker 
1348*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
1349*c8dee2aaSAndroid Build Coastguard Worker }
1350*c8dee2aaSAndroid Build Coastguard Worker 
create_random_colorfilter(SkRandom * rand)1351*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkColorFilter>, sk_sp<PrecompileColorFilter>> create_random_colorfilter(
1352*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1353*c8dee2aaSAndroid Build Coastguard Worker     return create_colorfilter(rand, random_colorfiltertype(rand));
1354*c8dee2aaSAndroid Build Coastguard Worker }
1355*c8dee2aaSAndroid Build Coastguard Worker 
1356*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
1357*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
arithmetic_imagefilter(SkRandom *)1358*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>> arithmetic_imagefilter(
1359*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* /* rand */) {
1360*c8dee2aaSAndroid Build Coastguard Worker 
1361*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImageFilter> arithmeticIF = SkImageFilters::Arithmetic(/* k1= */ 0.5f,
1362*c8dee2aaSAndroid Build Coastguard Worker                                                                    /* k2= */ 0.5f,
1363*c8dee2aaSAndroid Build Coastguard Worker                                                                    /* k3= */ 0.5f,
1364*c8dee2aaSAndroid Build Coastguard Worker                                                                    /* k4= */ 0.5f,
1365*c8dee2aaSAndroid Build Coastguard Worker                                                                    /* enforcePMColor= */ false,
1366*c8dee2aaSAndroid Build Coastguard Worker                                                                    /* background= */ nullptr,
1367*c8dee2aaSAndroid Build Coastguard Worker                                                                    /* foreground= */ nullptr);
1368*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileImageFilter> option = PrecompileImageFilters::Arithmetic(
1369*c8dee2aaSAndroid Build Coastguard Worker             /* background= */ nullptr,
1370*c8dee2aaSAndroid Build Coastguard Worker             /* foreground= */ nullptr);
1371*c8dee2aaSAndroid Build Coastguard Worker 
1372*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(arithmeticIF), std::move(option) };
1373*c8dee2aaSAndroid Build Coastguard Worker }
1374*c8dee2aaSAndroid Build Coastguard Worker 
blendmode_imagefilter(SkRandom * rand)1375*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>> blendmode_imagefilter(
1376*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1377*c8dee2aaSAndroid Build Coastguard Worker 
1378*c8dee2aaSAndroid Build Coastguard Worker     SkBlendMode bm = random_blend_mode(rand);
1379*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImageFilter> blendIF = SkImageFilters::Blend(bm,
1380*c8dee2aaSAndroid Build Coastguard Worker                                                          /* background= */ nullptr,
1381*c8dee2aaSAndroid Build Coastguard Worker                                                          /* foreground= */ nullptr);
1382*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileImageFilter> blendO = PrecompileImageFilters::Blend(
1383*c8dee2aaSAndroid Build Coastguard Worker             bm,
1384*c8dee2aaSAndroid Build Coastguard Worker             /* background= */ nullptr,
1385*c8dee2aaSAndroid Build Coastguard Worker             /* foreground= */ nullptr);
1386*c8dee2aaSAndroid Build Coastguard Worker 
1387*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(blendIF), std::move(blendO) };
1388*c8dee2aaSAndroid Build Coastguard Worker }
1389*c8dee2aaSAndroid Build Coastguard Worker 
runtime_blender_imagefilter(SkRandom * rand)1390*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>> runtime_blender_imagefilter(
1391*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1392*c8dee2aaSAndroid Build Coastguard Worker 
1393*c8dee2aaSAndroid Build Coastguard Worker     auto [blender, blenderO] = create_blender(rand, BlenderType::kRuntime);
1394*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImageFilter> blenderIF = SkImageFilters::Blend(std::move(blender),
1395*c8dee2aaSAndroid Build Coastguard Worker                                                            /* background= */ nullptr,
1396*c8dee2aaSAndroid Build Coastguard Worker                                                            /* foreground= */ nullptr);
1397*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileImageFilter> option = PrecompileImageFilters::Blend(std::move(blenderO),
1398*c8dee2aaSAndroid Build Coastguard Worker                                                                         /* background= */ nullptr,
1399*c8dee2aaSAndroid Build Coastguard Worker                                                                         /* foreground= */ nullptr);
1400*c8dee2aaSAndroid Build Coastguard Worker 
1401*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(blenderIF), std::move(option) };
1402*c8dee2aaSAndroid Build Coastguard Worker }
1403*c8dee2aaSAndroid Build Coastguard Worker 
blur_imagefilter(SkRandom * rand)1404*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>> blur_imagefilter(
1405*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1406*c8dee2aaSAndroid Build Coastguard Worker 
1407*c8dee2aaSAndroid Build Coastguard Worker     int option = rand->nextULessThan(3);
1408*c8dee2aaSAndroid Build Coastguard Worker 
1409*c8dee2aaSAndroid Build Coastguard Worker     float sigma;
1410*c8dee2aaSAndroid Build Coastguard Worker     switch (option) {
1411*c8dee2aaSAndroid Build Coastguard Worker         case 0:  sigma = 1.0f; break;  // 1DBlur4
1412*c8dee2aaSAndroid Build Coastguard Worker         case 1:  sigma = 2.0f; break;  // 1DBlur8
1413*c8dee2aaSAndroid Build Coastguard Worker         case 2:  [[fallthrough]];
1414*c8dee2aaSAndroid Build Coastguard Worker         default: sigma = 5.0f; break;  // 1DBlur16
1415*c8dee2aaSAndroid Build Coastguard Worker     }
1416*c8dee2aaSAndroid Build Coastguard Worker 
1417*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImageFilter> blurIF = SkImageFilters::Blur(sigma, sigma, /* input= */ nullptr);
1418*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileImageFilter> blurO = PrecompileImageFilters::Blur(/* input= */ nullptr);
1419*c8dee2aaSAndroid Build Coastguard Worker 
1420*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(blurIF), std::move(blurO) };
1421*c8dee2aaSAndroid Build Coastguard Worker }
1422*c8dee2aaSAndroid Build Coastguard Worker 
displacement_imagefilter(Recorder * recorder,SkRandom * rand)1423*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>> displacement_imagefilter(
1424*c8dee2aaSAndroid Build Coastguard Worker         Recorder* recorder,
1425*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1426*c8dee2aaSAndroid Build Coastguard Worker 
1427*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImage> checkerboard = ToolUtils::create_checkerboard_image(16, 16,
1428*c8dee2aaSAndroid Build Coastguard Worker                                                                        SK_ColorWHITE,
1429*c8dee2aaSAndroid Build Coastguard Worker                                                                        SK_ColorBLACK,
1430*c8dee2aaSAndroid Build Coastguard Worker                                                                        /* checkSize= */ 4);
1431*c8dee2aaSAndroid Build Coastguard Worker     checkerboard = SkImages::TextureFromImage(recorder, std::move(checkerboard), {false});
1432*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(checkerboard);
1433*c8dee2aaSAndroid Build Coastguard Worker 
1434*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImageFilter> imageIF(SkImageFilters::Image(std::move(checkerboard),
1435*c8dee2aaSAndroid Build Coastguard Worker                                                        SkFilterMode::kLinear));
1436*c8dee2aaSAndroid Build Coastguard Worker 
1437*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImageFilter> displacementIF;
1438*c8dee2aaSAndroid Build Coastguard Worker 
1439*c8dee2aaSAndroid Build Coastguard Worker     displacementIF = SkImageFilters::DisplacementMap(SkColorChannel::kR,
1440*c8dee2aaSAndroid Build Coastguard Worker                                                      SkColorChannel::kB,
1441*c8dee2aaSAndroid Build Coastguard Worker                                                      /* scale= */ 2.0f,
1442*c8dee2aaSAndroid Build Coastguard Worker                                                      /* displacement= */ std::move(imageIF),
1443*c8dee2aaSAndroid Build Coastguard Worker                                                      /* color= */ nullptr);
1444*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileImageFilter> option =
1445*c8dee2aaSAndroid Build Coastguard Worker             PrecompileImageFilters::DisplacementMap(/* input= */ nullptr);
1446*c8dee2aaSAndroid Build Coastguard Worker 
1447*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(displacementIF), std::move(option) };
1448*c8dee2aaSAndroid Build Coastguard Worker }
1449*c8dee2aaSAndroid Build Coastguard Worker 
colorfilter_imagefilter(SkRandom * rand)1450*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>> colorfilter_imagefilter(
1451*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1452*c8dee2aaSAndroid Build Coastguard Worker 
1453*c8dee2aaSAndroid Build Coastguard Worker     auto [cf, o] = create_random_colorfilter(rand);
1454*c8dee2aaSAndroid Build Coastguard Worker 
1455*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImageFilter> inputIF;
1456*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileImageFilter> inputO;
1457*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
1458*c8dee2aaSAndroid Build Coastguard Worker         // Exercise color filter collapsing in the factories
1459*c8dee2aaSAndroid Build Coastguard Worker         auto [cf2, o2] = create_random_colorfilter(rand);
1460*c8dee2aaSAndroid Build Coastguard Worker         inputIF = SkImageFilters::ColorFilter(std::move(cf2), /* input= */ nullptr);
1461*c8dee2aaSAndroid Build Coastguard Worker         inputO = PrecompileImageFilters::ColorFilter(std::move(o2), /* input= */ nullptr);
1462*c8dee2aaSAndroid Build Coastguard Worker     }
1463*c8dee2aaSAndroid Build Coastguard Worker 
1464*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImageFilter> cfIF = SkImageFilters::ColorFilter(std::move(cf), std::move(inputIF));
1465*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileImageFilter> cfIFO = PrecompileImageFilters::ColorFilter(std::move(o),
1466*c8dee2aaSAndroid Build Coastguard Worker                                                                              std::move(inputO));
1467*c8dee2aaSAndroid Build Coastguard Worker 
1468*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(cfIF), std::move(cfIFO) };
1469*c8dee2aaSAndroid Build Coastguard Worker }
1470*c8dee2aaSAndroid Build Coastguard Worker 
lighting_imagefilter(SkRandom * rand)1471*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>> lighting_imagefilter(
1472*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1473*c8dee2aaSAndroid Build Coastguard Worker     static constexpr SkPoint3 kLocation{10.0f, 2.0f, 30.0f};
1474*c8dee2aaSAndroid Build Coastguard Worker     static constexpr SkPoint3 kTarget{0, 0, 0};
1475*c8dee2aaSAndroid Build Coastguard Worker     static constexpr SkPoint3 kDirection{0, 1, 0};
1476*c8dee2aaSAndroid Build Coastguard Worker 
1477*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImageFilter> lightingIF;
1478*c8dee2aaSAndroid Build Coastguard Worker 
1479*c8dee2aaSAndroid Build Coastguard Worker     int option = rand->nextULessThan(6);
1480*c8dee2aaSAndroid Build Coastguard Worker     switch (option) {
1481*c8dee2aaSAndroid Build Coastguard Worker         case 0:
1482*c8dee2aaSAndroid Build Coastguard Worker             lightingIF = SkImageFilters::DistantLitDiffuse(kDirection, SK_ColorRED,
1483*c8dee2aaSAndroid Build Coastguard Worker                                                            /* surfaceScale= */ 1.0f,
1484*c8dee2aaSAndroid Build Coastguard Worker                                                            /* kd= */ 0.5f,
1485*c8dee2aaSAndroid Build Coastguard Worker                                                            /* input= */ nullptr);
1486*c8dee2aaSAndroid Build Coastguard Worker             break;
1487*c8dee2aaSAndroid Build Coastguard Worker         case 1:
1488*c8dee2aaSAndroid Build Coastguard Worker             lightingIF = SkImageFilters::PointLitDiffuse(kLocation, SK_ColorGREEN,
1489*c8dee2aaSAndroid Build Coastguard Worker                                                          /* surfaceScale= */ 1.0f,
1490*c8dee2aaSAndroid Build Coastguard Worker                                                          /* kd= */ 0.5f,
1491*c8dee2aaSAndroid Build Coastguard Worker                                                          /* input= */ nullptr);
1492*c8dee2aaSAndroid Build Coastguard Worker             break;
1493*c8dee2aaSAndroid Build Coastguard Worker         case 2:
1494*c8dee2aaSAndroid Build Coastguard Worker             lightingIF = SkImageFilters::SpotLitDiffuse(kLocation, kTarget,
1495*c8dee2aaSAndroid Build Coastguard Worker                                                         /* falloffExponent= */ 2.0f,
1496*c8dee2aaSAndroid Build Coastguard Worker                                                         /* cutoffAngle= */ 30.0f,
1497*c8dee2aaSAndroid Build Coastguard Worker                                                         SK_ColorBLUE,
1498*c8dee2aaSAndroid Build Coastguard Worker                                                         /* surfaceScale= */ 1.0f,
1499*c8dee2aaSAndroid Build Coastguard Worker                                                         /* kd= */ 0.5f,
1500*c8dee2aaSAndroid Build Coastguard Worker                                                         /* input= */ nullptr);
1501*c8dee2aaSAndroid Build Coastguard Worker             break;
1502*c8dee2aaSAndroid Build Coastguard Worker         case 3:
1503*c8dee2aaSAndroid Build Coastguard Worker             lightingIF = SkImageFilters::DistantLitSpecular(kDirection, SK_ColorCYAN,
1504*c8dee2aaSAndroid Build Coastguard Worker                                                             /* surfaceScale= */ 1.0f,
1505*c8dee2aaSAndroid Build Coastguard Worker                                                             /* ks= */ 0.5f,
1506*c8dee2aaSAndroid Build Coastguard Worker                                                             /* shininess= */ 2.0f,
1507*c8dee2aaSAndroid Build Coastguard Worker                                                             /* input= */ nullptr);
1508*c8dee2aaSAndroid Build Coastguard Worker             break;
1509*c8dee2aaSAndroid Build Coastguard Worker         case 4:
1510*c8dee2aaSAndroid Build Coastguard Worker             lightingIF = SkImageFilters::PointLitSpecular(kLocation, SK_ColorMAGENTA,
1511*c8dee2aaSAndroid Build Coastguard Worker                                                           /* surfaceScale= */ 1.0f,
1512*c8dee2aaSAndroid Build Coastguard Worker                                                           /* ks= */ 0.5f,
1513*c8dee2aaSAndroid Build Coastguard Worker                                                           /* shininess= */ 2.0f,
1514*c8dee2aaSAndroid Build Coastguard Worker                                                           /* input= */ nullptr);
1515*c8dee2aaSAndroid Build Coastguard Worker             break;
1516*c8dee2aaSAndroid Build Coastguard Worker         case 5:
1517*c8dee2aaSAndroid Build Coastguard Worker             lightingIF = SkImageFilters::SpotLitSpecular(kLocation, kTarget,
1518*c8dee2aaSAndroid Build Coastguard Worker                                                          /* falloffExponent= */ 2.0f,
1519*c8dee2aaSAndroid Build Coastguard Worker                                                          /* cutoffAngle= */ 30.0f,
1520*c8dee2aaSAndroid Build Coastguard Worker                                                          SK_ColorYELLOW,
1521*c8dee2aaSAndroid Build Coastguard Worker                                                          /* surfaceScale= */ 1.0f,
1522*c8dee2aaSAndroid Build Coastguard Worker                                                          /* ks= */ 4.0f,
1523*c8dee2aaSAndroid Build Coastguard Worker                                                          /* shininess= */ 0.5f,
1524*c8dee2aaSAndroid Build Coastguard Worker                                                          /* input= */ nullptr);
1525*c8dee2aaSAndroid Build Coastguard Worker             break;
1526*c8dee2aaSAndroid Build Coastguard Worker     }
1527*c8dee2aaSAndroid Build Coastguard Worker 
1528*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileImageFilter> lightingO = PrecompileImageFilters::Lighting(/* input= */ nullptr);
1529*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(lightingIF), std::move(lightingO) };
1530*c8dee2aaSAndroid Build Coastguard Worker }
1531*c8dee2aaSAndroid Build Coastguard Worker 
matrix_convolution_imagefilter(SkRandom * rand)1532*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>>  matrix_convolution_imagefilter(
1533*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1534*c8dee2aaSAndroid Build Coastguard Worker 
1535*c8dee2aaSAndroid Build Coastguard Worker     int kernelSize = 1;
1536*c8dee2aaSAndroid Build Coastguard Worker 
1537*c8dee2aaSAndroid Build Coastguard Worker     int option = rand->nextULessThan(3);
1538*c8dee2aaSAndroid Build Coastguard Worker     switch (option) {
1539*c8dee2aaSAndroid Build Coastguard Worker         case 0: kernelSize = 3;  break;
1540*c8dee2aaSAndroid Build Coastguard Worker         case 1: kernelSize = 7;  break;
1541*c8dee2aaSAndroid Build Coastguard Worker         case 2: kernelSize = 11; break;
1542*c8dee2aaSAndroid Build Coastguard Worker     }
1543*c8dee2aaSAndroid Build Coastguard Worker 
1544*c8dee2aaSAndroid Build Coastguard Worker     int center = (kernelSize * kernelSize - 1) / 2;
1545*c8dee2aaSAndroid Build Coastguard Worker     std::vector<float> kernel(kernelSize * kernelSize, SkIntToScalar(1));
1546*c8dee2aaSAndroid Build Coastguard Worker     kernel[center] = 2.0f - kernelSize * kernelSize;
1547*c8dee2aaSAndroid Build Coastguard Worker 
1548*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImageFilter> matrixConvIF;
1549*c8dee2aaSAndroid Build Coastguard Worker     matrixConvIF = SkImageFilters::MatrixConvolution({ kernelSize, kernelSize },
1550*c8dee2aaSAndroid Build Coastguard Worker                                                      /* kernel= */ kernel.data(),
1551*c8dee2aaSAndroid Build Coastguard Worker                                                      /* gain= */ 0.3f,
1552*c8dee2aaSAndroid Build Coastguard Worker                                                      /* bias= */ 100.0f,
1553*c8dee2aaSAndroid Build Coastguard Worker                                                      /* kernelOffset= */ { 1, 1 },
1554*c8dee2aaSAndroid Build Coastguard Worker                                                      SkTileMode::kMirror,
1555*c8dee2aaSAndroid Build Coastguard Worker                                                      /* convolveAlpha= */ false,
1556*c8dee2aaSAndroid Build Coastguard Worker                                                      /* input= */ nullptr);
1557*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(matrixConvIF);
1558*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileImageFilter> convOption = PrecompileImageFilters::MatrixConvolution(
1559*c8dee2aaSAndroid Build Coastguard Worker             /* input= */ nullptr);
1560*c8dee2aaSAndroid Build Coastguard Worker 
1561*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(matrixConvIF), std::move(convOption) };
1562*c8dee2aaSAndroid Build Coastguard Worker }
1563*c8dee2aaSAndroid Build Coastguard Worker 
morphology_imagefilter(SkRandom * rand)1564*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>> morphology_imagefilter(
1565*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1566*c8dee2aaSAndroid Build Coastguard Worker     static constexpr float kRadX = 2.0f, kRadY = 4.0f;
1567*c8dee2aaSAndroid Build Coastguard Worker 
1568*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImageFilter> morphologyIF;
1569*c8dee2aaSAndroid Build Coastguard Worker 
1570*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
1571*c8dee2aaSAndroid Build Coastguard Worker         morphologyIF = SkImageFilters::Erode(kRadX, kRadY, /* input= */ nullptr);
1572*c8dee2aaSAndroid Build Coastguard Worker     } else {
1573*c8dee2aaSAndroid Build Coastguard Worker         morphologyIF = SkImageFilters::Dilate(kRadX, kRadY, /* input= */ nullptr);
1574*c8dee2aaSAndroid Build Coastguard Worker     }
1575*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(morphologyIF);
1576*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileImageFilter> option = PrecompileImageFilters::Morphology(/* input= */ nullptr);
1577*c8dee2aaSAndroid Build Coastguard Worker 
1578*c8dee2aaSAndroid Build Coastguard Worker     return { std::move(morphologyIF), std::move(option) };
1579*c8dee2aaSAndroid Build Coastguard Worker }
1580*c8dee2aaSAndroid Build Coastguard Worker 
create_image_filter(Recorder * recorder,SkRandom * rand,ImageFilterType type)1581*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>> create_image_filter(
1582*c8dee2aaSAndroid Build Coastguard Worker         Recorder* recorder,
1583*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand,
1584*c8dee2aaSAndroid Build Coastguard Worker         ImageFilterType type) {
1585*c8dee2aaSAndroid Build Coastguard Worker 
1586*c8dee2aaSAndroid Build Coastguard Worker     switch (type) {
1587*c8dee2aaSAndroid Build Coastguard Worker         case ImageFilterType::kNone:
1588*c8dee2aaSAndroid Build Coastguard Worker             return {};
1589*c8dee2aaSAndroid Build Coastguard Worker         case ImageFilterType::kArithmetic:
1590*c8dee2aaSAndroid Build Coastguard Worker             return arithmetic_imagefilter(rand);
1591*c8dee2aaSAndroid Build Coastguard Worker         case ImageFilterType::kBlendMode:
1592*c8dee2aaSAndroid Build Coastguard Worker             return blendmode_imagefilter(rand);
1593*c8dee2aaSAndroid Build Coastguard Worker         case ImageFilterType::kRuntimeBlender:
1594*c8dee2aaSAndroid Build Coastguard Worker             return runtime_blender_imagefilter(rand);
1595*c8dee2aaSAndroid Build Coastguard Worker         case ImageFilterType::kBlur:
1596*c8dee2aaSAndroid Build Coastguard Worker             return blur_imagefilter(rand);
1597*c8dee2aaSAndroid Build Coastguard Worker         case ImageFilterType::kColorFilter:
1598*c8dee2aaSAndroid Build Coastguard Worker             return colorfilter_imagefilter(rand);
1599*c8dee2aaSAndroid Build Coastguard Worker         case ImageFilterType::kDisplacement:
1600*c8dee2aaSAndroid Build Coastguard Worker             return displacement_imagefilter(recorder, rand);
1601*c8dee2aaSAndroid Build Coastguard Worker         case ImageFilterType::kLighting:
1602*c8dee2aaSAndroid Build Coastguard Worker             return lighting_imagefilter(rand);
1603*c8dee2aaSAndroid Build Coastguard Worker         case ImageFilterType::kMatrixConvolution:
1604*c8dee2aaSAndroid Build Coastguard Worker             return matrix_convolution_imagefilter(rand);
1605*c8dee2aaSAndroid Build Coastguard Worker         case ImageFilterType::kMorphology:
1606*c8dee2aaSAndroid Build Coastguard Worker             return morphology_imagefilter(rand);
1607*c8dee2aaSAndroid Build Coastguard Worker     }
1608*c8dee2aaSAndroid Build Coastguard Worker 
1609*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
1610*c8dee2aaSAndroid Build Coastguard Worker }
1611*c8dee2aaSAndroid Build Coastguard Worker 
create_random_image_filter(Recorder * recorder,SkRandom * rand)1612*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkImageFilter>, sk_sp<PrecompileImageFilter>> create_random_image_filter(
1613*c8dee2aaSAndroid Build Coastguard Worker         Recorder* recorder,
1614*c8dee2aaSAndroid Build Coastguard Worker         SkRandom* rand) {
1615*c8dee2aaSAndroid Build Coastguard Worker     return create_image_filter(recorder, rand, random_imagefiltertype(rand));
1616*c8dee2aaSAndroid Build Coastguard Worker }
1617*c8dee2aaSAndroid Build Coastguard Worker 
create_blur_maskfilter(SkRandom * rand)1618*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkMaskFilter>, sk_sp<PrecompileMaskFilter>> create_blur_maskfilter(SkRandom* rand) {
1619*c8dee2aaSAndroid Build Coastguard Worker     SkBlurStyle style;
1620*c8dee2aaSAndroid Build Coastguard Worker     switch (rand->nextULessThan(4)) {
1621*c8dee2aaSAndroid Build Coastguard Worker         case 0:  style = kNormal_SkBlurStyle; break;
1622*c8dee2aaSAndroid Build Coastguard Worker         case 1:  style = kSolid_SkBlurStyle;  break;
1623*c8dee2aaSAndroid Build Coastguard Worker         case 2:  style = kOuter_SkBlurStyle;  break;
1624*c8dee2aaSAndroid Build Coastguard Worker         case 3:  [[fallthrough]];
1625*c8dee2aaSAndroid Build Coastguard Worker         default: style = kInner_SkBlurStyle;  break;
1626*c8dee2aaSAndroid Build Coastguard Worker     }
1627*c8dee2aaSAndroid Build Coastguard Worker 
1628*c8dee2aaSAndroid Build Coastguard Worker     float sigma = 1.0f;
1629*c8dee2aaSAndroid Build Coastguard Worker     switch (rand->nextULessThan(2)) {
1630*c8dee2aaSAndroid Build Coastguard Worker         case 0:  sigma = 1.0f; break;
1631*c8dee2aaSAndroid Build Coastguard Worker         case 1:  sigma = 2.0f; break;
1632*c8dee2aaSAndroid Build Coastguard Worker         case 2:  [[fallthrough]];
1633*c8dee2aaSAndroid Build Coastguard Worker         default: sigma = 5.0f; break;
1634*c8dee2aaSAndroid Build Coastguard Worker     }
1635*c8dee2aaSAndroid Build Coastguard Worker 
1636*c8dee2aaSAndroid Build Coastguard Worker     bool respectCTM = rand->nextBool();
1637*c8dee2aaSAndroid Build Coastguard Worker 
1638*c8dee2aaSAndroid Build Coastguard Worker     return { SkMaskFilter::MakeBlur(style, sigma, respectCTM), PrecompileMaskFilters::Blur() };
1639*c8dee2aaSAndroid Build Coastguard Worker }
1640*c8dee2aaSAndroid Build Coastguard Worker 
create_maskfilter(SkRandom * rand,MaskFilterType type)1641*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<SkMaskFilter>, sk_sp<PrecompileMaskFilter>> create_maskfilter(SkRandom* rand,
1642*c8dee2aaSAndroid Build Coastguard Worker                                                                               MaskFilterType type) {
1643*c8dee2aaSAndroid Build Coastguard Worker     switch (type) {
1644*c8dee2aaSAndroid Build Coastguard Worker         case MaskFilterType::kNone: return {nullptr, nullptr};
1645*c8dee2aaSAndroid Build Coastguard Worker         case MaskFilterType::kBlur: return create_blur_maskfilter(rand);
1646*c8dee2aaSAndroid Build Coastguard Worker     }
1647*c8dee2aaSAndroid Build Coastguard Worker 
1648*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
1649*c8dee2aaSAndroid Build Coastguard Worker }
1650*c8dee2aaSAndroid Build Coastguard Worker 
1651*c8dee2aaSAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
create_paint(SkRandom * rand,Recorder * recorder,ShaderType shaderType,BlenderType blenderType,ColorFilterType colorFilterType,MaskFilterType maskFilterType,ImageFilterType imageFilterType)1652*c8dee2aaSAndroid Build Coastguard Worker std::pair<SkPaint, PaintOptions> create_paint(SkRandom* rand,
1653*c8dee2aaSAndroid Build Coastguard Worker                                               Recorder* recorder,
1654*c8dee2aaSAndroid Build Coastguard Worker                                               ShaderType shaderType,
1655*c8dee2aaSAndroid Build Coastguard Worker                                               BlenderType blenderType,
1656*c8dee2aaSAndroid Build Coastguard Worker                                               ColorFilterType colorFilterType,
1657*c8dee2aaSAndroid Build Coastguard Worker                                               MaskFilterType maskFilterType,
1658*c8dee2aaSAndroid Build Coastguard Worker                                               ImageFilterType imageFilterType) {
1659*c8dee2aaSAndroid Build Coastguard Worker     SkPaint paint;
1660*c8dee2aaSAndroid Build Coastguard Worker     paint.setColor(random_color(rand, ColorConstraint::kOpaque));
1661*c8dee2aaSAndroid Build Coastguard Worker 
1662*c8dee2aaSAndroid Build Coastguard Worker     PaintOptions paintOptions;
1663*c8dee2aaSAndroid Build Coastguard Worker 
1664*c8dee2aaSAndroid Build Coastguard Worker     {
1665*c8dee2aaSAndroid Build Coastguard Worker         auto [s, o] = create_shader(rand, recorder, shaderType);
1666*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!s == !o);
1667*c8dee2aaSAndroid Build Coastguard Worker 
1668*c8dee2aaSAndroid Build Coastguard Worker         if (s) {
1669*c8dee2aaSAndroid Build Coastguard Worker             paint.setShader(std::move(s));
1670*c8dee2aaSAndroid Build Coastguard Worker             paintOptions.setShaders({o});
1671*c8dee2aaSAndroid Build Coastguard Worker         }
1672*c8dee2aaSAndroid Build Coastguard Worker     }
1673*c8dee2aaSAndroid Build Coastguard Worker 
1674*c8dee2aaSAndroid Build Coastguard Worker     {
1675*c8dee2aaSAndroid Build Coastguard Worker         auto [cf, o] = create_colorfilter(rand, colorFilterType);
1676*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!cf == !o);
1677*c8dee2aaSAndroid Build Coastguard Worker 
1678*c8dee2aaSAndroid Build Coastguard Worker         if (cf) {
1679*c8dee2aaSAndroid Build Coastguard Worker             paint.setColorFilter(std::move(cf));
1680*c8dee2aaSAndroid Build Coastguard Worker             paintOptions.setColorFilters({o});
1681*c8dee2aaSAndroid Build Coastguard Worker         }
1682*c8dee2aaSAndroid Build Coastguard Worker     }
1683*c8dee2aaSAndroid Build Coastguard Worker 
1684*c8dee2aaSAndroid Build Coastguard Worker     {
1685*c8dee2aaSAndroid Build Coastguard Worker         auto [mf, o] = create_maskfilter(rand, maskFilterType);
1686*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!mf == !o);
1687*c8dee2aaSAndroid Build Coastguard Worker 
1688*c8dee2aaSAndroid Build Coastguard Worker         if (mf) {
1689*c8dee2aaSAndroid Build Coastguard Worker             paint.setMaskFilter(std::move(mf));
1690*c8dee2aaSAndroid Build Coastguard Worker             paintOptions.setMaskFilters({o});
1691*c8dee2aaSAndroid Build Coastguard Worker         }
1692*c8dee2aaSAndroid Build Coastguard Worker     }
1693*c8dee2aaSAndroid Build Coastguard Worker 
1694*c8dee2aaSAndroid Build Coastguard Worker     {
1695*c8dee2aaSAndroid Build Coastguard Worker         auto [b, o] = create_blender(rand, blenderType);
1696*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!b == !o);
1697*c8dee2aaSAndroid Build Coastguard Worker 
1698*c8dee2aaSAndroid Build Coastguard Worker         if (b) {
1699*c8dee2aaSAndroid Build Coastguard Worker             paint.setBlender(std::move(b));
1700*c8dee2aaSAndroid Build Coastguard Worker             paintOptions.setBlenders({o});
1701*c8dee2aaSAndroid Build Coastguard Worker         }
1702*c8dee2aaSAndroid Build Coastguard Worker     }
1703*c8dee2aaSAndroid Build Coastguard Worker 
1704*c8dee2aaSAndroid Build Coastguard Worker     {
1705*c8dee2aaSAndroid Build Coastguard Worker         auto [filter, o] = create_image_filter(recorder, rand, imageFilterType);
1706*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!filter == !o);
1707*c8dee2aaSAndroid Build Coastguard Worker 
1708*c8dee2aaSAndroid Build Coastguard Worker         if (filter) {
1709*c8dee2aaSAndroid Build Coastguard Worker             paint.setImageFilter(std::move(filter));
1710*c8dee2aaSAndroid Build Coastguard Worker             paintOptions.setImageFilters({o});
1711*c8dee2aaSAndroid Build Coastguard Worker         }
1712*c8dee2aaSAndroid Build Coastguard Worker     }
1713*c8dee2aaSAndroid Build Coastguard Worker 
1714*c8dee2aaSAndroid Build Coastguard Worker     if (rand->nextBool()) {
1715*c8dee2aaSAndroid Build Coastguard Worker         paint.setDither(true);
1716*c8dee2aaSAndroid Build Coastguard Worker         paintOptions.setDither(true);
1717*c8dee2aaSAndroid Build Coastguard Worker     }
1718*c8dee2aaSAndroid Build Coastguard Worker 
1719*c8dee2aaSAndroid Build Coastguard Worker     return { paint, paintOptions };
1720*c8dee2aaSAndroid Build Coastguard Worker }
1721*c8dee2aaSAndroid Build Coastguard Worker 
make_path()1722*c8dee2aaSAndroid Build Coastguard Worker SkPath make_path() {
1723*c8dee2aaSAndroid Build Coastguard Worker     SkPathBuilder path;
1724*c8dee2aaSAndroid Build Coastguard Worker     path.moveTo(0, 0);
1725*c8dee2aaSAndroid Build Coastguard Worker     path.lineTo(8, 2);
1726*c8dee2aaSAndroid Build Coastguard Worker     path.lineTo(16, 0);
1727*c8dee2aaSAndroid Build Coastguard Worker     path.lineTo(14, 8);
1728*c8dee2aaSAndroid Build Coastguard Worker     path.lineTo(16, 16);
1729*c8dee2aaSAndroid Build Coastguard Worker     path.lineTo(8, 14);
1730*c8dee2aaSAndroid Build Coastguard Worker     path.lineTo(0, 16);
1731*c8dee2aaSAndroid Build Coastguard Worker     path.lineTo(2, 8);
1732*c8dee2aaSAndroid Build Coastguard Worker     path.close();
1733*c8dee2aaSAndroid Build Coastguard Worker     return path.detach();
1734*c8dee2aaSAndroid Build Coastguard Worker }
1735*c8dee2aaSAndroid Build Coastguard Worker 
1736*c8dee2aaSAndroid Build Coastguard Worker struct DrawData {
DrawData__anon74e4dc3c0111::DrawData1737*c8dee2aaSAndroid Build Coastguard Worker     DrawData() {
1738*c8dee2aaSAndroid Build Coastguard Worker         static constexpr int kMaskTextFontSize = 16;
1739*c8dee2aaSAndroid Build Coastguard Worker         // A large font size can bump text to be drawn as a path.
1740*c8dee2aaSAndroid Build Coastguard Worker         static constexpr int kPathTextFontSize = 300;
1741*c8dee2aaSAndroid Build Coastguard Worker 
1742*c8dee2aaSAndroid Build Coastguard Worker         SkFont font(ToolUtils::DefaultPortableTypeface(), kMaskTextFontSize);
1743*c8dee2aaSAndroid Build Coastguard Worker 
1744*c8dee2aaSAndroid Build Coastguard Worker         SkFont lcdFont(ToolUtils::DefaultPortableTypeface(), kMaskTextFontSize);
1745*c8dee2aaSAndroid Build Coastguard Worker         lcdFont.setSubpixel(true);
1746*c8dee2aaSAndroid Build Coastguard Worker         lcdFont.setEdging(SkFont::Edging::kSubpixelAntiAlias);
1747*c8dee2aaSAndroid Build Coastguard Worker 
1748*c8dee2aaSAndroid Build Coastguard Worker         ToolUtils::EmojiTestSample emojiTestSample =
1749*c8dee2aaSAndroid Build Coastguard Worker                 ToolUtils::EmojiSample(ToolUtils::EmojiFontFormat::ColrV0);
1750*c8dee2aaSAndroid Build Coastguard Worker         SkFont emojiFont(emojiTestSample.typeface);
1751*c8dee2aaSAndroid Build Coastguard Worker 
1752*c8dee2aaSAndroid Build Coastguard Worker         SkFont pathFont(ToolUtils::DefaultPortableTypeface(), kPathTextFontSize);
1753*c8dee2aaSAndroid Build Coastguard Worker 
1754*c8dee2aaSAndroid Build Coastguard Worker         const char text[] = "hambur1";
1755*c8dee2aaSAndroid Build Coastguard Worker 
1756*c8dee2aaSAndroid Build Coastguard Worker         constexpr int kNumVerts = 4;
1757*c8dee2aaSAndroid Build Coastguard Worker         constexpr SkPoint kPositions[kNumVerts] { { 0, 0 }, { 0, 16 }, { 16, 16 }, { 16, 0 } };
1758*c8dee2aaSAndroid Build Coastguard Worker         constexpr SkColor kColors[kNumVerts] = { SK_ColorBLUE, SK_ColorGREEN,
1759*c8dee2aaSAndroid Build Coastguard Worker                                                  SK_ColorCYAN, SK_ColorYELLOW };
1760*c8dee2aaSAndroid Build Coastguard Worker 
1761*c8dee2aaSAndroid Build Coastguard Worker         fPath = make_path();
1762*c8dee2aaSAndroid Build Coastguard Worker         fBlob = SkTextBlob::MakeFromText(text, strlen(text), font);
1763*c8dee2aaSAndroid Build Coastguard Worker         fLCDBlob = SkTextBlob::MakeFromText(text, strlen(text), lcdFont);
1764*c8dee2aaSAndroid Build Coastguard Worker         fEmojiBlob = SkTextBlob::MakeFromText(emojiTestSample.sampleText,
1765*c8dee2aaSAndroid Build Coastguard Worker                                               strlen(emojiTestSample.sampleText),
1766*c8dee2aaSAndroid Build Coastguard Worker                                               emojiFont);
1767*c8dee2aaSAndroid Build Coastguard Worker         fPathBlob = SkTextBlob::MakeFromText(text, strlen(text), pathFont);
1768*c8dee2aaSAndroid Build Coastguard Worker 
1769*c8dee2aaSAndroid Build Coastguard Worker         fVertsWithColors = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode, kNumVerts,
1770*c8dee2aaSAndroid Build Coastguard Worker                                                 kPositions, kPositions, kColors);
1771*c8dee2aaSAndroid Build Coastguard Worker         fVertsWithOutColors = SkVertices::MakeCopy(SkVertices::kTriangleFan_VertexMode, kNumVerts,
1772*c8dee2aaSAndroid Build Coastguard Worker                                                    kPositions, kPositions, /* colors= */ nullptr);
1773*c8dee2aaSAndroid Build Coastguard Worker     }
1774*c8dee2aaSAndroid Build Coastguard Worker 
1775*c8dee2aaSAndroid Build Coastguard Worker     SkPath fPath;
1776*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkTextBlob> fBlob;
1777*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkTextBlob> fLCDBlob;
1778*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkTextBlob> fEmojiBlob;
1779*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkTextBlob> fPathBlob;
1780*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkVertices> fVertsWithColors;
1781*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkVertices> fVertsWithOutColors;
1782*c8dee2aaSAndroid Build Coastguard Worker };
1783*c8dee2aaSAndroid Build Coastguard Worker 
simple_draws(SkCanvas * canvas,const SkPaint & paint)1784*c8dee2aaSAndroid Build Coastguard Worker void simple_draws(SkCanvas* canvas, const SkPaint& paint) {
1785*c8dee2aaSAndroid Build Coastguard Worker     // TODO: add some drawLine calls
1786*c8dee2aaSAndroid Build Coastguard Worker     canvas->drawRect(SkRect::MakeWH(16, 16), paint);
1787*c8dee2aaSAndroid Build Coastguard Worker     canvas->drawRRect(SkRRect::MakeOval({0, 0, 16, 16}), paint);
1788*c8dee2aaSAndroid Build Coastguard Worker     canvas->drawRRect(SkRRect::MakeRectXY({0, 0, 16, 16}, 4, 4), paint);
1789*c8dee2aaSAndroid Build Coastguard Worker     canvas->drawArc({0, 0, 16, 16}, 0, 90, /* useCenter= */ false, paint);
1790*c8dee2aaSAndroid Build Coastguard Worker     if (paint.getStyle() == SkPaint::kFill_Style) {
1791*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawArc({0, 0, 16, 16}, 0, 90, /* useCenter= */ true, paint);
1792*c8dee2aaSAndroid Build Coastguard Worker     }
1793*c8dee2aaSAndroid Build Coastguard Worker 
1794*c8dee2aaSAndroid Build Coastguard Worker     // TODO: add a case that uses the SkCanvas::experimental_DrawEdgeAAImageSet entry point
1795*c8dee2aaSAndroid Build Coastguard Worker     if (!paint.getShader() &&
1796*c8dee2aaSAndroid Build Coastguard Worker         !paint.getColorFilter() &&
1797*c8dee2aaSAndroid Build Coastguard Worker         !paint.getImageFilter() &&
1798*c8dee2aaSAndroid Build Coastguard Worker         paint.asBlendMode().has_value()) {
1799*c8dee2aaSAndroid Build Coastguard Worker         // The SkPaint reconstructed inside the drawEdgeAAQuad call needs to match 'paint' for
1800*c8dee2aaSAndroid Build Coastguard Worker         // the precompilation checks to work.
1801*c8dee2aaSAndroid Build Coastguard Worker         canvas->experimental_DrawEdgeAAQuad(SkRect::MakeWH(16, 16),
1802*c8dee2aaSAndroid Build Coastguard Worker                                             /* clip= */ nullptr,
1803*c8dee2aaSAndroid Build Coastguard Worker                                             SkCanvas::kAll_QuadAAFlags,
1804*c8dee2aaSAndroid Build Coastguard Worker                                             paint.getColor4f(),
1805*c8dee2aaSAndroid Build Coastguard Worker                                             paint.asBlendMode().value());
1806*c8dee2aaSAndroid Build Coastguard Worker     }
1807*c8dee2aaSAndroid Build Coastguard Worker }
1808*c8dee2aaSAndroid Build Coastguard Worker 
non_simple_draws(SkCanvas * canvas,const SkPaint & paint,const DrawData & drawData)1809*c8dee2aaSAndroid Build Coastguard Worker void non_simple_draws(SkCanvas* canvas, const SkPaint& paint, const DrawData& drawData) {
1810*c8dee2aaSAndroid Build Coastguard Worker     // TODO: add strokeAndFill draws here as well as a stroked non-circular rrect draw
1811*c8dee2aaSAndroid Build Coastguard Worker     canvas->drawPath(drawData.fPath, paint);
1812*c8dee2aaSAndroid Build Coastguard Worker     canvas->drawTextBlob(drawData.fPathBlob, 0, 16, paint);
1813*c8dee2aaSAndroid Build Coastguard Worker     if (paint.getStyle() == SkPaint::kStroke_Style) {
1814*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawArc({0, 0, 16, 16}, 0, 90, /* useCenter= */ true, paint);
1815*c8dee2aaSAndroid Build Coastguard Worker     }
1816*c8dee2aaSAndroid Build Coastguard Worker }
1817*c8dee2aaSAndroid Build Coastguard Worker 
1818*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
dump_keys(PrecompileContext * precompileContext,const std::vector<skgpu::UniqueKey> & needleKeys,const std::vector<skgpu::UniqueKey> & hayStackKeys,const char * needleName,const char * haystackName)1819*c8dee2aaSAndroid Build Coastguard Worker void dump_keys(PrecompileContext* precompileContext,
1820*c8dee2aaSAndroid Build Coastguard Worker                const std::vector<skgpu::UniqueKey>& needleKeys,
1821*c8dee2aaSAndroid Build Coastguard Worker                const std::vector<skgpu::UniqueKey>& hayStackKeys,
1822*c8dee2aaSAndroid Build Coastguard Worker                const char* needleName,
1823*c8dee2aaSAndroid Build Coastguard Worker                const char* haystackName) {
1824*c8dee2aaSAndroid Build Coastguard Worker 
1825*c8dee2aaSAndroid Build Coastguard Worker     SkDebugf("-------------------------- %zu %s pipelines\n", needleKeys.size(), needleName);
1826*c8dee2aaSAndroid Build Coastguard Worker 
1827*c8dee2aaSAndroid Build Coastguard Worker     int count = 0;
1828*c8dee2aaSAndroid Build Coastguard Worker     for (const skgpu::UniqueKey& k : needleKeys) {
1829*c8dee2aaSAndroid Build Coastguard Worker         bool found = std::find(hayStackKeys.begin(), hayStackKeys.end(), k) != hayStackKeys.end();
1830*c8dee2aaSAndroid Build Coastguard Worker 
1831*c8dee2aaSAndroid Build Coastguard Worker         GraphicsPipelineDesc originalPipelineDesc;
1832*c8dee2aaSAndroid Build Coastguard Worker         RenderPassDesc originalRenderPassDesc;
1833*c8dee2aaSAndroid Build Coastguard Worker         UniqueKeyUtils::ExtractKeyDescs(precompileContext, k,
1834*c8dee2aaSAndroid Build Coastguard Worker                                         &originalPipelineDesc,
1835*c8dee2aaSAndroid Build Coastguard Worker                                         &originalRenderPassDesc);
1836*c8dee2aaSAndroid Build Coastguard Worker 
1837*c8dee2aaSAndroid Build Coastguard Worker         SkString label;
1838*c8dee2aaSAndroid Build Coastguard Worker         label.appendf("--- %s key %d (%s in %s):\n",
1839*c8dee2aaSAndroid Build Coastguard Worker                       needleName, count++, found ? "found" : "not-found", haystackName);
1840*c8dee2aaSAndroid Build Coastguard Worker         k.dump(label.c_str());
1841*c8dee2aaSAndroid Build Coastguard Worker         UniqueKeyUtils::DumpDescs(precompileContext,
1842*c8dee2aaSAndroid Build Coastguard Worker                                   originalPipelineDesc,
1843*c8dee2aaSAndroid Build Coastguard Worker                                   originalRenderPassDesc);
1844*c8dee2aaSAndroid Build Coastguard Worker     }
1845*c8dee2aaSAndroid Build Coastguard Worker }
1846*c8dee2aaSAndroid Build Coastguard Worker #endif
1847*c8dee2aaSAndroid Build Coastguard Worker 
check_draw(skiatest::Reporter * reporter,Context * context,PrecompileContext * precompileContext,skiatest::graphite::GraphiteTestContext * testContext,Recorder * recorder,const SkPaint & paint,DrawTypeFlags dt,ClipType clip,sk_sp<SkShader> clipShader)1848*c8dee2aaSAndroid Build Coastguard Worker void check_draw(skiatest::Reporter* reporter,
1849*c8dee2aaSAndroid Build Coastguard Worker                 Context* context,
1850*c8dee2aaSAndroid Build Coastguard Worker                 PrecompileContext* precompileContext,
1851*c8dee2aaSAndroid Build Coastguard Worker                 skiatest::graphite::GraphiteTestContext* testContext,
1852*c8dee2aaSAndroid Build Coastguard Worker                 Recorder* recorder,
1853*c8dee2aaSAndroid Build Coastguard Worker                 const SkPaint& paint,
1854*c8dee2aaSAndroid Build Coastguard Worker                 DrawTypeFlags dt,
1855*c8dee2aaSAndroid Build Coastguard Worker                 ClipType clip,
1856*c8dee2aaSAndroid Build Coastguard Worker                 sk_sp<SkShader> clipShader) {
1857*c8dee2aaSAndroid Build Coastguard Worker     static const DrawData kDrawData;
1858*c8dee2aaSAndroid Build Coastguard Worker 
1859*c8dee2aaSAndroid Build Coastguard Worker     std::vector<skgpu::UniqueKey> precompileKeys, drawKeys;
1860*c8dee2aaSAndroid Build Coastguard Worker 
1861*c8dee2aaSAndroid Build Coastguard Worker     UniqueKeyUtils::FetchUniqueKeys(precompileContext, &precompileKeys);
1862*c8dee2aaSAndroid Build Coastguard Worker 
1863*c8dee2aaSAndroid Build Coastguard Worker     precompileContext->priv().globalCache()->resetGraphicsPipelines();
1864*c8dee2aaSAndroid Build Coastguard Worker 
1865*c8dee2aaSAndroid Build Coastguard Worker     {
1866*c8dee2aaSAndroid Build Coastguard Worker         // TODO: vary the colorType of the target surface too
1867*c8dee2aaSAndroid Build Coastguard Worker         SkImageInfo ii = SkImageInfo::Make(16, 16,
1868*c8dee2aaSAndroid Build Coastguard Worker                                            kBGRA_8888_SkColorType,
1869*c8dee2aaSAndroid Build Coastguard Worker                                            kPremul_SkAlphaType);
1870*c8dee2aaSAndroid Build Coastguard Worker 
1871*c8dee2aaSAndroid Build Coastguard Worker         SkSurfaceProps props;
1872*c8dee2aaSAndroid Build Coastguard Worker 
1873*c8dee2aaSAndroid Build Coastguard Worker         if (dt == DrawTypeFlags::kBitmapText_LCD || dt == DrawTypeFlags::kSDFText_LCD) {
1874*c8dee2aaSAndroid Build Coastguard Worker             props = SkSurfaceProps(/* flags= */ 0x0, SkPixelGeometry::kRGB_H_SkPixelGeometry);
1875*c8dee2aaSAndroid Build Coastguard Worker         }
1876*c8dee2aaSAndroid Build Coastguard Worker 
1877*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> surf = SkSurfaces::RenderTarget(recorder, ii,
1878*c8dee2aaSAndroid Build Coastguard Worker                                                          skgpu::Mipmapped::kNo,
1879*c8dee2aaSAndroid Build Coastguard Worker                                                          &props);
1880*c8dee2aaSAndroid Build Coastguard Worker         SkCanvas* canvas = surf->getCanvas();
1881*c8dee2aaSAndroid Build Coastguard Worker 
1882*c8dee2aaSAndroid Build Coastguard Worker         switch (clip) {
1883*c8dee2aaSAndroid Build Coastguard Worker             case ClipType::kNone:
1884*c8dee2aaSAndroid Build Coastguard Worker                 break;
1885*c8dee2aaSAndroid Build Coastguard Worker             case ClipType::kShader:
1886*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(clipShader);
1887*c8dee2aaSAndroid Build Coastguard Worker                 canvas->clipShader(clipShader, SkClipOp::kIntersect);
1888*c8dee2aaSAndroid Build Coastguard Worker                 break;
1889*c8dee2aaSAndroid Build Coastguard Worker             case ClipType::kShader_Diff:
1890*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(clipShader);
1891*c8dee2aaSAndroid Build Coastguard Worker                 canvas->clipShader(clipShader, SkClipOp::kDifference);
1892*c8dee2aaSAndroid Build Coastguard Worker                 break;
1893*c8dee2aaSAndroid Build Coastguard Worker         }
1894*c8dee2aaSAndroid Build Coastguard Worker 
1895*c8dee2aaSAndroid Build Coastguard Worker         switch (dt) {
1896*c8dee2aaSAndroid Build Coastguard Worker             case DrawTypeFlags::kBitmapText_Mask:
1897*c8dee2aaSAndroid Build Coastguard Worker                 canvas->drawTextBlob(kDrawData.fBlob, 0, 16, paint);
1898*c8dee2aaSAndroid Build Coastguard Worker                 break;
1899*c8dee2aaSAndroid Build Coastguard Worker             case DrawTypeFlags::kBitmapText_LCD:
1900*c8dee2aaSAndroid Build Coastguard Worker                 canvas->drawTextBlob(kDrawData.fLCDBlob, 0, 16, paint);
1901*c8dee2aaSAndroid Build Coastguard Worker                 break;
1902*c8dee2aaSAndroid Build Coastguard Worker             case DrawTypeFlags::kBitmapText_Color:
1903*c8dee2aaSAndroid Build Coastguard Worker                 canvas->drawTextBlob(kDrawData.fEmojiBlob, 0, 16, paint);
1904*c8dee2aaSAndroid Build Coastguard Worker                 break;
1905*c8dee2aaSAndroid Build Coastguard Worker             case DrawTypeFlags::kSDFText: {
1906*c8dee2aaSAndroid Build Coastguard Worker                 SkMatrix perspective;
1907*c8dee2aaSAndroid Build Coastguard Worker                 perspective.setPerspX(0.01f);
1908*c8dee2aaSAndroid Build Coastguard Worker                 perspective.setPerspY(0.001f);
1909*c8dee2aaSAndroid Build Coastguard Worker                 canvas->save();
1910*c8dee2aaSAndroid Build Coastguard Worker                 canvas->concat(perspective);
1911*c8dee2aaSAndroid Build Coastguard Worker                 canvas->drawTextBlob(kDrawData.fBlob, 0, 16, paint);
1912*c8dee2aaSAndroid Build Coastguard Worker                 canvas->restore();
1913*c8dee2aaSAndroid Build Coastguard Worker             } break;
1914*c8dee2aaSAndroid Build Coastguard Worker             case DrawTypeFlags::kSDFText_LCD: {
1915*c8dee2aaSAndroid Build Coastguard Worker                 SkMatrix perspective;
1916*c8dee2aaSAndroid Build Coastguard Worker                 perspective.setPerspX(0.01f);
1917*c8dee2aaSAndroid Build Coastguard Worker                 perspective.setPerspY(0.001f);
1918*c8dee2aaSAndroid Build Coastguard Worker                 canvas->save();
1919*c8dee2aaSAndroid Build Coastguard Worker                 canvas->concat(perspective);
1920*c8dee2aaSAndroid Build Coastguard Worker                 canvas->drawTextBlob(kDrawData.fLCDBlob, 0, 16, paint);
1921*c8dee2aaSAndroid Build Coastguard Worker                 canvas->restore();
1922*c8dee2aaSAndroid Build Coastguard Worker             } break;
1923*c8dee2aaSAndroid Build Coastguard Worker             case DrawTypeFlags::kDrawVertices:
1924*c8dee2aaSAndroid Build Coastguard Worker                 canvas->drawVertices(kDrawData.fVertsWithColors, SkBlendMode::kDst, paint);
1925*c8dee2aaSAndroid Build Coastguard Worker                 canvas->drawVertices(kDrawData.fVertsWithOutColors, SkBlendMode::kDst, paint);
1926*c8dee2aaSAndroid Build Coastguard Worker                 break;
1927*c8dee2aaSAndroid Build Coastguard Worker             case DrawTypeFlags::kSimpleShape:
1928*c8dee2aaSAndroid Build Coastguard Worker                 simple_draws(canvas, paint);
1929*c8dee2aaSAndroid Build Coastguard Worker                 break;
1930*c8dee2aaSAndroid Build Coastguard Worker             case DrawTypeFlags::kNonSimpleShape:
1931*c8dee2aaSAndroid Build Coastguard Worker                 non_simple_draws(canvas, paint, kDrawData);
1932*c8dee2aaSAndroid Build Coastguard Worker                 break;
1933*c8dee2aaSAndroid Build Coastguard Worker             default:
1934*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(false);
1935*c8dee2aaSAndroid Build Coastguard Worker                 break;
1936*c8dee2aaSAndroid Build Coastguard Worker         }
1937*c8dee2aaSAndroid Build Coastguard Worker 
1938*c8dee2aaSAndroid Build Coastguard Worker         std::unique_ptr<skgpu::graphite::Recording> recording = recorder->snap();
1939*c8dee2aaSAndroid Build Coastguard Worker         context->insertRecording({ recording.get() });
1940*c8dee2aaSAndroid Build Coastguard Worker         testContext->syncedSubmit(context);
1941*c8dee2aaSAndroid Build Coastguard Worker     }
1942*c8dee2aaSAndroid Build Coastguard Worker 
1943*c8dee2aaSAndroid Build Coastguard Worker     UniqueKeyUtils::FetchUniqueKeys(precompileContext, &drawKeys);
1944*c8dee2aaSAndroid Build Coastguard Worker 
1945*c8dee2aaSAndroid Build Coastguard Worker     // Actually using the SkPaint with the specified type of draw shouldn't have added
1946*c8dee2aaSAndroid Build Coastguard Worker     // any additional pipelines
1947*c8dee2aaSAndroid Build Coastguard Worker     int missingPipelines = 0;
1948*c8dee2aaSAndroid Build Coastguard Worker     for (const skgpu::UniqueKey& k : drawKeys) {
1949*c8dee2aaSAndroid Build Coastguard Worker         bool found =
1950*c8dee2aaSAndroid Build Coastguard Worker                 std::find(precompileKeys.begin(), precompileKeys.end(), k) != precompileKeys.end();
1951*c8dee2aaSAndroid Build Coastguard Worker         if (!found) {
1952*c8dee2aaSAndroid Build Coastguard Worker             ++missingPipelines;
1953*c8dee2aaSAndroid Build Coastguard Worker         }
1954*c8dee2aaSAndroid Build Coastguard Worker     }
1955*c8dee2aaSAndroid Build Coastguard Worker 
1956*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, missingPipelines == 0,
1957*c8dee2aaSAndroid Build Coastguard Worker                     "precompile pipelines: %zu draw pipelines: %zu - %d missing from precompile",
1958*c8dee2aaSAndroid Build Coastguard Worker                     precompileKeys.size(), drawKeys.size(), missingPipelines);
1959*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
1960*c8dee2aaSAndroid Build Coastguard Worker     if (missingPipelines) {
1961*c8dee2aaSAndroid Build Coastguard Worker         dump_keys(precompileContext, drawKeys, precompileKeys, "draw", "precompile");
1962*c8dee2aaSAndroid Build Coastguard Worker         dump_keys(precompileContext, precompileKeys, drawKeys, "precompile", "draw");
1963*c8dee2aaSAndroid Build Coastguard Worker     }
1964*c8dee2aaSAndroid Build Coastguard Worker #endif // SK_DEBUG
1965*c8dee2aaSAndroid Build Coastguard Worker 
1966*c8dee2aaSAndroid Build Coastguard Worker }
1967*c8dee2aaSAndroid Build Coastguard Worker 
create_key_context(Context * context,RuntimeEffectDictionary * rtDict)1968*c8dee2aaSAndroid Build Coastguard Worker KeyContext create_key_context(Context* context, RuntimeEffectDictionary* rtDict) {
1969*c8dee2aaSAndroid Build Coastguard Worker     ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
1970*c8dee2aaSAndroid Build Coastguard Worker 
1971*c8dee2aaSAndroid Build Coastguard Worker     SkColorInfo destColorInfo = SkColorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType,
1972*c8dee2aaSAndroid Build Coastguard Worker                                             SkColorSpace::MakeSRGB());
1973*c8dee2aaSAndroid Build Coastguard Worker     return KeyContext(context->priv().caps(),
1974*c8dee2aaSAndroid Build Coastguard Worker                       dict,
1975*c8dee2aaSAndroid Build Coastguard Worker                       rtDict,
1976*c8dee2aaSAndroid Build Coastguard Worker                       destColorInfo);
1977*c8dee2aaSAndroid Build Coastguard Worker }
1978*c8dee2aaSAndroid Build Coastguard Worker 
1979*c8dee2aaSAndroid Build Coastguard Worker // This subtest compares the output of ExtractPaintData (applied to an SkPaint) and
1980*c8dee2aaSAndroid Build Coastguard Worker // PaintOptions::buildCombinations (applied to a matching PaintOptions). The actual check
1981*c8dee2aaSAndroid Build Coastguard Worker // performed is that the UniquePaintParamsID created by ExtractPaintData is contained in the
1982*c8dee2aaSAndroid Build Coastguard Worker // set of IDs generated by buildCombinations.
1983*c8dee2aaSAndroid Build Coastguard Worker [[maybe_unused]]
extract_vs_build_subtest(skiatest::Reporter * reporter,Context * context,skiatest::graphite::GraphiteTestContext *,const KeyContext & precompileKeyContext,Recorder * recorder,const SkPaint & paint,const PaintOptions & paintOptions,ShaderType s,BlenderType bm,ColorFilterType cf,MaskFilterType mf,ImageFilterType imageFilter,ClipType clip,sk_sp<SkShader> clipShader,DrawTypeFlags dt,uint32_t seed,SkRandom * rand,bool verbose)1984*c8dee2aaSAndroid Build Coastguard Worker void extract_vs_build_subtest(skiatest::Reporter* reporter,
1985*c8dee2aaSAndroid Build Coastguard Worker                               Context* context,
1986*c8dee2aaSAndroid Build Coastguard Worker                               skiatest::graphite::GraphiteTestContext* /* testContext */,
1987*c8dee2aaSAndroid Build Coastguard Worker                               const KeyContext& precompileKeyContext,
1988*c8dee2aaSAndroid Build Coastguard Worker                               Recorder* recorder,
1989*c8dee2aaSAndroid Build Coastguard Worker                               const SkPaint& paint,
1990*c8dee2aaSAndroid Build Coastguard Worker                               const PaintOptions& paintOptions,
1991*c8dee2aaSAndroid Build Coastguard Worker                               ShaderType s,
1992*c8dee2aaSAndroid Build Coastguard Worker                               BlenderType bm,
1993*c8dee2aaSAndroid Build Coastguard Worker                               ColorFilterType cf,
1994*c8dee2aaSAndroid Build Coastguard Worker                               MaskFilterType mf,
1995*c8dee2aaSAndroid Build Coastguard Worker                               ImageFilterType imageFilter,
1996*c8dee2aaSAndroid Build Coastguard Worker                               ClipType clip,
1997*c8dee2aaSAndroid Build Coastguard Worker                               sk_sp<SkShader> clipShader,
1998*c8dee2aaSAndroid Build Coastguard Worker                               DrawTypeFlags dt,
1999*c8dee2aaSAndroid Build Coastguard Worker                               uint32_t seed,
2000*c8dee2aaSAndroid Build Coastguard Worker                               SkRandom* rand,
2001*c8dee2aaSAndroid Build Coastguard Worker                               bool verbose) {
2002*c8dee2aaSAndroid Build Coastguard Worker 
2003*c8dee2aaSAndroid Build Coastguard Worker     ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
2004*c8dee2aaSAndroid Build Coastguard Worker 
2005*c8dee2aaSAndroid Build Coastguard Worker     PaintParamsKeyBuilder builder(dict);
2006*c8dee2aaSAndroid Build Coastguard Worker     PipelineDataGatherer paramsGatherer(Layout::kMetal);
2007*c8dee2aaSAndroid Build Coastguard Worker     PipelineDataGatherer precompileGatherer(Layout::kMetal);
2008*c8dee2aaSAndroid Build Coastguard Worker 
2009*c8dee2aaSAndroid Build Coastguard Worker     for (bool withPrimitiveBlender: {false, true}) {
2010*c8dee2aaSAndroid Build Coastguard Worker 
2011*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkBlender> primitiveBlender;
2012*c8dee2aaSAndroid Build Coastguard Worker         if (withPrimitiveBlender) {
2013*c8dee2aaSAndroid Build Coastguard Worker             if (dt != DrawTypeFlags::kDrawVertices) {
2014*c8dee2aaSAndroid Build Coastguard Worker                 // Only drawVertices calls need a primitive blender
2015*c8dee2aaSAndroid Build Coastguard Worker                 continue;
2016*c8dee2aaSAndroid Build Coastguard Worker             }
2017*c8dee2aaSAndroid Build Coastguard Worker 
2018*c8dee2aaSAndroid Build Coastguard Worker             primitiveBlender = SkBlender::Mode(SkBlendMode::kSrcOver);
2019*c8dee2aaSAndroid Build Coastguard Worker         }
2020*c8dee2aaSAndroid Build Coastguard Worker 
2021*c8dee2aaSAndroid Build Coastguard Worker         constexpr Coverage coverageOptions[3] = {
2022*c8dee2aaSAndroid Build Coastguard Worker                 Coverage::kNone, Coverage::kSingleChannel, Coverage::kLCD
2023*c8dee2aaSAndroid Build Coastguard Worker         };
2024*c8dee2aaSAndroid Build Coastguard Worker         Coverage coverage = coverageOptions[rand->nextULessThan(3)];
2025*c8dee2aaSAndroid Build Coastguard Worker 
2026*c8dee2aaSAndroid Build Coastguard Worker         DstReadRequirement dstReadReq = DstReadRequirement::kNone;
2027*c8dee2aaSAndroid Build Coastguard Worker         const SkBlenderBase* blender = as_BB(paint.getBlender());
2028*c8dee2aaSAndroid Build Coastguard Worker         if (blender) {
2029*c8dee2aaSAndroid Build Coastguard Worker             dstReadReq = GetDstReadRequirement(recorder->priv().caps(),
2030*c8dee2aaSAndroid Build Coastguard Worker                                                blender->asBlendMode(),
2031*c8dee2aaSAndroid Build Coastguard Worker                                                coverage);
2032*c8dee2aaSAndroid Build Coastguard Worker         }
2033*c8dee2aaSAndroid Build Coastguard Worker 
2034*c8dee2aaSAndroid Build Coastguard Worker         // In the normal API this modification happens in SkDevice::clipShader()
2035*c8dee2aaSAndroid Build Coastguard Worker         // All clipShaders get wrapped in a CTMShader
2036*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkShader> modifiedClipShader = clipShader
2037*c8dee2aaSAndroid Build Coastguard Worker                                              ? as_SB(clipShader)->makeWithCTM(SkMatrix::I())
2038*c8dee2aaSAndroid Build Coastguard Worker                                              : nullptr;
2039*c8dee2aaSAndroid Build Coastguard Worker         if (clip == ClipType::kShader_Diff && modifiedClipShader) {
2040*c8dee2aaSAndroid Build Coastguard Worker             // The CTMShader gets further wrapped in a ColorFilterShader for kDifference clips
2041*c8dee2aaSAndroid Build Coastguard Worker             modifiedClipShader = modifiedClipShader->makeWithColorFilter(
2042*c8dee2aaSAndroid Build Coastguard Worker                     SkColorFilters::Blend(0xFFFFFFFF, SkBlendMode::kSrcOut));
2043*c8dee2aaSAndroid Build Coastguard Worker         }
2044*c8dee2aaSAndroid Build Coastguard Worker 
2045*c8dee2aaSAndroid Build Coastguard Worker         UniquePaintParamsID paintID =
2046*c8dee2aaSAndroid Build Coastguard Worker                 ExtractPaintData(recorder,
2047*c8dee2aaSAndroid Build Coastguard Worker                                  &paramsGatherer,
2048*c8dee2aaSAndroid Build Coastguard Worker                                  &builder,
2049*c8dee2aaSAndroid Build Coastguard Worker                                  Layout::kMetal,
2050*c8dee2aaSAndroid Build Coastguard Worker                                  {},
2051*c8dee2aaSAndroid Build Coastguard Worker                                  PaintParams(paint,
2052*c8dee2aaSAndroid Build Coastguard Worker                                              primitiveBlender,
2053*c8dee2aaSAndroid Build Coastguard Worker                                              {}, // TODO (jvanverth): add analytic clip to test
2054*c8dee2aaSAndroid Build Coastguard Worker                                              std::move(modifiedClipShader),
2055*c8dee2aaSAndroid Build Coastguard Worker                                              dstReadReq,
2056*c8dee2aaSAndroid Build Coastguard Worker                                              /* skipColorXform= */ false),
2057*c8dee2aaSAndroid Build Coastguard Worker                                  {},
2058*c8dee2aaSAndroid Build Coastguard Worker                                  precompileKeyContext.dstColorInfo());
2059*c8dee2aaSAndroid Build Coastguard Worker 
2060*c8dee2aaSAndroid Build Coastguard Worker         RenderPassDesc unusedRenderPassDesc;
2061*c8dee2aaSAndroid Build Coastguard Worker 
2062*c8dee2aaSAndroid Build Coastguard Worker         std::vector<UniquePaintParamsID> precompileIDs;
2063*c8dee2aaSAndroid Build Coastguard Worker         paintOptions.priv().buildCombinations(precompileKeyContext,
2064*c8dee2aaSAndroid Build Coastguard Worker                                               &precompileGatherer,
2065*c8dee2aaSAndroid Build Coastguard Worker                                               DrawTypeFlags::kNone,
2066*c8dee2aaSAndroid Build Coastguard Worker                                               withPrimitiveBlender,
2067*c8dee2aaSAndroid Build Coastguard Worker                                               coverage,
2068*c8dee2aaSAndroid Build Coastguard Worker                                               unusedRenderPassDesc,
2069*c8dee2aaSAndroid Build Coastguard Worker                                               [&precompileIDs](UniquePaintParamsID id,
2070*c8dee2aaSAndroid Build Coastguard Worker                                                                DrawTypeFlags,
2071*c8dee2aaSAndroid Build Coastguard Worker                                                                bool /* withPrimitiveBlender */,
2072*c8dee2aaSAndroid Build Coastguard Worker                                                                Coverage,
2073*c8dee2aaSAndroid Build Coastguard Worker                                                                const RenderPassDesc&) {
2074*c8dee2aaSAndroid Build Coastguard Worker                                                   precompileIDs.push_back(id);
2075*c8dee2aaSAndroid Build Coastguard Worker                                               });
2076*c8dee2aaSAndroid Build Coastguard Worker 
2077*c8dee2aaSAndroid Build Coastguard Worker         if (verbose) {
2078*c8dee2aaSAndroid Build Coastguard Worker             SkDebugf("Precompilation generated %zu unique keys\n", precompileIDs.size());
2079*c8dee2aaSAndroid Build Coastguard Worker         }
2080*c8dee2aaSAndroid Build Coastguard Worker 
2081*c8dee2aaSAndroid Build Coastguard Worker         // Although we've gathered both sets of uniforms (i.e., from the paint
2082*c8dee2aaSAndroid Build Coastguard Worker         // params and the precompilation paths) we can't compare the two since the
2083*c8dee2aaSAndroid Build Coastguard Worker         // precompilation path may have generated multiple sets
2084*c8dee2aaSAndroid Build Coastguard Worker         // and the last one created may not be the one that matches the paint
2085*c8dee2aaSAndroid Build Coastguard Worker         // params' set. Additionally, for runtime effects we just skip gathering
2086*c8dee2aaSAndroid Build Coastguard Worker         // the uniforms in the precompilation path.
2087*c8dee2aaSAndroid Build Coastguard Worker 
2088*c8dee2aaSAndroid Build Coastguard Worker         // The specific key generated by ExtractPaintData should be one of the
2089*c8dee2aaSAndroid Build Coastguard Worker         // combinations generated by the combination system.
2090*c8dee2aaSAndroid Build Coastguard Worker         auto result = std::find(precompileIDs.begin(), precompileIDs.end(), paintID);
2091*c8dee2aaSAndroid Build Coastguard Worker 
2092*c8dee2aaSAndroid Build Coastguard Worker         if (result == precompileIDs.end()) {
2093*c8dee2aaSAndroid Build Coastguard Worker             log_run("Failure on case", seed, s, bm, cf, mf, imageFilter, clip, dt);
2094*c8dee2aaSAndroid Build Coastguard Worker         }
2095*c8dee2aaSAndroid Build Coastguard Worker 
2096*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
2097*c8dee2aaSAndroid Build Coastguard Worker         if (result == precompileIDs.end()) {
2098*c8dee2aaSAndroid Build Coastguard Worker             SkDebugf("From paint: ");
2099*c8dee2aaSAndroid Build Coastguard Worker             dict->dump(paintID);
2100*c8dee2aaSAndroid Build Coastguard Worker 
2101*c8dee2aaSAndroid Build Coastguard Worker             SkDebugf("From combination builder [%d]:", static_cast<int>(precompileIDs.size()));
2102*c8dee2aaSAndroid Build Coastguard Worker             for (auto iter: precompileIDs) {
2103*c8dee2aaSAndroid Build Coastguard Worker                 dict->dump(iter);
2104*c8dee2aaSAndroid Build Coastguard Worker             }
2105*c8dee2aaSAndroid Build Coastguard Worker         }
2106*c8dee2aaSAndroid Build Coastguard Worker #endif
2107*c8dee2aaSAndroid Build Coastguard Worker 
2108*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, result != precompileIDs.end());
2109*c8dee2aaSAndroid Build Coastguard Worker     }
2110*c8dee2aaSAndroid Build Coastguard Worker }
2111*c8dee2aaSAndroid Build Coastguard Worker 
2112*c8dee2aaSAndroid Build Coastguard Worker // This subtest verifies that, given an equivalent SkPaint and PaintOptions, the
2113*c8dee2aaSAndroid Build Coastguard Worker // Precompile system will, at least, generate all the pipelines a real draw would generate.
precompile_vs_real_draws_subtest(skiatest::Reporter * reporter,Context * context,PrecompileContext * precompileContext,skiatest::graphite::GraphiteTestContext * testContext,Recorder * recorder,const SkPaint & paint,const PaintOptions & paintOptions,ClipType clip,sk_sp<SkShader> clipShader,DrawTypeFlags dt,bool)2114*c8dee2aaSAndroid Build Coastguard Worker void precompile_vs_real_draws_subtest(skiatest::Reporter* reporter,
2115*c8dee2aaSAndroid Build Coastguard Worker                                       Context* context,
2116*c8dee2aaSAndroid Build Coastguard Worker                                       PrecompileContext* precompileContext,
2117*c8dee2aaSAndroid Build Coastguard Worker                                       skiatest::graphite::GraphiteTestContext* testContext,
2118*c8dee2aaSAndroid Build Coastguard Worker                                       Recorder* recorder,
2119*c8dee2aaSAndroid Build Coastguard Worker                                       const SkPaint& paint,
2120*c8dee2aaSAndroid Build Coastguard Worker                                       const PaintOptions& paintOptions,
2121*c8dee2aaSAndroid Build Coastguard Worker                                       ClipType clip,
2122*c8dee2aaSAndroid Build Coastguard Worker                                       sk_sp<SkShader> clipShader,
2123*c8dee2aaSAndroid Build Coastguard Worker                                       DrawTypeFlags dt,
2124*c8dee2aaSAndroid Build Coastguard Worker                                       bool /* verbose */) {
2125*c8dee2aaSAndroid Build Coastguard Worker     GlobalCache* globalCache = precompileContext->priv().globalCache();
2126*c8dee2aaSAndroid Build Coastguard Worker 
2127*c8dee2aaSAndroid Build Coastguard Worker     globalCache->resetGraphicsPipelines();
2128*c8dee2aaSAndroid Build Coastguard Worker 
2129*c8dee2aaSAndroid Build Coastguard Worker     const skgpu::graphite::Caps* caps = context->priv().caps();
2130*c8dee2aaSAndroid Build Coastguard Worker 
2131*c8dee2aaSAndroid Build Coastguard Worker     const SkColorType kColorType = kBGRA_8888_SkColorType;
2132*c8dee2aaSAndroid Build Coastguard Worker 
2133*c8dee2aaSAndroid Build Coastguard Worker     static const RenderPassProperties kDepth_Stencil_4 { DepthStencilFlags::kDepthStencil,
2134*c8dee2aaSAndroid Build Coastguard Worker                                                          kColorType,
2135*c8dee2aaSAndroid Build Coastguard Worker                                                          /* requiresMSAA= */ true };
2136*c8dee2aaSAndroid Build Coastguard Worker     static const RenderPassProperties kDepth_1 { DepthStencilFlags::kDepth,
2137*c8dee2aaSAndroid Build Coastguard Worker                                                  kColorType,
2138*c8dee2aaSAndroid Build Coastguard Worker                                                  /* requiresMSAA= */ false };
2139*c8dee2aaSAndroid Build Coastguard Worker 
2140*c8dee2aaSAndroid Build Coastguard Worker     TextureInfo textureInfo = caps->getDefaultSampledTextureInfo(kColorType,
2141*c8dee2aaSAndroid Build Coastguard Worker                                                                  skgpu::Mipmapped::kNo,
2142*c8dee2aaSAndroid Build Coastguard Worker                                                                  skgpu::Protected::kNo,
2143*c8dee2aaSAndroid Build Coastguard Worker                                                                  skgpu::Renderable::kYes);
2144*c8dee2aaSAndroid Build Coastguard Worker 
2145*c8dee2aaSAndroid Build Coastguard Worker     TextureInfo msaaTex = caps->getDefaultMSAATextureInfo(textureInfo, Discardable::kYes);
2146*c8dee2aaSAndroid Build Coastguard Worker 
2147*c8dee2aaSAndroid Build Coastguard Worker     bool vello = false;
2148*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_ENABLE_VELLO_SHADERS
2149*c8dee2aaSAndroid Build Coastguard Worker     vello = caps->computeSupport();
2150*c8dee2aaSAndroid Build Coastguard Worker #endif
2151*c8dee2aaSAndroid Build Coastguard Worker 
2152*c8dee2aaSAndroid Build Coastguard Worker     // Using Vello skips using MSAA for complex paths. Additionally, Intel Macs avoid MSAA
2153*c8dee2aaSAndroid Build Coastguard Worker     // in favor of path rendering.
2154*c8dee2aaSAndroid Build Coastguard Worker     const RenderPassProperties* pathProperties = (msaaTex.numSamples() > 1 && !vello)
2155*c8dee2aaSAndroid Build Coastguard Worker                                                                  ? &kDepth_Stencil_4
2156*c8dee2aaSAndroid Build Coastguard Worker                                                                  : &kDepth_1;
2157*c8dee2aaSAndroid Build Coastguard Worker 
2158*c8dee2aaSAndroid Build Coastguard Worker     int before = globalCache->numGraphicsPipelines();
2159*c8dee2aaSAndroid Build Coastguard Worker     Precompile(precompileContext, paintOptions, dt,
2160*c8dee2aaSAndroid Build Coastguard Worker                dt == kNonSimpleShape ? SkSpan(pathProperties, 1) : SkSpan(&kDepth_1, 1));
2161*c8dee2aaSAndroid Build Coastguard Worker     if (gNeedSKPPaintOption) {
2162*c8dee2aaSAndroid Build Coastguard Worker         // The skp draws a rect w/ a default SkPaint
2163*c8dee2aaSAndroid Build Coastguard Worker         PaintOptions skpPaintOptions;
2164*c8dee2aaSAndroid Build Coastguard Worker         Precompile(precompileContext, skpPaintOptions, DrawTypeFlags::kSimpleShape,
2165*c8dee2aaSAndroid Build Coastguard Worker                    { kDepth_1 });
2166*c8dee2aaSAndroid Build Coastguard Worker     }
2167*c8dee2aaSAndroid Build Coastguard Worker     int after = globalCache->numGraphicsPipelines();
2168*c8dee2aaSAndroid Build Coastguard Worker 
2169*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, before == 0);
2170*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, after > before);
2171*c8dee2aaSAndroid Build Coastguard Worker 
2172*c8dee2aaSAndroid Build Coastguard Worker     check_draw(reporter,
2173*c8dee2aaSAndroid Build Coastguard Worker                context,
2174*c8dee2aaSAndroid Build Coastguard Worker                precompileContext,
2175*c8dee2aaSAndroid Build Coastguard Worker                testContext,
2176*c8dee2aaSAndroid Build Coastguard Worker                recorder,
2177*c8dee2aaSAndroid Build Coastguard Worker                paint,
2178*c8dee2aaSAndroid Build Coastguard Worker                dt,
2179*c8dee2aaSAndroid Build Coastguard Worker                clip,
2180*c8dee2aaSAndroid Build Coastguard Worker                clipShader);
2181*c8dee2aaSAndroid Build Coastguard Worker }
2182*c8dee2aaSAndroid Build Coastguard Worker 
run_test(skiatest::Reporter * reporter,Context * context,PrecompileContext * precompileContext,skiatest::graphite::GraphiteTestContext * testContext,const KeyContext & precompileKeyContext,ShaderType s,BlenderType bm,ColorFilterType cf,MaskFilterType mf,ImageFilterType imageFilter,ClipType clip,DrawTypeFlags dt,uint32_t seed,bool verbose)2183*c8dee2aaSAndroid Build Coastguard Worker void run_test(skiatest::Reporter* reporter,
2184*c8dee2aaSAndroid Build Coastguard Worker               Context* context,
2185*c8dee2aaSAndroid Build Coastguard Worker               PrecompileContext* precompileContext,
2186*c8dee2aaSAndroid Build Coastguard Worker               skiatest::graphite::GraphiteTestContext* testContext,
2187*c8dee2aaSAndroid Build Coastguard Worker               const KeyContext& precompileKeyContext,
2188*c8dee2aaSAndroid Build Coastguard Worker               ShaderType s,
2189*c8dee2aaSAndroid Build Coastguard Worker               BlenderType bm,
2190*c8dee2aaSAndroid Build Coastguard Worker               ColorFilterType cf,
2191*c8dee2aaSAndroid Build Coastguard Worker               MaskFilterType mf,
2192*c8dee2aaSAndroid Build Coastguard Worker               ImageFilterType imageFilter,
2193*c8dee2aaSAndroid Build Coastguard Worker               ClipType clip,
2194*c8dee2aaSAndroid Build Coastguard Worker               DrawTypeFlags dt,
2195*c8dee2aaSAndroid Build Coastguard Worker               uint32_t seed,
2196*c8dee2aaSAndroid Build Coastguard Worker               bool verbose) {
2197*c8dee2aaSAndroid Build Coastguard Worker     SkRandom rand(seed);
2198*c8dee2aaSAndroid Build Coastguard Worker 
2199*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Recorder> recorder = context->makeRecorder();
2200*c8dee2aaSAndroid Build Coastguard Worker 
2201*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> clipShader;
2202*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PrecompileShader> clipShaderOption;
2203*c8dee2aaSAndroid Build Coastguard Worker 
2204*c8dee2aaSAndroid Build Coastguard Worker     if (clip == ClipType::kShader || clip == ClipType::kShader_Diff) {
2205*c8dee2aaSAndroid Build Coastguard Worker         std::tie(clipShader, clipShaderOption) = create_clip_shader(&rand, recorder.get());
2206*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!clipShader == !clipShaderOption);
2207*c8dee2aaSAndroid Build Coastguard Worker     }
2208*c8dee2aaSAndroid Build Coastguard Worker 
2209*c8dee2aaSAndroid Build Coastguard Worker     gNeedSKPPaintOption = false;
2210*c8dee2aaSAndroid Build Coastguard Worker     auto [paint, paintOptions] = create_paint(&rand, recorder.get(), s, bm, cf, mf, imageFilter);
2211*c8dee2aaSAndroid Build Coastguard Worker 
2212*c8dee2aaSAndroid Build Coastguard Worker     // The PaintOptions' clipShader can be handled here while the SkPaint's clipShader handling
2213*c8dee2aaSAndroid Build Coastguard Worker     // must be performed later (in ExtractPaintData or when an SkCanvas is accessible for
2214*c8dee2aaSAndroid Build Coastguard Worker     // a SkCanvas::clipShader call).
2215*c8dee2aaSAndroid Build Coastguard Worker     paintOptions.priv().setClipShaders({clipShaderOption});
2216*c8dee2aaSAndroid Build Coastguard Worker 
2217*c8dee2aaSAndroid Build Coastguard Worker     extract_vs_build_subtest(reporter, context, testContext, precompileKeyContext, recorder.get(),
2218*c8dee2aaSAndroid Build Coastguard Worker                              paint, paintOptions, s, bm, cf, mf, imageFilter, clip, clipShader, dt,
2219*c8dee2aaSAndroid Build Coastguard Worker                              seed, &rand, verbose);
2220*c8dee2aaSAndroid Build Coastguard Worker     precompile_vs_real_draws_subtest(reporter, context, precompileContext,
2221*c8dee2aaSAndroid Build Coastguard Worker                                      testContext, recorder.get(),
2222*c8dee2aaSAndroid Build Coastguard Worker                                      paint, paintOptions, clip, clipShader, dt, verbose);
2223*c8dee2aaSAndroid Build Coastguard Worker }
2224*c8dee2aaSAndroid Build Coastguard Worker 
2225*c8dee2aaSAndroid Build Coastguard Worker } // anonymous namespace
2226*c8dee2aaSAndroid Build Coastguard Worker 
DEF_CONDITIONAL_GRAPHITE_TEST_FOR_ALL_CONTEXTS(PaintParamsKeyTestReduced,reporter,context,testContext,true,CtsEnforcement::kNever)2227*c8dee2aaSAndroid Build Coastguard Worker DEF_CONDITIONAL_GRAPHITE_TEST_FOR_ALL_CONTEXTS(PaintParamsKeyTestReduced,
2228*c8dee2aaSAndroid Build Coastguard Worker                                                reporter,
2229*c8dee2aaSAndroid Build Coastguard Worker                                                context,
2230*c8dee2aaSAndroid Build Coastguard Worker                                                testContext,
2231*c8dee2aaSAndroid Build Coastguard Worker                                                true,
2232*c8dee2aaSAndroid Build Coastguard Worker                                                CtsEnforcement::kNever) {
2233*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<PrecompileContext> precompileContext = context->makePrecompileContext();
2234*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<RuntimeEffectDictionary> rtDict = std::make_unique<RuntimeEffectDictionary>();
2235*c8dee2aaSAndroid Build Coastguard Worker 
2236*c8dee2aaSAndroid Build Coastguard Worker #if 1
2237*c8dee2aaSAndroid Build Coastguard Worker     //----------------------
2238*c8dee2aaSAndroid Build Coastguard Worker     uint32_t seed = std::time(nullptr) % std::numeric_limits<uint32_t>::max();
2239*c8dee2aaSAndroid Build Coastguard Worker     SkRandom rand(seed);
2240*c8dee2aaSAndroid Build Coastguard Worker     ShaderType shaderType = random_shadertype(&rand);
2241*c8dee2aaSAndroid Build Coastguard Worker     BlenderType blenderType = random_blendertype(&rand);
2242*c8dee2aaSAndroid Build Coastguard Worker     ColorFilterType colorFilterType = random_colorfiltertype(&rand);
2243*c8dee2aaSAndroid Build Coastguard Worker     MaskFilterType maskFilterType = random_maskfiltertype(&rand);
2244*c8dee2aaSAndroid Build Coastguard Worker     ImageFilterType imageFilterType = ImageFilterType::kNone; // random_imagefiltertype(&rand);
2245*c8dee2aaSAndroid Build Coastguard Worker     ClipType clipType = random_cliptype(&rand);
2246*c8dee2aaSAndroid Build Coastguard Worker     DrawTypeFlags drawTypeFlags = random_drawtype(&rand);
2247*c8dee2aaSAndroid Build Coastguard Worker     //----------------------
2248*c8dee2aaSAndroid Build Coastguard Worker #else
2249*c8dee2aaSAndroid Build Coastguard Worker     //------------------------
2250*c8dee2aaSAndroid Build Coastguard Worker     uint32_t seed = 1721227069;
2251*c8dee2aaSAndroid Build Coastguard Worker     ShaderType shaderType = ShaderType::kLocalMatrix;
2252*c8dee2aaSAndroid Build Coastguard Worker     BlenderType blenderType = BlenderType::kArithmetic;
2253*c8dee2aaSAndroid Build Coastguard Worker     ColorFilterType colorFilterType = ColorFilterType::kRuntime;
2254*c8dee2aaSAndroid Build Coastguard Worker     MaskFilterType maskFilterType = MaskFilterType::kNone;
2255*c8dee2aaSAndroid Build Coastguard Worker     ImageFilterType imageFilterType = ImageFilterType::kDisplacement;
2256*c8dee2aaSAndroid Build Coastguard Worker     ClipType clipType = ClipType::kNone;
2257*c8dee2aaSAndroid Build Coastguard Worker     DrawTypeFlags drawTypeFlags = DrawTypeFlags::kText;
2258*c8dee2aaSAndroid Build Coastguard Worker     //-----------------------
2259*c8dee2aaSAndroid Build Coastguard Worker #endif
2260*c8dee2aaSAndroid Build Coastguard Worker 
2261*c8dee2aaSAndroid Build Coastguard Worker     SkString logMsg("Running ");
2262*c8dee2aaSAndroid Build Coastguard Worker     logMsg += BackendApiToStr(context->backend());
2263*c8dee2aaSAndroid Build Coastguard Worker 
2264*c8dee2aaSAndroid Build Coastguard Worker     log_run(logMsg.c_str(), seed, shaderType, blenderType, colorFilterType, maskFilterType,
2265*c8dee2aaSAndroid Build Coastguard Worker             imageFilterType, clipType, drawTypeFlags);
2266*c8dee2aaSAndroid Build Coastguard Worker 
2267*c8dee2aaSAndroid Build Coastguard Worker     run_test(reporter,
2268*c8dee2aaSAndroid Build Coastguard Worker              context,
2269*c8dee2aaSAndroid Build Coastguard Worker              precompileContext.get(),
2270*c8dee2aaSAndroid Build Coastguard Worker              testContext,
2271*c8dee2aaSAndroid Build Coastguard Worker              create_key_context(context, rtDict.get()),
2272*c8dee2aaSAndroid Build Coastguard Worker              shaderType,
2273*c8dee2aaSAndroid Build Coastguard Worker              blenderType,
2274*c8dee2aaSAndroid Build Coastguard Worker              colorFilterType,
2275*c8dee2aaSAndroid Build Coastguard Worker              maskFilterType,
2276*c8dee2aaSAndroid Build Coastguard Worker              imageFilterType,
2277*c8dee2aaSAndroid Build Coastguard Worker              clipType,
2278*c8dee2aaSAndroid Build Coastguard Worker              drawTypeFlags,
2279*c8dee2aaSAndroid Build Coastguard Worker              seed,
2280*c8dee2aaSAndroid Build Coastguard Worker              /* verbose= */ true);
2281*c8dee2aaSAndroid Build Coastguard Worker }
2282*c8dee2aaSAndroid Build Coastguard Worker 
2283*c8dee2aaSAndroid Build Coastguard Worker // This is intended to be a smoke test for the agreement between the two ways of creating a
2284*c8dee2aaSAndroid Build Coastguard Worker // PaintParamsKey:
2285*c8dee2aaSAndroid Build Coastguard Worker //    via ExtractPaintData (i.e., from an SkPaint)
2286*c8dee2aaSAndroid Build Coastguard Worker //    and via the pre-compilation system
2287*c8dee2aaSAndroid Build Coastguard Worker //
2288*c8dee2aaSAndroid Build Coastguard Worker // TODO: keep this as a smoke test but add a fuzzer that reuses all the helpers
2289*c8dee2aaSAndroid Build Coastguard Worker // TODO(b/306174708): enable in SkQP (if it's feasible)
DEF_CONDITIONAL_GRAPHITE_TEST_FOR_ALL_CONTEXTS(PaintParamsKeyTest,reporter,context,testContext,true,CtsEnforcement::kNever)2290*c8dee2aaSAndroid Build Coastguard Worker DEF_CONDITIONAL_GRAPHITE_TEST_FOR_ALL_CONTEXTS(PaintParamsKeyTest,
2291*c8dee2aaSAndroid Build Coastguard Worker                                                reporter,
2292*c8dee2aaSAndroid Build Coastguard Worker                                                context,
2293*c8dee2aaSAndroid Build Coastguard Worker                                                testContext,
2294*c8dee2aaSAndroid Build Coastguard Worker                                                true,
2295*c8dee2aaSAndroid Build Coastguard Worker                                                CtsEnforcement::kNever) {
2296*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<PrecompileContext> precompileContext = context->makePrecompileContext();
2297*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<RuntimeEffectDictionary> rtDict = std::make_unique<RuntimeEffectDictionary>();
2298*c8dee2aaSAndroid Build Coastguard Worker 
2299*c8dee2aaSAndroid Build Coastguard Worker     KeyContext precompileKeyContext(create_key_context(context, rtDict.get()));
2300*c8dee2aaSAndroid Build Coastguard Worker 
2301*c8dee2aaSAndroid Build Coastguard Worker     ShaderType shaders[] = {
2302*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kBlend,
2303*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kImage,
2304*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kRadialGradient,
2305*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kSolidColor,
2306*c8dee2aaSAndroid Build Coastguard Worker #if EXPANDED_SET
2307*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kNone,
2308*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kColorFilter,
2309*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kCoordClamp,
2310*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kConicalGradient,
2311*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kLinearGradient,
2312*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kLocalMatrix,
2313*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kPerlinNoise,
2314*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kPicture,
2315*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kRuntime,
2316*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kSweepGradient,
2317*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kYUVImage,
2318*c8dee2aaSAndroid Build Coastguard Worker             ShaderType::kWorkingColorSpace,
2319*c8dee2aaSAndroid Build Coastguard Worker #endif
2320*c8dee2aaSAndroid Build Coastguard Worker     };
2321*c8dee2aaSAndroid Build Coastguard Worker 
2322*c8dee2aaSAndroid Build Coastguard Worker     BlenderType blenders[] = {
2323*c8dee2aaSAndroid Build Coastguard Worker             BlenderType::kPorterDuff,
2324*c8dee2aaSAndroid Build Coastguard Worker             BlenderType::kShaderBased,
2325*c8dee2aaSAndroid Build Coastguard Worker             BlenderType::kRuntime,
2326*c8dee2aaSAndroid Build Coastguard Worker #if EXPANDED_SET
2327*c8dee2aaSAndroid Build Coastguard Worker             BlenderType::kNone,
2328*c8dee2aaSAndroid Build Coastguard Worker             BlenderType::kArithmetic,
2329*c8dee2aaSAndroid Build Coastguard Worker #endif
2330*c8dee2aaSAndroid Build Coastguard Worker     };
2331*c8dee2aaSAndroid Build Coastguard Worker 
2332*c8dee2aaSAndroid Build Coastguard Worker     ColorFilterType colorFilters[] = {
2333*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kNone,
2334*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kBlendMode,
2335*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kMatrix,
2336*c8dee2aaSAndroid Build Coastguard Worker #if EXPANDED_SET
2337*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kColorSpaceXform,
2338*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kCompose,
2339*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kGaussian,
2340*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kHighContrast,
2341*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kHSLAMatrix,
2342*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kLerp,
2343*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kLighting,
2344*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kLinearToSRGB,
2345*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kLuma,
2346*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kOverdraw,
2347*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kRuntime,
2348*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kSRGBToLinear,
2349*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kTable,
2350*c8dee2aaSAndroid Build Coastguard Worker             ColorFilterType::kWorkingFormat,
2351*c8dee2aaSAndroid Build Coastguard Worker #endif
2352*c8dee2aaSAndroid Build Coastguard Worker     };
2353*c8dee2aaSAndroid Build Coastguard Worker 
2354*c8dee2aaSAndroid Build Coastguard Worker     MaskFilterType maskFilters[] = {
2355*c8dee2aaSAndroid Build Coastguard Worker             MaskFilterType::kNone,
2356*c8dee2aaSAndroid Build Coastguard Worker #if EXPANDED_SET
2357*c8dee2aaSAndroid Build Coastguard Worker             MaskFilterType::kBlur,
2358*c8dee2aaSAndroid Build Coastguard Worker #endif
2359*c8dee2aaSAndroid Build Coastguard Worker     };
2360*c8dee2aaSAndroid Build Coastguard Worker 
2361*c8dee2aaSAndroid Build Coastguard Worker     ImageFilterType imageFilters[] = {
2362*c8dee2aaSAndroid Build Coastguard Worker             ImageFilterType::kNone,
2363*c8dee2aaSAndroid Build Coastguard Worker #if EXPANDED_SET
2364*c8dee2aaSAndroid Build Coastguard Worker             ImageFilterType::kArithmetic,
2365*c8dee2aaSAndroid Build Coastguard Worker             ImageFilterType::kBlendMode,
2366*c8dee2aaSAndroid Build Coastguard Worker             ImageFilterType::kRuntimeBlender,
2367*c8dee2aaSAndroid Build Coastguard Worker             ImageFilterType::kBlur,
2368*c8dee2aaSAndroid Build Coastguard Worker             ImageFilterType::kColorFilter,
2369*c8dee2aaSAndroid Build Coastguard Worker             ImageFilterType::kDisplacement,
2370*c8dee2aaSAndroid Build Coastguard Worker             ImageFilterType::kLighting,
2371*c8dee2aaSAndroid Build Coastguard Worker             ImageFilterType::kMatrixConvolution,
2372*c8dee2aaSAndroid Build Coastguard Worker             ImageFilterType::kMorphology,
2373*c8dee2aaSAndroid Build Coastguard Worker #endif
2374*c8dee2aaSAndroid Build Coastguard Worker     };
2375*c8dee2aaSAndroid Build Coastguard Worker 
2376*c8dee2aaSAndroid Build Coastguard Worker     ClipType clips[] = {
2377*c8dee2aaSAndroid Build Coastguard Worker             ClipType::kNone,
2378*c8dee2aaSAndroid Build Coastguard Worker #if EXPANDED_SET
2379*c8dee2aaSAndroid Build Coastguard Worker             ClipType::kShader,        // w/ a SkClipOp::kIntersect
2380*c8dee2aaSAndroid Build Coastguard Worker             ClipType::kShader_Diff,   // w/ a SkClipOp::kDifference
2381*c8dee2aaSAndroid Build Coastguard Worker #endif
2382*c8dee2aaSAndroid Build Coastguard Worker     };
2383*c8dee2aaSAndroid Build Coastguard Worker 
2384*c8dee2aaSAndroid Build Coastguard Worker     static const DrawTypeFlags kDrawTypeFlags[] = {
2385*c8dee2aaSAndroid Build Coastguard Worker             DrawTypeFlags::kBitmapText_Mask,
2386*c8dee2aaSAndroid Build Coastguard Worker             DrawTypeFlags::kBitmapText_LCD,
2387*c8dee2aaSAndroid Build Coastguard Worker             DrawTypeFlags::kBitmapText_Color,
2388*c8dee2aaSAndroid Build Coastguard Worker             DrawTypeFlags::kSDFText,
2389*c8dee2aaSAndroid Build Coastguard Worker             DrawTypeFlags::kSDFText_LCD,
2390*c8dee2aaSAndroid Build Coastguard Worker             DrawTypeFlags::kDrawVertices,
2391*c8dee2aaSAndroid Build Coastguard Worker             DrawTypeFlags::kSimpleShape,
2392*c8dee2aaSAndroid Build Coastguard Worker             DrawTypeFlags::kNonSimpleShape,
2393*c8dee2aaSAndroid Build Coastguard Worker     };
2394*c8dee2aaSAndroid Build Coastguard Worker 
2395*c8dee2aaSAndroid Build Coastguard Worker #if EXPANDED_SET
2396*c8dee2aaSAndroid Build Coastguard Worker     size_t kExpected = std::size(shaders) * std::size(blenders) * std::size(colorFilters) *
2397*c8dee2aaSAndroid Build Coastguard Worker                        std::size(maskFilters) * std::size(imageFilters) * std::size(clips) *
2398*c8dee2aaSAndroid Build Coastguard Worker                        std::size(kDrawTypeFlags);
2399*c8dee2aaSAndroid Build Coastguard Worker     int current = 0;
2400*c8dee2aaSAndroid Build Coastguard Worker #endif
2401*c8dee2aaSAndroid Build Coastguard Worker 
2402*c8dee2aaSAndroid Build Coastguard Worker     for (auto shader : shaders) {
2403*c8dee2aaSAndroid Build Coastguard Worker         for (auto blender : blenders) {
2404*c8dee2aaSAndroid Build Coastguard Worker             for (auto cf : colorFilters) {
2405*c8dee2aaSAndroid Build Coastguard Worker                 for (auto mf : maskFilters) {
2406*c8dee2aaSAndroid Build Coastguard Worker                     for (auto imageFilter : imageFilters) {
2407*c8dee2aaSAndroid Build Coastguard Worker                         for (auto clip : clips) {
2408*c8dee2aaSAndroid Build Coastguard Worker                             for (DrawTypeFlags dt : kDrawTypeFlags) {
2409*c8dee2aaSAndroid Build Coastguard Worker #if EXPANDED_SET
2410*c8dee2aaSAndroid Build Coastguard Worker                                 SkDebugf("%d/%zu\n", current, kExpected);
2411*c8dee2aaSAndroid Build Coastguard Worker                                 ++current;
2412*c8dee2aaSAndroid Build Coastguard Worker #endif
2413*c8dee2aaSAndroid Build Coastguard Worker 
2414*c8dee2aaSAndroid Build Coastguard Worker                                 run_test(reporter, context, precompileContext.get(),
2415*c8dee2aaSAndroid Build Coastguard Worker                                          testContext, precompileKeyContext,
2416*c8dee2aaSAndroid Build Coastguard Worker                                          shader, blender, cf, mf, imageFilter, clip, dt,
2417*c8dee2aaSAndroid Build Coastguard Worker                                          kDefaultSeed, /* verbose= */ false);
2418*c8dee2aaSAndroid Build Coastguard Worker                             }
2419*c8dee2aaSAndroid Build Coastguard Worker                         }
2420*c8dee2aaSAndroid Build Coastguard Worker                     }
2421*c8dee2aaSAndroid Build Coastguard Worker                 }
2422*c8dee2aaSAndroid Build Coastguard Worker             }
2423*c8dee2aaSAndroid Build Coastguard Worker         }
2424*c8dee2aaSAndroid Build Coastguard Worker     }
2425*c8dee2aaSAndroid Build Coastguard Worker 
2426*c8dee2aaSAndroid Build Coastguard Worker #if EXPANDED_SET
2427*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(current == (int) kExpected);
2428*c8dee2aaSAndroid Build Coastguard Worker #endif
2429*c8dee2aaSAndroid Build Coastguard Worker }
2430*c8dee2aaSAndroid Build Coastguard Worker 
2431*c8dee2aaSAndroid Build Coastguard Worker #endif // SK_GRAPHITE
2432