1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2017 Google Inc.
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 "fuzz/Fuzz.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "fuzz/FuzzCommon.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkPngDecoder.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlurTypes.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorFilter.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontMgr.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageFilter.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMaskFilter.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathEffect.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPictureRecorder.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint3.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRSXform.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRegion.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextBlob.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkVertices.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/docs/SkPDFDocument.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/Sk1DPathEffect.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/Sk2DPathEffect.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkCornerPathEffect.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkDashPathEffect.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkDiscretePathEffect.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkGradientShader.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkHighContrastFilter.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkImageFilters.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkLumaColorFilter.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkPerlinNoiseShader.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "include/encode/SkPngEncoder.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "include/svg/SkSVGCanvas.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "include/utils/SkNullCanvas.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkUTF.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkFontPriv.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkOSFile.h"
46*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkPaintPriv.h"
47*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkPicturePriv.h"
48*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkReadBuffer.h"
49*c8dee2aaSAndroid Build Coastguard Worker #include "src/utils/SkJSONWriter.h"
50*c8dee2aaSAndroid Build Coastguard Worker #include "tools/UrlDataManager.h"
51*c8dee2aaSAndroid Build Coastguard Worker #include "tools/debugger/DebugCanvas.h"
52*c8dee2aaSAndroid Build Coastguard Worker #include "tools/flags/CommandLineFlags.h"
53*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h"
54*c8dee2aaSAndroid Build Coastguard Worker
55*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_GANESH)
56*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
57*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
58*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/GrContextFactory.h"
59*c8dee2aaSAndroid Build Coastguard Worker #endif
60*c8dee2aaSAndroid Build Coastguard Worker
61*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
62*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLFunctions.h"
63*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLGpu.h"
64*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLUtil.h"
65*c8dee2aaSAndroid Build Coastguard Worker #endif
66*c8dee2aaSAndroid Build Coastguard Worker
67*c8dee2aaSAndroid Build Coastguard Worker #include <iostream>
68*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
69*c8dee2aaSAndroid Build Coastguard Worker
70*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker static DEFINE_bool2(gpuInfo, g, false, "Display GPU information on relevant targets.");
73*c8dee2aaSAndroid Build Coastguard Worker
74*c8dee2aaSAndroid Build Coastguard Worker // TODO:
75*c8dee2aaSAndroid Build Coastguard Worker // SkTextBlob with Unicode
76*c8dee2aaSAndroid Build Coastguard Worker // SkImage: more types
77*c8dee2aaSAndroid Build Coastguard Worker
78*c8dee2aaSAndroid Build Coastguard Worker // be careful: `foo(make_fuzz_t<T>(f), make_fuzz_t<U>(f))` is undefined.
79*c8dee2aaSAndroid Build Coastguard Worker // In fact, all make_fuzz_foo() functions have this potential problem.
80*c8dee2aaSAndroid Build Coastguard Worker // Use sequence points!
81*c8dee2aaSAndroid Build Coastguard Worker template <typename T>
make_fuzz_t(Fuzz * fuzz)82*c8dee2aaSAndroid Build Coastguard Worker inline T make_fuzz_t(Fuzz* fuzz) {
83*c8dee2aaSAndroid Build Coastguard Worker T t;
84*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&t);
85*c8dee2aaSAndroid Build Coastguard Worker return t;
86*c8dee2aaSAndroid Build Coastguard Worker }
87*c8dee2aaSAndroid Build Coastguard Worker
88*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkImage> make_fuzz_image(Fuzz*);
89*c8dee2aaSAndroid Build Coastguard Worker
90*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkPicture> make_fuzz_picture(Fuzz*, int depth);
91*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_colorfilter(Fuzz * fuzz,int depth)92*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkColorFilter> make_fuzz_colorfilter(Fuzz* fuzz, int depth) {
93*c8dee2aaSAndroid Build Coastguard Worker if (depth <= 0) {
94*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
95*c8dee2aaSAndroid Build Coastguard Worker }
96*c8dee2aaSAndroid Build Coastguard Worker int colorFilterType;
97*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&colorFilterType, 0, 8);
98*c8dee2aaSAndroid Build Coastguard Worker switch (colorFilterType) {
99*c8dee2aaSAndroid Build Coastguard Worker case 0:
100*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
101*c8dee2aaSAndroid Build Coastguard Worker case 1: {
102*c8dee2aaSAndroid Build Coastguard Worker SkColor color;
103*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode mode;
104*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&color);
105*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&mode, SkBlendMode::kLastMode);
106*c8dee2aaSAndroid Build Coastguard Worker return SkColorFilters::Blend(color, mode);
107*c8dee2aaSAndroid Build Coastguard Worker }
108*c8dee2aaSAndroid Build Coastguard Worker case 2: {
109*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorFilter> outer = make_fuzz_colorfilter(fuzz, depth - 1);
110*c8dee2aaSAndroid Build Coastguard Worker if (!outer) {
111*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
112*c8dee2aaSAndroid Build Coastguard Worker }
113*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorFilter> inner = make_fuzz_colorfilter(fuzz, depth - 1);
114*c8dee2aaSAndroid Build Coastguard Worker // makeComposed should be able to handle nullptr.
115*c8dee2aaSAndroid Build Coastguard Worker return outer->makeComposed(std::move(inner));
116*c8dee2aaSAndroid Build Coastguard Worker }
117*c8dee2aaSAndroid Build Coastguard Worker case 3: {
118*c8dee2aaSAndroid Build Coastguard Worker float array[20];
119*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(array, std::size(array));
120*c8dee2aaSAndroid Build Coastguard Worker return SkColorFilters::Matrix(array);
121*c8dee2aaSAndroid Build Coastguard Worker }
122*c8dee2aaSAndroid Build Coastguard Worker case 4: {
123*c8dee2aaSAndroid Build Coastguard Worker SkColor mul, add;
124*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&mul, &add);
125*c8dee2aaSAndroid Build Coastguard Worker return SkColorFilters::Lighting(mul, add);
126*c8dee2aaSAndroid Build Coastguard Worker }
127*c8dee2aaSAndroid Build Coastguard Worker case 5: {
128*c8dee2aaSAndroid Build Coastguard Worker bool grayscale;
129*c8dee2aaSAndroid Build Coastguard Worker int invertStyle;
130*c8dee2aaSAndroid Build Coastguard Worker float contrast;
131*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&grayscale);
132*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&invertStyle, 0, 2);
133*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&contrast, -1.0f, 1.0f);
134*c8dee2aaSAndroid Build Coastguard Worker return SkHighContrastFilter::Make(SkHighContrastConfig(
135*c8dee2aaSAndroid Build Coastguard Worker grayscale, SkHighContrastConfig::InvertStyle(invertStyle), contrast));
136*c8dee2aaSAndroid Build Coastguard Worker }
137*c8dee2aaSAndroid Build Coastguard Worker case 6:
138*c8dee2aaSAndroid Build Coastguard Worker return SkLumaColorFilter::Make();
139*c8dee2aaSAndroid Build Coastguard Worker case 7: {
140*c8dee2aaSAndroid Build Coastguard Worker uint8_t table[256];
141*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(table, std::size(table));
142*c8dee2aaSAndroid Build Coastguard Worker return SkColorFilters::Table(table);
143*c8dee2aaSAndroid Build Coastguard Worker }
144*c8dee2aaSAndroid Build Coastguard Worker case 8: {
145*c8dee2aaSAndroid Build Coastguard Worker uint8_t tableA[256];
146*c8dee2aaSAndroid Build Coastguard Worker uint8_t tableR[256];
147*c8dee2aaSAndroid Build Coastguard Worker uint8_t tableG[256];
148*c8dee2aaSAndroid Build Coastguard Worker uint8_t tableB[256];
149*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(tableA, std::size(tableA));
150*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(tableR, std::size(tableR));
151*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(tableG, std::size(tableG));
152*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(tableB, std::size(tableB));
153*c8dee2aaSAndroid Build Coastguard Worker return SkColorFilters::TableARGB(tableA, tableR, tableG, tableB);
154*c8dee2aaSAndroid Build Coastguard Worker }
155*c8dee2aaSAndroid Build Coastguard Worker default:
156*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(false);
157*c8dee2aaSAndroid Build Coastguard Worker break;
158*c8dee2aaSAndroid Build Coastguard Worker }
159*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
160*c8dee2aaSAndroid Build Coastguard Worker }
161*c8dee2aaSAndroid Build Coastguard Worker
fuzz_gradient_stops(Fuzz * fuzz,SkScalar * pos,int colorCount)162*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_gradient_stops(Fuzz* fuzz, SkScalar* pos, int colorCount) {
163*c8dee2aaSAndroid Build Coastguard Worker SkScalar totalPos = 0;
164*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < colorCount; ++i) {
165*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&pos[i], 1.0f, 1024.0f);
166*c8dee2aaSAndroid Build Coastguard Worker totalPos += pos[i];
167*c8dee2aaSAndroid Build Coastguard Worker }
168*c8dee2aaSAndroid Build Coastguard Worker totalPos = 1.0f / totalPos;
169*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < colorCount; ++i) {
170*c8dee2aaSAndroid Build Coastguard Worker pos[i] *= totalPos;
171*c8dee2aaSAndroid Build Coastguard Worker }
172*c8dee2aaSAndroid Build Coastguard Worker // SkASSERT(fabs(pos[colorCount - 1] - 1.0f) < 0.00001f);
173*c8dee2aaSAndroid Build Coastguard Worker pos[colorCount - 1] = 1.0f;
174*c8dee2aaSAndroid Build Coastguard Worker }
175*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_shader(Fuzz * fuzz,int depth)176*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkShader> make_fuzz_shader(Fuzz* fuzz, int depth) {
177*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkShader> shader1(nullptr), shader2(nullptr);
178*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorFilter> colorFilter(nullptr);
179*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bitmap;
180*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> img;
181*c8dee2aaSAndroid Build Coastguard Worker SkTileMode tmX, tmY;
182*c8dee2aaSAndroid Build Coastguard Worker bool useMatrix;
183*c8dee2aaSAndroid Build Coastguard Worker SkColor color;
184*c8dee2aaSAndroid Build Coastguard Worker SkMatrix matrix;
185*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode blendMode;
186*c8dee2aaSAndroid Build Coastguard Worker int shaderType;
187*c8dee2aaSAndroid Build Coastguard Worker if (depth <= 0) {
188*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
189*c8dee2aaSAndroid Build Coastguard Worker }
190*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&shaderType, 0, 14);
191*c8dee2aaSAndroid Build Coastguard Worker switch (shaderType) {
192*c8dee2aaSAndroid Build Coastguard Worker case 0:
193*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
194*c8dee2aaSAndroid Build Coastguard Worker case 1:
195*c8dee2aaSAndroid Build Coastguard Worker return SkShaders::Empty();
196*c8dee2aaSAndroid Build Coastguard Worker case 2:
197*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&color);
198*c8dee2aaSAndroid Build Coastguard Worker return SkShaders::Color(color);
199*c8dee2aaSAndroid Build Coastguard Worker case 3:
200*c8dee2aaSAndroid Build Coastguard Worker img = make_fuzz_image(fuzz);
201*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&tmX, SkTileMode::kLastTileMode);
202*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&tmY, SkTileMode::kLastTileMode);
203*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useMatrix);
204*c8dee2aaSAndroid Build Coastguard Worker if (useMatrix) {
205*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &matrix);
206*c8dee2aaSAndroid Build Coastguard Worker }
207*c8dee2aaSAndroid Build Coastguard Worker return img->makeShader(tmX, tmY, SkSamplingOptions(), useMatrix ? &matrix : nullptr);
208*c8dee2aaSAndroid Build Coastguard Worker case 5:
209*c8dee2aaSAndroid Build Coastguard Worker shader1 = make_fuzz_shader(fuzz, depth - 1); // limit recursion.
210*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &matrix);
211*c8dee2aaSAndroid Build Coastguard Worker return shader1 ? shader1->makeWithLocalMatrix(matrix) : nullptr;
212*c8dee2aaSAndroid Build Coastguard Worker case 6:
213*c8dee2aaSAndroid Build Coastguard Worker shader1 = make_fuzz_shader(fuzz, depth - 1); // limit recursion.
214*c8dee2aaSAndroid Build Coastguard Worker colorFilter = make_fuzz_colorfilter(fuzz, depth - 1);
215*c8dee2aaSAndroid Build Coastguard Worker return shader1 ? shader1->makeWithColorFilter(std::move(colorFilter)) : nullptr;
216*c8dee2aaSAndroid Build Coastguard Worker case 7:
217*c8dee2aaSAndroid Build Coastguard Worker shader1 = make_fuzz_shader(fuzz, depth - 1); // limit recursion.
218*c8dee2aaSAndroid Build Coastguard Worker shader2 = make_fuzz_shader(fuzz, depth - 1);
219*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&blendMode, SkBlendMode::kLastMode);
220*c8dee2aaSAndroid Build Coastguard Worker return SkShaders::Blend(blendMode, std::move(shader1), std::move(shader2));
221*c8dee2aaSAndroid Build Coastguard Worker case 8: {
222*c8dee2aaSAndroid Build Coastguard Worker auto pic = make_fuzz_picture(fuzz, depth - 1);
223*c8dee2aaSAndroid Build Coastguard Worker bool useTile;
224*c8dee2aaSAndroid Build Coastguard Worker SkRect tile;
225*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&tmX, SkTileMode::kLastTileMode);
226*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&tmY, SkTileMode::kLastTileMode);
227*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useMatrix, &useTile);
228*c8dee2aaSAndroid Build Coastguard Worker if (useMatrix) {
229*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &matrix);
230*c8dee2aaSAndroid Build Coastguard Worker }
231*c8dee2aaSAndroid Build Coastguard Worker if (useTile) {
232*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&tile);
233*c8dee2aaSAndroid Build Coastguard Worker }
234*c8dee2aaSAndroid Build Coastguard Worker return pic->makeShader(tmX, tmY, SkFilterMode::kNearest,
235*c8dee2aaSAndroid Build Coastguard Worker useMatrix ? &matrix : nullptr, useTile ? &tile : nullptr);
236*c8dee2aaSAndroid Build Coastguard Worker }
237*c8dee2aaSAndroid Build Coastguard Worker // EFFECTS:
238*c8dee2aaSAndroid Build Coastguard Worker case 9:
239*c8dee2aaSAndroid Build Coastguard Worker // Deprecated SkGaussianEdgeShader
240*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
241*c8dee2aaSAndroid Build Coastguard Worker case 10: {
242*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMaxColors = 12;
243*c8dee2aaSAndroid Build Coastguard Worker SkPoint pts[2];
244*c8dee2aaSAndroid Build Coastguard Worker SkColor colors[kMaxColors];
245*c8dee2aaSAndroid Build Coastguard Worker SkScalar pos[kMaxColors];
246*c8dee2aaSAndroid Build Coastguard Worker int colorCount;
247*c8dee2aaSAndroid Build Coastguard Worker bool usePos;
248*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(pts, 2);
249*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&colorCount, 2, kMaxColors);
250*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(colors, colorCount);
251*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&tmX, SkTileMode::kLastTileMode);
252*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useMatrix, &usePos);
253*c8dee2aaSAndroid Build Coastguard Worker if (useMatrix) {
254*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &matrix);
255*c8dee2aaSAndroid Build Coastguard Worker }
256*c8dee2aaSAndroid Build Coastguard Worker if (usePos) {
257*c8dee2aaSAndroid Build Coastguard Worker fuzz_gradient_stops(fuzz, pos, colorCount);
258*c8dee2aaSAndroid Build Coastguard Worker }
259*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeLinear(pts, colors, usePos ? pos : nullptr, colorCount,
260*c8dee2aaSAndroid Build Coastguard Worker tmX, 0, useMatrix ? &matrix : nullptr);
261*c8dee2aaSAndroid Build Coastguard Worker }
262*c8dee2aaSAndroid Build Coastguard Worker case 11: {
263*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMaxColors = 12;
264*c8dee2aaSAndroid Build Coastguard Worker SkPoint center;
265*c8dee2aaSAndroid Build Coastguard Worker SkScalar radius;
266*c8dee2aaSAndroid Build Coastguard Worker int colorCount;
267*c8dee2aaSAndroid Build Coastguard Worker bool usePos;
268*c8dee2aaSAndroid Build Coastguard Worker SkColor colors[kMaxColors];
269*c8dee2aaSAndroid Build Coastguard Worker SkScalar pos[kMaxColors];
270*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&tmX, SkTileMode::kLastTileMode);
271*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useMatrix, &usePos, ¢er, &radius);
272*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&colorCount, 2, kMaxColors);
273*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(colors, colorCount);
274*c8dee2aaSAndroid Build Coastguard Worker if (useMatrix) {
275*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &matrix);
276*c8dee2aaSAndroid Build Coastguard Worker }
277*c8dee2aaSAndroid Build Coastguard Worker if (usePos) {
278*c8dee2aaSAndroid Build Coastguard Worker fuzz_gradient_stops(fuzz, pos, colorCount);
279*c8dee2aaSAndroid Build Coastguard Worker }
280*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeRadial(center, radius, colors, usePos ? pos : nullptr,
281*c8dee2aaSAndroid Build Coastguard Worker colorCount, tmX, 0, useMatrix ? &matrix : nullptr);
282*c8dee2aaSAndroid Build Coastguard Worker }
283*c8dee2aaSAndroid Build Coastguard Worker case 12: {
284*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMaxColors = 12;
285*c8dee2aaSAndroid Build Coastguard Worker SkPoint start, end;
286*c8dee2aaSAndroid Build Coastguard Worker SkScalar startRadius, endRadius;
287*c8dee2aaSAndroid Build Coastguard Worker int colorCount;
288*c8dee2aaSAndroid Build Coastguard Worker bool usePos;
289*c8dee2aaSAndroid Build Coastguard Worker SkColor colors[kMaxColors];
290*c8dee2aaSAndroid Build Coastguard Worker SkScalar pos[kMaxColors];
291*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&tmX, SkTileMode::kLastTileMode);
292*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useMatrix, &usePos, &startRadius, &endRadius, &start, &end);
293*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&colorCount, 2, kMaxColors);
294*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(colors, colorCount);
295*c8dee2aaSAndroid Build Coastguard Worker if (useMatrix) {
296*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &matrix);
297*c8dee2aaSAndroid Build Coastguard Worker }
298*c8dee2aaSAndroid Build Coastguard Worker if (usePos) {
299*c8dee2aaSAndroid Build Coastguard Worker fuzz_gradient_stops(fuzz, pos, colorCount);
300*c8dee2aaSAndroid Build Coastguard Worker }
301*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius, colors,
302*c8dee2aaSAndroid Build Coastguard Worker usePos ? pos : nullptr, colorCount, tmX, 0,
303*c8dee2aaSAndroid Build Coastguard Worker useMatrix ? &matrix : nullptr);
304*c8dee2aaSAndroid Build Coastguard Worker }
305*c8dee2aaSAndroid Build Coastguard Worker case 13: {
306*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMaxColors = 12;
307*c8dee2aaSAndroid Build Coastguard Worker SkScalar cx, cy;
308*c8dee2aaSAndroid Build Coastguard Worker int colorCount;
309*c8dee2aaSAndroid Build Coastguard Worker bool usePos;
310*c8dee2aaSAndroid Build Coastguard Worker SkColor colors[kMaxColors];
311*c8dee2aaSAndroid Build Coastguard Worker SkScalar pos[kMaxColors];
312*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cx, &cy, &useMatrix, &usePos);
313*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&colorCount, 2, kMaxColors);
314*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(colors, colorCount);
315*c8dee2aaSAndroid Build Coastguard Worker if (useMatrix) {
316*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &matrix);
317*c8dee2aaSAndroid Build Coastguard Worker }
318*c8dee2aaSAndroid Build Coastguard Worker if (usePos) {
319*c8dee2aaSAndroid Build Coastguard Worker fuzz_gradient_stops(fuzz, pos, colorCount);
320*c8dee2aaSAndroid Build Coastguard Worker }
321*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeSweep(cx, cy, colors, usePos ? pos : nullptr, colorCount,
322*c8dee2aaSAndroid Build Coastguard Worker 0, useMatrix ? &matrix : nullptr);
323*c8dee2aaSAndroid Build Coastguard Worker }
324*c8dee2aaSAndroid Build Coastguard Worker case 14: {
325*c8dee2aaSAndroid Build Coastguard Worker SkScalar baseFrequencyX, baseFrequencyY, seed;
326*c8dee2aaSAndroid Build Coastguard Worker int numOctaves;
327*c8dee2aaSAndroid Build Coastguard Worker SkISize tileSize;
328*c8dee2aaSAndroid Build Coastguard Worker bool useTileSize, turbulence;
329*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&baseFrequencyX, &baseFrequencyY, &seed, &useTileSize, &turbulence);
330*c8dee2aaSAndroid Build Coastguard Worker if (useTileSize) {
331*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&tileSize);
332*c8dee2aaSAndroid Build Coastguard Worker }
333*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&numOctaves, 2, 7);
334*c8dee2aaSAndroid Build Coastguard Worker if (turbulence) {
335*c8dee2aaSAndroid Build Coastguard Worker return SkShaders::MakeTurbulence(baseFrequencyX,
336*c8dee2aaSAndroid Build Coastguard Worker baseFrequencyY,
337*c8dee2aaSAndroid Build Coastguard Worker numOctaves,
338*c8dee2aaSAndroid Build Coastguard Worker seed,
339*c8dee2aaSAndroid Build Coastguard Worker useTileSize ? &tileSize : nullptr);
340*c8dee2aaSAndroid Build Coastguard Worker } else {
341*c8dee2aaSAndroid Build Coastguard Worker return SkShaders::MakeFractalNoise(baseFrequencyX,
342*c8dee2aaSAndroid Build Coastguard Worker baseFrequencyY,
343*c8dee2aaSAndroid Build Coastguard Worker numOctaves,
344*c8dee2aaSAndroid Build Coastguard Worker seed,
345*c8dee2aaSAndroid Build Coastguard Worker useTileSize ? &tileSize : nullptr);
346*c8dee2aaSAndroid Build Coastguard Worker }
347*c8dee2aaSAndroid Build Coastguard Worker }
348*c8dee2aaSAndroid Build Coastguard Worker default:
349*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(false);
350*c8dee2aaSAndroid Build Coastguard Worker break;
351*c8dee2aaSAndroid Build Coastguard Worker }
352*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
353*c8dee2aaSAndroid Build Coastguard Worker }
354*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_patheffect(Fuzz * fuzz,int depth)355*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkPathEffect> make_fuzz_patheffect(Fuzz* fuzz, int depth) {
356*c8dee2aaSAndroid Build Coastguard Worker if (depth <= 0) {
357*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
358*c8dee2aaSAndroid Build Coastguard Worker }
359*c8dee2aaSAndroid Build Coastguard Worker uint8_t pathEffectType;
360*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&pathEffectType, 0, 8);
361*c8dee2aaSAndroid Build Coastguard Worker switch (pathEffectType) {
362*c8dee2aaSAndroid Build Coastguard Worker case 0: {
363*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
364*c8dee2aaSAndroid Build Coastguard Worker }
365*c8dee2aaSAndroid Build Coastguard Worker case 1: {
366*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPathEffect> first = make_fuzz_patheffect(fuzz, depth - 1);
367*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPathEffect> second = make_fuzz_patheffect(fuzz, depth - 1);
368*c8dee2aaSAndroid Build Coastguard Worker return SkPathEffect::MakeSum(std::move(first), std::move(second));
369*c8dee2aaSAndroid Build Coastguard Worker }
370*c8dee2aaSAndroid Build Coastguard Worker case 2: {
371*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPathEffect> first = make_fuzz_patheffect(fuzz, depth - 1);
372*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPathEffect> second = make_fuzz_patheffect(fuzz, depth - 1);
373*c8dee2aaSAndroid Build Coastguard Worker return SkPathEffect::MakeCompose(std::move(first), std::move(second));
374*c8dee2aaSAndroid Build Coastguard Worker }
375*c8dee2aaSAndroid Build Coastguard Worker case 3: {
376*c8dee2aaSAndroid Build Coastguard Worker SkPath path;
377*c8dee2aaSAndroid Build Coastguard Worker FuzzNicePath(fuzz, &path, 20);
378*c8dee2aaSAndroid Build Coastguard Worker SkScalar advance, phase;
379*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&advance, &phase);
380*c8dee2aaSAndroid Build Coastguard Worker SkPath1DPathEffect::Style style;
381*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&style, SkPath1DPathEffect::kLastEnum_Style);
382*c8dee2aaSAndroid Build Coastguard Worker return SkPath1DPathEffect::Make(path, advance, phase, style);
383*c8dee2aaSAndroid Build Coastguard Worker }
384*c8dee2aaSAndroid Build Coastguard Worker case 4: {
385*c8dee2aaSAndroid Build Coastguard Worker SkScalar width;
386*c8dee2aaSAndroid Build Coastguard Worker SkMatrix matrix;
387*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&width);
388*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &matrix);
389*c8dee2aaSAndroid Build Coastguard Worker return SkLine2DPathEffect::Make(width, matrix);
390*c8dee2aaSAndroid Build Coastguard Worker }
391*c8dee2aaSAndroid Build Coastguard Worker case 5: {
392*c8dee2aaSAndroid Build Coastguard Worker SkPath path;
393*c8dee2aaSAndroid Build Coastguard Worker FuzzNicePath(fuzz, &path, 20);
394*c8dee2aaSAndroid Build Coastguard Worker SkMatrix matrix;
395*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &matrix);
396*c8dee2aaSAndroid Build Coastguard Worker return SkPath2DPathEffect::Make(matrix, path);
397*c8dee2aaSAndroid Build Coastguard Worker }
398*c8dee2aaSAndroid Build Coastguard Worker case 6: {
399*c8dee2aaSAndroid Build Coastguard Worker SkScalar radius;
400*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&radius);
401*c8dee2aaSAndroid Build Coastguard Worker return SkCornerPathEffect::Make(radius);
402*c8dee2aaSAndroid Build Coastguard Worker }
403*c8dee2aaSAndroid Build Coastguard Worker case 7: {
404*c8dee2aaSAndroid Build Coastguard Worker SkScalar phase;
405*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&phase);
406*c8dee2aaSAndroid Build Coastguard Worker SkScalar intervals[20];
407*c8dee2aaSAndroid Build Coastguard Worker int count;
408*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&count, 0, (int)std::size(intervals));
409*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(intervals, count);
410*c8dee2aaSAndroid Build Coastguard Worker return SkDashPathEffect::Make(intervals, count, phase);
411*c8dee2aaSAndroid Build Coastguard Worker }
412*c8dee2aaSAndroid Build Coastguard Worker case 8: {
413*c8dee2aaSAndroid Build Coastguard Worker SkScalar segLength, dev;
414*c8dee2aaSAndroid Build Coastguard Worker uint32_t seed;
415*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&segLength, &dev, &seed);
416*c8dee2aaSAndroid Build Coastguard Worker return SkDiscretePathEffect::Make(segLength, dev, seed);
417*c8dee2aaSAndroid Build Coastguard Worker }
418*c8dee2aaSAndroid Build Coastguard Worker default:
419*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(false);
420*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
421*c8dee2aaSAndroid Build Coastguard Worker }
422*c8dee2aaSAndroid Build Coastguard Worker }
423*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_maskfilter(Fuzz * fuzz)424*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkMaskFilter> make_fuzz_maskfilter(Fuzz* fuzz) {
425*c8dee2aaSAndroid Build Coastguard Worker int maskfilterType;
426*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&maskfilterType, 0, 1);
427*c8dee2aaSAndroid Build Coastguard Worker switch (maskfilterType) {
428*c8dee2aaSAndroid Build Coastguard Worker case 0:
429*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
430*c8dee2aaSAndroid Build Coastguard Worker case 1: {
431*c8dee2aaSAndroid Build Coastguard Worker SkBlurStyle blurStyle;
432*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&blurStyle, kLastEnum_SkBlurStyle);
433*c8dee2aaSAndroid Build Coastguard Worker SkScalar sigma;
434*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&sigma);
435*c8dee2aaSAndroid Build Coastguard Worker bool respectCTM;
436*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&respectCTM);
437*c8dee2aaSAndroid Build Coastguard Worker return SkMaskFilter::MakeBlur(blurStyle, sigma, respectCTM);
438*c8dee2aaSAndroid Build Coastguard Worker }
439*c8dee2aaSAndroid Build Coastguard Worker default:
440*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(false);
441*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
442*c8dee2aaSAndroid Build Coastguard Worker }
443*c8dee2aaSAndroid Build Coastguard Worker }
444*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_typeface(Fuzz * fuzz)445*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkTypeface> make_fuzz_typeface(Fuzz* fuzz) {
446*c8dee2aaSAndroid Build Coastguard Worker if (make_fuzz_t<bool>(fuzz)) {
447*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
448*c8dee2aaSAndroid Build Coastguard Worker }
449*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFontMgr> mgr = ToolUtils::TestFontMgr();
450*c8dee2aaSAndroid Build Coastguard Worker int familyCount = mgr->countFamilies();
451*c8dee2aaSAndroid Build Coastguard Worker int i, j;
452*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&i, 0, familyCount - 1);
453*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFontStyleSet> family(mgr->createStyleSet(i));
454*c8dee2aaSAndroid Build Coastguard Worker int styleCount = family->count();
455*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&j, 0, styleCount - 1);
456*c8dee2aaSAndroid Build Coastguard Worker return sk_sp<SkTypeface>(family->createTypeface(j));
457*c8dee2aaSAndroid Build Coastguard Worker }
458*c8dee2aaSAndroid Build Coastguard Worker
459*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkImageFilter> make_fuzz_imageFilter(Fuzz* fuzz, int depth);
460*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_lighting_imagefilter(Fuzz * fuzz,int depth)461*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkImageFilter> make_fuzz_lighting_imagefilter(Fuzz* fuzz, int depth) {
462*c8dee2aaSAndroid Build Coastguard Worker if (depth <= 0) {
463*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
464*c8dee2aaSAndroid Build Coastguard Worker }
465*c8dee2aaSAndroid Build Coastguard Worker uint8_t imageFilterType;
466*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&imageFilterType, 1, 6);
467*c8dee2aaSAndroid Build Coastguard Worker SkPoint3 p, q;
468*c8dee2aaSAndroid Build Coastguard Worker SkColor lightColor;
469*c8dee2aaSAndroid Build Coastguard Worker SkScalar surfaceScale, k, specularExponent, cutoffAngle, shininess;
470*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input;
471*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
472*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
473*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useCropRect);
474*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
475*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
476*c8dee2aaSAndroid Build Coastguard Worker }
477*c8dee2aaSAndroid Build Coastguard Worker switch (imageFilterType) {
478*c8dee2aaSAndroid Build Coastguard Worker case 1:
479*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&p, &lightColor, &surfaceScale, &k);
480*c8dee2aaSAndroid Build Coastguard Worker input = make_fuzz_imageFilter(fuzz, depth - 1);
481*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::DistantLitDiffuse(p, lightColor, surfaceScale, k,
482*c8dee2aaSAndroid Build Coastguard Worker std::move(input),
483*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
484*c8dee2aaSAndroid Build Coastguard Worker case 2:
485*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&p, &lightColor, &surfaceScale, &k);
486*c8dee2aaSAndroid Build Coastguard Worker input = make_fuzz_imageFilter(fuzz, depth - 1);
487*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::PointLitDiffuse(p, lightColor, surfaceScale, k,
488*c8dee2aaSAndroid Build Coastguard Worker std::move(input),
489*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
490*c8dee2aaSAndroid Build Coastguard Worker case 3:
491*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&p, &q, &specularExponent, &cutoffAngle, &lightColor, &surfaceScale, &k);
492*c8dee2aaSAndroid Build Coastguard Worker input = make_fuzz_imageFilter(fuzz, depth - 1);
493*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::SpotLitDiffuse(
494*c8dee2aaSAndroid Build Coastguard Worker p, q, specularExponent, cutoffAngle, lightColor, surfaceScale, k,
495*c8dee2aaSAndroid Build Coastguard Worker std::move(input), useCropRect ? &cropRect : nullptr);
496*c8dee2aaSAndroid Build Coastguard Worker case 4:
497*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&p, &lightColor, &surfaceScale, &k, &shininess);
498*c8dee2aaSAndroid Build Coastguard Worker input = make_fuzz_imageFilter(fuzz, depth - 1);
499*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::DistantLitSpecular(p, lightColor, surfaceScale, k,
500*c8dee2aaSAndroid Build Coastguard Worker shininess, std::move(input),
501*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
502*c8dee2aaSAndroid Build Coastguard Worker case 5:
503*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&p, &lightColor, &surfaceScale, &k, &shininess);
504*c8dee2aaSAndroid Build Coastguard Worker input = make_fuzz_imageFilter(fuzz, depth - 1);
505*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::PointLitSpecular(p, lightColor, surfaceScale, k,
506*c8dee2aaSAndroid Build Coastguard Worker shininess, std::move(input),
507*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
508*c8dee2aaSAndroid Build Coastguard Worker case 6:
509*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&p, &q, &specularExponent, &cutoffAngle, &lightColor, &surfaceScale, &k,
510*c8dee2aaSAndroid Build Coastguard Worker &shininess);
511*c8dee2aaSAndroid Build Coastguard Worker input = make_fuzz_imageFilter(fuzz, depth - 1);
512*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::SpotLitSpecular(
513*c8dee2aaSAndroid Build Coastguard Worker p, q, specularExponent, cutoffAngle, lightColor, surfaceScale, k, shininess,
514*c8dee2aaSAndroid Build Coastguard Worker std::move(input), useCropRect ? &cropRect : nullptr);
515*c8dee2aaSAndroid Build Coastguard Worker default:
516*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(false);
517*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
518*c8dee2aaSAndroid Build Coastguard Worker }
519*c8dee2aaSAndroid Build Coastguard Worker }
520*c8dee2aaSAndroid Build Coastguard Worker
521*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_paint(Fuzz* fuzz, SkPaint* paint, int depth);
522*c8dee2aaSAndroid Build Coastguard Worker
next_sampling(Fuzz * fuzz)523*c8dee2aaSAndroid Build Coastguard Worker static SkSamplingOptions next_sampling(Fuzz* fuzz) {
524*c8dee2aaSAndroid Build Coastguard Worker if (fuzz->nextBool()) {
525*c8dee2aaSAndroid Build Coastguard Worker float B, C;
526*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&B, &C);
527*c8dee2aaSAndroid Build Coastguard Worker return SkSamplingOptions({B, C});
528*c8dee2aaSAndroid Build Coastguard Worker } else {
529*c8dee2aaSAndroid Build Coastguard Worker SkFilterMode fm;
530*c8dee2aaSAndroid Build Coastguard Worker SkMipmapMode mm;
531*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&fm, SkFilterMode::kLast);
532*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&mm, SkMipmapMode::kLast);
533*c8dee2aaSAndroid Build Coastguard Worker return SkSamplingOptions(fm, mm);
534*c8dee2aaSAndroid Build Coastguard Worker }
535*c8dee2aaSAndroid Build Coastguard Worker }
536*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_imageFilter(Fuzz * fuzz,int depth)537*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkImageFilter> make_fuzz_imageFilter(Fuzz* fuzz, int depth) {
538*c8dee2aaSAndroid Build Coastguard Worker if (depth <= 0) {
539*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
540*c8dee2aaSAndroid Build Coastguard Worker }
541*c8dee2aaSAndroid Build Coastguard Worker uint8_t imageFilterType;
542*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&imageFilterType, 0, 22);
543*c8dee2aaSAndroid Build Coastguard Worker switch (imageFilterType) {
544*c8dee2aaSAndroid Build Coastguard Worker case 0:
545*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
546*c8dee2aaSAndroid Build Coastguard Worker case 1: {
547*c8dee2aaSAndroid Build Coastguard Worker SkScalar sigmaX, sigmaY;
548*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
549*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
550*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&sigmaX, &sigmaY, &useCropRect);
551*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
552*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
553*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
554*c8dee2aaSAndroid Build Coastguard Worker }
555*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Blur(sigmaX, sigmaY, std::move(input),
556*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
557*c8dee2aaSAndroid Build Coastguard Worker }
558*c8dee2aaSAndroid Build Coastguard Worker case 2: {
559*c8dee2aaSAndroid Build Coastguard Worker SkMatrix matrix;
560*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &matrix);
561*c8dee2aaSAndroid Build Coastguard Worker const auto sampling = next_sampling(fuzz);
562*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
563*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::MatrixTransform(matrix, sampling, std::move(input));
564*c8dee2aaSAndroid Build Coastguard Worker }
565*c8dee2aaSAndroid Build Coastguard Worker case 3: {
566*c8dee2aaSAndroid Build Coastguard Worker float k1, k2, k3, k4;
567*c8dee2aaSAndroid Build Coastguard Worker bool enforcePMColor;
568*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
569*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&k1, &k2, &k3, &k4, &enforcePMColor, &useCropRect);
570*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> background = make_fuzz_imageFilter(fuzz, depth - 1);
571*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> foreground = make_fuzz_imageFilter(fuzz, depth - 1);
572*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
573*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
574*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
575*c8dee2aaSAndroid Build Coastguard Worker }
576*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Arithmetic(k1, k2, k3, k4, enforcePMColor,
577*c8dee2aaSAndroid Build Coastguard Worker std::move(background), std::move(foreground),
578*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
579*c8dee2aaSAndroid Build Coastguard Worker }
580*c8dee2aaSAndroid Build Coastguard Worker case 4: {
581*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkColorFilter> cf = make_fuzz_colorfilter(fuzz, depth - 1);
582*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
583*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
584*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
585*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useCropRect);
586*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
587*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
588*c8dee2aaSAndroid Build Coastguard Worker }
589*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::ColorFilter(std::move(cf), std::move(input),
590*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
591*c8dee2aaSAndroid Build Coastguard Worker }
592*c8dee2aaSAndroid Build Coastguard Worker case 5: {
593*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> ifo = make_fuzz_imageFilter(fuzz, depth - 1);
594*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> ifi = make_fuzz_imageFilter(fuzz, depth - 1);
595*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Compose(std::move(ifo), std::move(ifi));
596*c8dee2aaSAndroid Build Coastguard Worker }
597*c8dee2aaSAndroid Build Coastguard Worker case 6: {
598*c8dee2aaSAndroid Build Coastguard Worker SkColorChannel xChannelSelector, yChannelSelector;
599*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&xChannelSelector, SkColorChannel::kLastEnum);
600*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&yChannelSelector, SkColorChannel::kLastEnum);
601*c8dee2aaSAndroid Build Coastguard Worker SkScalar scale;
602*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
603*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&scale, &useCropRect);
604*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
605*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
606*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
607*c8dee2aaSAndroid Build Coastguard Worker }
608*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> displacement = make_fuzz_imageFilter(fuzz, depth - 1);
609*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> color = make_fuzz_imageFilter(fuzz, depth - 1);
610*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::DisplacementMap(xChannelSelector, yChannelSelector, scale,
611*c8dee2aaSAndroid Build Coastguard Worker std::move(displacement), std::move(color),
612*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
613*c8dee2aaSAndroid Build Coastguard Worker }
614*c8dee2aaSAndroid Build Coastguard Worker case 7: {
615*c8dee2aaSAndroid Build Coastguard Worker SkScalar dx, dy, sigmaX, sigmaY;
616*c8dee2aaSAndroid Build Coastguard Worker SkColor color;
617*c8dee2aaSAndroid Build Coastguard Worker bool shadowOnly, useCropRect;
618*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&dx, &dy, &sigmaX, &sigmaY, &color, &shadowOnly, &useCropRect);
619*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
620*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
621*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
622*c8dee2aaSAndroid Build Coastguard Worker }
623*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
624*c8dee2aaSAndroid Build Coastguard Worker if (shadowOnly) {
625*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::DropShadowOnly(dx, dy, sigmaX, sigmaY, color,
626*c8dee2aaSAndroid Build Coastguard Worker std::move(input),
627*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
628*c8dee2aaSAndroid Build Coastguard Worker } else {
629*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::DropShadow(dx, dy, sigmaX, sigmaY, color, std::move(input),
630*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
631*c8dee2aaSAndroid Build Coastguard Worker }
632*c8dee2aaSAndroid Build Coastguard Worker }
633*c8dee2aaSAndroid Build Coastguard Worker case 8:
634*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Image(make_fuzz_image(fuzz), SkCubicResampler::Mitchell());
635*c8dee2aaSAndroid Build Coastguard Worker case 9: {
636*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> image = make_fuzz_image(fuzz);
637*c8dee2aaSAndroid Build Coastguard Worker SkRect srcRect, dstRect;
638*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&srcRect, &dstRect);
639*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Image(std::move(image), srcRect, dstRect, next_sampling(fuzz));
640*c8dee2aaSAndroid Build Coastguard Worker }
641*c8dee2aaSAndroid Build Coastguard Worker case 10:
642*c8dee2aaSAndroid Build Coastguard Worker return make_fuzz_lighting_imagefilter(fuzz, depth - 1);
643*c8dee2aaSAndroid Build Coastguard Worker case 11: {
644*c8dee2aaSAndroid Build Coastguard Worker SkRect lensBounds;
645*c8dee2aaSAndroid Build Coastguard Worker SkScalar zoomAmount;
646*c8dee2aaSAndroid Build Coastguard Worker SkScalar inset;
647*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
648*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
649*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&lensBounds, &zoomAmount, &inset, &useCropRect);
650*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
651*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
652*c8dee2aaSAndroid Build Coastguard Worker }
653*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
654*c8dee2aaSAndroid Build Coastguard Worker const auto sampling = next_sampling(fuzz);
655*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Magnifier(lensBounds, zoomAmount, inset, sampling,
656*c8dee2aaSAndroid Build Coastguard Worker std::move(input), useCropRect ? &cropRect : nullptr);
657*c8dee2aaSAndroid Build Coastguard Worker }
658*c8dee2aaSAndroid Build Coastguard Worker case 12: {
659*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMaxKernelSize = 5;
660*c8dee2aaSAndroid Build Coastguard Worker int32_t n, m;
661*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&n, 1, kMaxKernelSize);
662*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&m, 1, kMaxKernelSize);
663*c8dee2aaSAndroid Build Coastguard Worker SkScalar kernel[kMaxKernelSize * kMaxKernelSize];
664*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(kernel, n * m);
665*c8dee2aaSAndroid Build Coastguard Worker int32_t offsetX, offsetY;
666*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&offsetX, 0, n - 1);
667*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&offsetY, 0, m - 1);
668*c8dee2aaSAndroid Build Coastguard Worker SkScalar gain, bias;
669*c8dee2aaSAndroid Build Coastguard Worker bool convolveAlpha, useCropRect;
670*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&gain, &bias, &convolveAlpha, &useCropRect);
671*c8dee2aaSAndroid Build Coastguard Worker SkTileMode tileMode;
672*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&tileMode, SkTileMode::kLastTileMode);
673*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
674*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
675*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
676*c8dee2aaSAndroid Build Coastguard Worker }
677*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
678*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::MatrixConvolution(
679*c8dee2aaSAndroid Build Coastguard Worker SkISize{n, m}, kernel, gain, bias, SkIPoint{offsetX, offsetY}, tileMode,
680*c8dee2aaSAndroid Build Coastguard Worker convolveAlpha, std::move(input), useCropRect ? &cropRect : nullptr);
681*c8dee2aaSAndroid Build Coastguard Worker }
682*c8dee2aaSAndroid Build Coastguard Worker case 13: {
683*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> first = make_fuzz_imageFilter(fuzz, depth - 1);
684*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> second = make_fuzz_imageFilter(fuzz, depth - 1);
685*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
686*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useCropRect);
687*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
688*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
689*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
690*c8dee2aaSAndroid Build Coastguard Worker }
691*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Merge(std::move(first), std::move(second),
692*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
693*c8dee2aaSAndroid Build Coastguard Worker }
694*c8dee2aaSAndroid Build Coastguard Worker case 14: {
695*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMaxCount = 4;
696*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> ifs[kMaxCount];
697*c8dee2aaSAndroid Build Coastguard Worker int count;
698*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&count, 1, kMaxCount);
699*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < count; ++i) {
700*c8dee2aaSAndroid Build Coastguard Worker ifs[i] = make_fuzz_imageFilter(fuzz, depth - 1);
701*c8dee2aaSAndroid Build Coastguard Worker }
702*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
703*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useCropRect);
704*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
705*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
706*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
707*c8dee2aaSAndroid Build Coastguard Worker }
708*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Merge(ifs, count, useCropRect ? &cropRect : nullptr);
709*c8dee2aaSAndroid Build Coastguard Worker }
710*c8dee2aaSAndroid Build Coastguard Worker case 15: {
711*c8dee2aaSAndroid Build Coastguard Worker int rx, ry;
712*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&rx, &ry);
713*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
714*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useCropRect);
715*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
716*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
717*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
718*c8dee2aaSAndroid Build Coastguard Worker }
719*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
720*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Dilate(rx, ry, std::move(input),
721*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
722*c8dee2aaSAndroid Build Coastguard Worker }
723*c8dee2aaSAndroid Build Coastguard Worker case 16: {
724*c8dee2aaSAndroid Build Coastguard Worker int rx, ry;
725*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&rx, &ry);
726*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
727*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useCropRect);
728*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
729*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
730*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
731*c8dee2aaSAndroid Build Coastguard Worker }
732*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
733*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Erode(rx, ry, std::move(input),
734*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
735*c8dee2aaSAndroid Build Coastguard Worker }
736*c8dee2aaSAndroid Build Coastguard Worker case 17: {
737*c8dee2aaSAndroid Build Coastguard Worker SkScalar dx, dy;
738*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&dx, &dy);
739*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
740*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useCropRect);
741*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
742*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
743*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
744*c8dee2aaSAndroid Build Coastguard Worker }
745*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
746*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Offset(dx, dy, std::move(input),
747*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
748*c8dee2aaSAndroid Build Coastguard Worker }
749*c8dee2aaSAndroid Build Coastguard Worker case 18: {
750*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPicture> picture = make_fuzz_picture(fuzz, depth - 1);
751*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Picture(std::move(picture));
752*c8dee2aaSAndroid Build Coastguard Worker }
753*c8dee2aaSAndroid Build Coastguard Worker case 19: {
754*c8dee2aaSAndroid Build Coastguard Worker SkRect cropRect;
755*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
756*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPicture> picture = make_fuzz_picture(fuzz, depth - 1);
757*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Picture(std::move(picture), cropRect);
758*c8dee2aaSAndroid Build Coastguard Worker }
759*c8dee2aaSAndroid Build Coastguard Worker case 20: {
760*c8dee2aaSAndroid Build Coastguard Worker SkRect src, dst;
761*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&src, &dst);
762*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
763*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Tile(src, dst, std::move(input));
764*c8dee2aaSAndroid Build Coastguard Worker }
765*c8dee2aaSAndroid Build Coastguard Worker case 21: {
766*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode blendMode;
767*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
768*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useCropRect);
769*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&blendMode, SkBlendMode::kLastMode);
770*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
771*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
772*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
773*c8dee2aaSAndroid Build Coastguard Worker }
774*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> bg = make_fuzz_imageFilter(fuzz, depth - 1);
775*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> fg = make_fuzz_imageFilter(fuzz, depth - 1);
776*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Blend(blendMode, std::move(bg), std::move(fg),
777*c8dee2aaSAndroid Build Coastguard Worker useCropRect ? &cropRect : nullptr);
778*c8dee2aaSAndroid Build Coastguard Worker }
779*c8dee2aaSAndroid Build Coastguard Worker case 22: {
780*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkShader> shader = make_fuzz_shader(fuzz, depth - 1);
781*c8dee2aaSAndroid Build Coastguard Worker bool useCropRect;
782*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useCropRect);
783*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect;
784*c8dee2aaSAndroid Build Coastguard Worker if (useCropRect) {
785*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&cropRect);
786*c8dee2aaSAndroid Build Coastguard Worker }
787*c8dee2aaSAndroid Build Coastguard Worker return SkImageFilters::Shader(std::move(shader), useCropRect ? &cropRect : nullptr);
788*c8dee2aaSAndroid Build Coastguard Worker }
789*c8dee2aaSAndroid Build Coastguard Worker default:
790*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(false);
791*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
792*c8dee2aaSAndroid Build Coastguard Worker }
793*c8dee2aaSAndroid Build Coastguard Worker }
794*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_image(Fuzz * fuzz)795*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkImage> make_fuzz_image(Fuzz* fuzz) {
796*c8dee2aaSAndroid Build Coastguard Worker int w, h;
797*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&w, 1, 1024);
798*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&h, 1, 1024);
799*c8dee2aaSAndroid Build Coastguard Worker AutoTMalloc<SkPMColor> data(w * h);
800*c8dee2aaSAndroid Build Coastguard Worker SkPixmap pixmap(SkImageInfo::MakeN32Premul(w, h), data.get(), w * sizeof(SkPMColor));
801*c8dee2aaSAndroid Build Coastguard Worker int n = w * h;
802*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < n; ++i) {
803*c8dee2aaSAndroid Build Coastguard Worker SkColor c;
804*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&c);
805*c8dee2aaSAndroid Build Coastguard Worker data[i] = SkPreMultiplyColor(c);
806*c8dee2aaSAndroid Build Coastguard Worker }
807*c8dee2aaSAndroid Build Coastguard Worker (void)data.release();
808*c8dee2aaSAndroid Build Coastguard Worker return SkImages::RasterFromPixmap(
809*c8dee2aaSAndroid Build Coastguard Worker pixmap, [](const void* p, void*) { sk_free(const_cast<void*>(p)); }, nullptr);
810*c8dee2aaSAndroid Build Coastguard Worker }
811*c8dee2aaSAndroid Build Coastguard Worker
812*c8dee2aaSAndroid Build Coastguard Worker template <typename T>
make_fuzz_enum_range(Fuzz * fuzz,T maxv)813*c8dee2aaSAndroid Build Coastguard Worker static T make_fuzz_enum_range(Fuzz* fuzz, T maxv) {
814*c8dee2aaSAndroid Build Coastguard Worker T value;
815*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&value, maxv);
816*c8dee2aaSAndroid Build Coastguard Worker return value;
817*c8dee2aaSAndroid Build Coastguard Worker }
818*c8dee2aaSAndroid Build Coastguard Worker
fuzz_paint(Fuzz * fuzz,SkPaint * paint,int depth)819*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_paint(Fuzz* fuzz, SkPaint* paint, int depth) {
820*c8dee2aaSAndroid Build Coastguard Worker if (!fuzz || !paint || depth <= 0) {
821*c8dee2aaSAndroid Build Coastguard Worker return;
822*c8dee2aaSAndroid Build Coastguard Worker }
823*c8dee2aaSAndroid Build Coastguard Worker
824*c8dee2aaSAndroid Build Coastguard Worker paint->setAntiAlias( make_fuzz_t<bool>(fuzz));
825*c8dee2aaSAndroid Build Coastguard Worker paint->setDither( make_fuzz_t<bool>(fuzz));
826*c8dee2aaSAndroid Build Coastguard Worker paint->setColor( make_fuzz_t<SkColor>(fuzz));
827*c8dee2aaSAndroid Build Coastguard Worker paint->setBlendMode( make_fuzz_enum_range<SkBlendMode>(fuzz, SkBlendMode::kLastMode));
828*c8dee2aaSAndroid Build Coastguard Worker paint->setStyle( make_fuzz_enum_range<SkPaint::Style>(fuzz,
829*c8dee2aaSAndroid Build Coastguard Worker SkPaint::Style::kStrokeAndFill_Style));
830*c8dee2aaSAndroid Build Coastguard Worker paint->setShader( make_fuzz_shader(fuzz, depth - 1));
831*c8dee2aaSAndroid Build Coastguard Worker paint->setPathEffect( make_fuzz_patheffect(fuzz, depth - 1));
832*c8dee2aaSAndroid Build Coastguard Worker paint->setMaskFilter( make_fuzz_maskfilter(fuzz));
833*c8dee2aaSAndroid Build Coastguard Worker paint->setImageFilter( make_fuzz_imageFilter(fuzz, depth - 1));
834*c8dee2aaSAndroid Build Coastguard Worker paint->setColorFilter( make_fuzz_colorfilter(fuzz, depth - 1));
835*c8dee2aaSAndroid Build Coastguard Worker
836*c8dee2aaSAndroid Build Coastguard Worker if (paint->getStyle() != SkPaint::kFill_Style) {
837*c8dee2aaSAndroid Build Coastguard Worker paint->setStrokeWidth(make_fuzz_t<SkScalar>(fuzz));
838*c8dee2aaSAndroid Build Coastguard Worker paint->setStrokeMiter(make_fuzz_t<SkScalar>(fuzz));
839*c8dee2aaSAndroid Build Coastguard Worker paint->setStrokeCap( make_fuzz_enum_range<SkPaint::Cap>(fuzz, SkPaint::kLast_Cap));
840*c8dee2aaSAndroid Build Coastguard Worker paint->setStrokeJoin( make_fuzz_enum_range<SkPaint::Join>(fuzz, SkPaint::kLast_Join));
841*c8dee2aaSAndroid Build Coastguard Worker }
842*c8dee2aaSAndroid Build Coastguard Worker }
843*c8dee2aaSAndroid Build Coastguard Worker
fuzz_font(Fuzz * fuzz)844*c8dee2aaSAndroid Build Coastguard Worker static SkFont fuzz_font(Fuzz* fuzz) {
845*c8dee2aaSAndroid Build Coastguard Worker SkFont font;
846*c8dee2aaSAndroid Build Coastguard Worker font.setTypeface( make_fuzz_typeface(fuzz));
847*c8dee2aaSAndroid Build Coastguard Worker font.setSize( make_fuzz_t<SkScalar>(fuzz));
848*c8dee2aaSAndroid Build Coastguard Worker font.setScaleX( make_fuzz_t<SkScalar>(fuzz));
849*c8dee2aaSAndroid Build Coastguard Worker font.setSkewX( make_fuzz_t<SkScalar>(fuzz));
850*c8dee2aaSAndroid Build Coastguard Worker font.setLinearMetrics( make_fuzz_t<bool>(fuzz));
851*c8dee2aaSAndroid Build Coastguard Worker font.setSubpixel( make_fuzz_t<bool>(fuzz));
852*c8dee2aaSAndroid Build Coastguard Worker font.setEmbeddedBitmaps( make_fuzz_t<bool>(fuzz));
853*c8dee2aaSAndroid Build Coastguard Worker font.setForceAutoHinting( make_fuzz_t<bool>(fuzz));
854*c8dee2aaSAndroid Build Coastguard Worker font.setEmbolden( make_fuzz_t<bool>(fuzz));
855*c8dee2aaSAndroid Build Coastguard Worker font.setHinting( make_fuzz_enum_range<SkFontHinting>(fuzz, SkFontHinting::kFull));
856*c8dee2aaSAndroid Build Coastguard Worker font.setEdging( make_fuzz_enum_range<SkFont::Edging>(fuzz,
857*c8dee2aaSAndroid Build Coastguard Worker SkFont::Edging::kSubpixelAntiAlias));
858*c8dee2aaSAndroid Build Coastguard Worker return font;
859*c8dee2aaSAndroid Build Coastguard Worker }
860*c8dee2aaSAndroid Build Coastguard Worker
fuzz_paint_text_encoding(Fuzz * fuzz)861*c8dee2aaSAndroid Build Coastguard Worker static SkTextEncoding fuzz_paint_text_encoding(Fuzz* fuzz) {
862*c8dee2aaSAndroid Build Coastguard Worker return make_fuzz_enum_range<SkTextEncoding>(fuzz, SkTextEncoding::kUTF32);
863*c8dee2aaSAndroid Build Coastguard Worker }
864*c8dee2aaSAndroid Build Coastguard Worker
865*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMaxGlyphCount = 30;
866*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_text(Fuzz * fuzz,const SkFont & font,SkTextEncoding encoding)867*c8dee2aaSAndroid Build Coastguard Worker static SkTDArray<uint8_t> make_fuzz_text(Fuzz* fuzz, const SkFont& font, SkTextEncoding encoding) {
868*c8dee2aaSAndroid Build Coastguard Worker SkTDArray<uint8_t> array;
869*c8dee2aaSAndroid Build Coastguard Worker if (SkTextEncoding::kGlyphID == encoding) {
870*c8dee2aaSAndroid Build Coastguard Worker int glyphRange = font.getTypeface()->countGlyphs();
871*c8dee2aaSAndroid Build Coastguard Worker if (glyphRange == 0) {
872*c8dee2aaSAndroid Build Coastguard Worker // Some fuzzing environments have no fonts, so empty array is the best
873*c8dee2aaSAndroid Build Coastguard Worker // we can do.
874*c8dee2aaSAndroid Build Coastguard Worker return array;
875*c8dee2aaSAndroid Build Coastguard Worker }
876*c8dee2aaSAndroid Build Coastguard Worker int glyphCount;
877*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&glyphCount, 1, kMaxGlyphCount);
878*c8dee2aaSAndroid Build Coastguard Worker SkGlyphID* glyphs = (SkGlyphID*)array.append(glyphCount * sizeof(SkGlyphID));
879*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < glyphCount; ++i) {
880*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&glyphs[i], 0, glyphRange - 1);
881*c8dee2aaSAndroid Build Coastguard Worker }
882*c8dee2aaSAndroid Build Coastguard Worker return array;
883*c8dee2aaSAndroid Build Coastguard Worker }
884*c8dee2aaSAndroid Build Coastguard Worker static const SkUnichar ranges[][2] = {
885*c8dee2aaSAndroid Build Coastguard Worker {0x0020, 0x007F},
886*c8dee2aaSAndroid Build Coastguard Worker {0x00A1, 0x0250},
887*c8dee2aaSAndroid Build Coastguard Worker {0x0400, 0x0500},
888*c8dee2aaSAndroid Build Coastguard Worker };
889*c8dee2aaSAndroid Build Coastguard Worker int32_t count = 0;
890*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < std::size(ranges); ++i) {
891*c8dee2aaSAndroid Build Coastguard Worker count += (ranges[i][1] - ranges[i][0]);
892*c8dee2aaSAndroid Build Coastguard Worker }
893*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMaxLength = kMaxGlyphCount;
894*c8dee2aaSAndroid Build Coastguard Worker SkUnichar buffer[kMaxLength];
895*c8dee2aaSAndroid Build Coastguard Worker int length;
896*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&length, 1, kMaxLength);
897*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < length; ++j) {
898*c8dee2aaSAndroid Build Coastguard Worker int32_t value;
899*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&value, 0, count - 1);
900*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < std::size(ranges); ++i) {
901*c8dee2aaSAndroid Build Coastguard Worker if (value + ranges[i][0] < ranges[i][1]) {
902*c8dee2aaSAndroid Build Coastguard Worker buffer[j] = value + ranges[i][0];
903*c8dee2aaSAndroid Build Coastguard Worker break;
904*c8dee2aaSAndroid Build Coastguard Worker } else {
905*c8dee2aaSAndroid Build Coastguard Worker value -= (ranges[i][1] - ranges[i][0]);
906*c8dee2aaSAndroid Build Coastguard Worker }
907*c8dee2aaSAndroid Build Coastguard Worker }
908*c8dee2aaSAndroid Build Coastguard Worker }
909*c8dee2aaSAndroid Build Coastguard Worker switch (encoding) {
910*c8dee2aaSAndroid Build Coastguard Worker case SkTextEncoding::kUTF8: {
911*c8dee2aaSAndroid Build Coastguard Worker size_t utf8len = 0;
912*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < length; ++j) {
913*c8dee2aaSAndroid Build Coastguard Worker utf8len += SkUTF::ToUTF8(buffer[j], nullptr);
914*c8dee2aaSAndroid Build Coastguard Worker }
915*c8dee2aaSAndroid Build Coastguard Worker char* ptr = (char*)array.append(utf8len);
916*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < length; ++j) {
917*c8dee2aaSAndroid Build Coastguard Worker ptr += SkUTF::ToUTF8(buffer[j], ptr);
918*c8dee2aaSAndroid Build Coastguard Worker }
919*c8dee2aaSAndroid Build Coastguard Worker } break;
920*c8dee2aaSAndroid Build Coastguard Worker case SkTextEncoding::kUTF16: {
921*c8dee2aaSAndroid Build Coastguard Worker size_t utf16len = 0;
922*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < length; ++j) {
923*c8dee2aaSAndroid Build Coastguard Worker utf16len += SkUTF::ToUTF16(buffer[j]);
924*c8dee2aaSAndroid Build Coastguard Worker }
925*c8dee2aaSAndroid Build Coastguard Worker uint16_t* ptr = (uint16_t*)array.append(utf16len * sizeof(uint16_t));
926*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < length; ++j) {
927*c8dee2aaSAndroid Build Coastguard Worker ptr += SkUTF::ToUTF16(buffer[j], ptr);
928*c8dee2aaSAndroid Build Coastguard Worker }
929*c8dee2aaSAndroid Build Coastguard Worker } break;
930*c8dee2aaSAndroid Build Coastguard Worker case SkTextEncoding::kUTF32:
931*c8dee2aaSAndroid Build Coastguard Worker memcpy(array.append(length * sizeof(SkUnichar)), buffer, length * sizeof(SkUnichar));
932*c8dee2aaSAndroid Build Coastguard Worker break;
933*c8dee2aaSAndroid Build Coastguard Worker default:
934*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(false);
935*c8dee2aaSAndroid Build Coastguard Worker break;
936*c8dee2aaSAndroid Build Coastguard Worker }
937*c8dee2aaSAndroid Build Coastguard Worker return array;
938*c8dee2aaSAndroid Build Coastguard Worker }
939*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_string(Fuzz * fuzz)940*c8dee2aaSAndroid Build Coastguard Worker static std::string make_fuzz_string(Fuzz* fuzz) {
941*c8dee2aaSAndroid Build Coastguard Worker int len;
942*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&len, 0, kMaxGlyphCount);
943*c8dee2aaSAndroid Build Coastguard Worker std::string str(len, 0);
944*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < len; i++) {
945*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&str[i]);
946*c8dee2aaSAndroid Build Coastguard Worker }
947*c8dee2aaSAndroid Build Coastguard Worker return str;
948*c8dee2aaSAndroid Build Coastguard Worker }
949*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_textblob(Fuzz * fuzz)950*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkTextBlob> make_fuzz_textblob(Fuzz* fuzz) {
951*c8dee2aaSAndroid Build Coastguard Worker SkTextBlobBuilder textBlobBuilder;
952*c8dee2aaSAndroid Build Coastguard Worker int8_t runCount;
953*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&runCount, (int8_t)1, (int8_t)8);
954*c8dee2aaSAndroid Build Coastguard Worker while (runCount-- > 0) {
955*c8dee2aaSAndroid Build Coastguard Worker SkFont font = ToolUtils::DefaultFont();
956*c8dee2aaSAndroid Build Coastguard Worker SkTextEncoding encoding = fuzz_paint_text_encoding(fuzz);
957*c8dee2aaSAndroid Build Coastguard Worker font.setEdging(make_fuzz_t<bool>(fuzz) ? SkFont::Edging::kAlias : SkFont::Edging::kAntiAlias);
958*c8dee2aaSAndroid Build Coastguard Worker SkTDArray<uint8_t> text = make_fuzz_text(fuzz, font, encoding);
959*c8dee2aaSAndroid Build Coastguard Worker int glyphCount = font.countText(text.begin(), SkToSizeT(text.size()), encoding);
960*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(glyphCount <= kMaxGlyphCount);
961*c8dee2aaSAndroid Build Coastguard Worker SkScalar x, y;
962*c8dee2aaSAndroid Build Coastguard Worker const SkTextBlobBuilder::RunBuffer* buffer;
963*c8dee2aaSAndroid Build Coastguard Worker uint8_t runType;
964*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&runType, (uint8_t)0, (uint8_t)2);
965*c8dee2aaSAndroid Build Coastguard Worker const void* textPtr = text.begin();
966*c8dee2aaSAndroid Build Coastguard Worker size_t textLen = SkToSizeT(text.size());
967*c8dee2aaSAndroid Build Coastguard Worker switch (runType) {
968*c8dee2aaSAndroid Build Coastguard Worker case 0:
969*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&x, &y);
970*c8dee2aaSAndroid Build Coastguard Worker // TODO: Test other variations of this.
971*c8dee2aaSAndroid Build Coastguard Worker buffer = &textBlobBuilder.allocRun(font, glyphCount, x, y);
972*c8dee2aaSAndroid Build Coastguard Worker (void)font.textToGlyphs(textPtr, textLen, encoding, buffer->glyphs, glyphCount);
973*c8dee2aaSAndroid Build Coastguard Worker break;
974*c8dee2aaSAndroid Build Coastguard Worker case 1:
975*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&y);
976*c8dee2aaSAndroid Build Coastguard Worker // TODO: Test other variations of this.
977*c8dee2aaSAndroid Build Coastguard Worker buffer = &textBlobBuilder.allocRunPosH(font, glyphCount, y);
978*c8dee2aaSAndroid Build Coastguard Worker (void)font.textToGlyphs(textPtr, textLen, encoding, buffer->glyphs, glyphCount);
979*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(buffer->pos, glyphCount);
980*c8dee2aaSAndroid Build Coastguard Worker break;
981*c8dee2aaSAndroid Build Coastguard Worker case 2:
982*c8dee2aaSAndroid Build Coastguard Worker // TODO: Test other variations of this.
983*c8dee2aaSAndroid Build Coastguard Worker buffer = &textBlobBuilder.allocRunPos(font, glyphCount);
984*c8dee2aaSAndroid Build Coastguard Worker (void)font.textToGlyphs(textPtr, textLen, encoding, buffer->glyphs, glyphCount);
985*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(buffer->pos, glyphCount * 2);
986*c8dee2aaSAndroid Build Coastguard Worker break;
987*c8dee2aaSAndroid Build Coastguard Worker default:
988*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(false);
989*c8dee2aaSAndroid Build Coastguard Worker break;
990*c8dee2aaSAndroid Build Coastguard Worker }
991*c8dee2aaSAndroid Build Coastguard Worker }
992*c8dee2aaSAndroid Build Coastguard Worker return textBlobBuilder.make();
993*c8dee2aaSAndroid Build Coastguard Worker }
994*c8dee2aaSAndroid Build Coastguard Worker
fuzz_canvas(Fuzz * fuzz,SkCanvas * canvas,int depth=9)995*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) {
996*c8dee2aaSAndroid Build Coastguard Worker if (!fuzz || !canvas || depth <= 0) {
997*c8dee2aaSAndroid Build Coastguard Worker return;
998*c8dee2aaSAndroid Build Coastguard Worker }
999*c8dee2aaSAndroid Build Coastguard Worker SkAutoCanvasRestore autoCanvasRestore(canvas, false);
1000*c8dee2aaSAndroid Build Coastguard Worker unsigned N;
1001*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&N, 0, 2000);
1002*c8dee2aaSAndroid Build Coastguard Worker for (unsigned loop = 0; loop < N; ++loop) {
1003*c8dee2aaSAndroid Build Coastguard Worker if (fuzz->exhausted()) {
1004*c8dee2aaSAndroid Build Coastguard Worker return;
1005*c8dee2aaSAndroid Build Coastguard Worker }
1006*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
1007*c8dee2aaSAndroid Build Coastguard Worker SkFont font = ToolUtils::DefaultFont();
1008*c8dee2aaSAndroid Build Coastguard Worker unsigned drawCommand;
1009*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&drawCommand, 0, 62);
1010*c8dee2aaSAndroid Build Coastguard Worker switch (drawCommand) {
1011*c8dee2aaSAndroid Build Coastguard Worker case 0:
1012*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_GANESH)
1013*c8dee2aaSAndroid Build Coastguard Worker if (auto dContext = GrAsDirectContext(canvas->recordingContext())) {
1014*c8dee2aaSAndroid Build Coastguard Worker dContext->flushAndSubmit();
1015*c8dee2aaSAndroid Build Coastguard Worker }
1016*c8dee2aaSAndroid Build Coastguard Worker #endif
1017*c8dee2aaSAndroid Build Coastguard Worker break;
1018*c8dee2aaSAndroid Build Coastguard Worker case 1:
1019*c8dee2aaSAndroid Build Coastguard Worker canvas->save();
1020*c8dee2aaSAndroid Build Coastguard Worker break;
1021*c8dee2aaSAndroid Build Coastguard Worker case 2: {
1022*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds;
1023*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&bounds);
1024*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1025*c8dee2aaSAndroid Build Coastguard Worker canvas->saveLayer(&bounds, &paint);
1026*c8dee2aaSAndroid Build Coastguard Worker break;
1027*c8dee2aaSAndroid Build Coastguard Worker }
1028*c8dee2aaSAndroid Build Coastguard Worker case 3: {
1029*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds;
1030*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&bounds);
1031*c8dee2aaSAndroid Build Coastguard Worker canvas->saveLayer(&bounds, nullptr);
1032*c8dee2aaSAndroid Build Coastguard Worker break;
1033*c8dee2aaSAndroid Build Coastguard Worker }
1034*c8dee2aaSAndroid Build Coastguard Worker case 4:
1035*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1036*c8dee2aaSAndroid Build Coastguard Worker canvas->saveLayer(nullptr, &paint);
1037*c8dee2aaSAndroid Build Coastguard Worker break;
1038*c8dee2aaSAndroid Build Coastguard Worker case 5:
1039*c8dee2aaSAndroid Build Coastguard Worker canvas->saveLayer(nullptr, nullptr);
1040*c8dee2aaSAndroid Build Coastguard Worker break;
1041*c8dee2aaSAndroid Build Coastguard Worker case 6: {
1042*c8dee2aaSAndroid Build Coastguard Worker uint8_t alpha;
1043*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&alpha);
1044*c8dee2aaSAndroid Build Coastguard Worker canvas->saveLayerAlpha(nullptr, (U8CPU)alpha);
1045*c8dee2aaSAndroid Build Coastguard Worker break;
1046*c8dee2aaSAndroid Build Coastguard Worker }
1047*c8dee2aaSAndroid Build Coastguard Worker case 7: {
1048*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds;
1049*c8dee2aaSAndroid Build Coastguard Worker uint8_t alpha;
1050*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&bounds, &alpha);
1051*c8dee2aaSAndroid Build Coastguard Worker canvas->saveLayerAlpha(&bounds, (U8CPU)alpha);
1052*c8dee2aaSAndroid Build Coastguard Worker break;
1053*c8dee2aaSAndroid Build Coastguard Worker }
1054*c8dee2aaSAndroid Build Coastguard Worker case 8: {
1055*c8dee2aaSAndroid Build Coastguard Worker SkCanvas::SaveLayerRec saveLayerRec;
1056*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds;
1057*c8dee2aaSAndroid Build Coastguard Worker if (make_fuzz_t<bool>(fuzz)) {
1058*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&bounds);
1059*c8dee2aaSAndroid Build Coastguard Worker saveLayerRec.fBounds = &bounds;
1060*c8dee2aaSAndroid Build Coastguard Worker }
1061*c8dee2aaSAndroid Build Coastguard Worker if (make_fuzz_t<bool>(fuzz)) {
1062*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1063*c8dee2aaSAndroid Build Coastguard Worker saveLayerRec.fPaint = &paint;
1064*c8dee2aaSAndroid Build Coastguard Worker }
1065*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> imageFilter;
1066*c8dee2aaSAndroid Build Coastguard Worker if (make_fuzz_t<bool>(fuzz)) {
1067*c8dee2aaSAndroid Build Coastguard Worker imageFilter = make_fuzz_imageFilter(fuzz, depth - 1);
1068*c8dee2aaSAndroid Build Coastguard Worker saveLayerRec.fBackdrop = imageFilter.get();
1069*c8dee2aaSAndroid Build Coastguard Worker }
1070*c8dee2aaSAndroid Build Coastguard Worker // _DumpCanvas can't handle this.
1071*c8dee2aaSAndroid Build Coastguard Worker // if (make_fuzz_t<bool>(fuzz)) {
1072*c8dee2aaSAndroid Build Coastguard Worker // saveLayerRec.fSaveLayerFlags |= SkCanvas::kPreserveLCDText_SaveLayerFlag;
1073*c8dee2aaSAndroid Build Coastguard Worker // }
1074*c8dee2aaSAndroid Build Coastguard Worker
1075*c8dee2aaSAndroid Build Coastguard Worker canvas->saveLayer(saveLayerRec);
1076*c8dee2aaSAndroid Build Coastguard Worker break;
1077*c8dee2aaSAndroid Build Coastguard Worker }
1078*c8dee2aaSAndroid Build Coastguard Worker case 9:
1079*c8dee2aaSAndroid Build Coastguard Worker canvas->restore();
1080*c8dee2aaSAndroid Build Coastguard Worker break;
1081*c8dee2aaSAndroid Build Coastguard Worker case 10: {
1082*c8dee2aaSAndroid Build Coastguard Worker int saveCount;
1083*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&saveCount);
1084*c8dee2aaSAndroid Build Coastguard Worker canvas->restoreToCount(saveCount);
1085*c8dee2aaSAndroid Build Coastguard Worker break;
1086*c8dee2aaSAndroid Build Coastguard Worker }
1087*c8dee2aaSAndroid Build Coastguard Worker case 11: {
1088*c8dee2aaSAndroid Build Coastguard Worker SkScalar x, y;
1089*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&x, &y);
1090*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(x, y);
1091*c8dee2aaSAndroid Build Coastguard Worker break;
1092*c8dee2aaSAndroid Build Coastguard Worker }
1093*c8dee2aaSAndroid Build Coastguard Worker case 12: {
1094*c8dee2aaSAndroid Build Coastguard Worker SkScalar x, y;
1095*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&x, &y);
1096*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(x, y);
1097*c8dee2aaSAndroid Build Coastguard Worker break;
1098*c8dee2aaSAndroid Build Coastguard Worker }
1099*c8dee2aaSAndroid Build Coastguard Worker case 13: {
1100*c8dee2aaSAndroid Build Coastguard Worker SkScalar v;
1101*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&v);
1102*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(v);
1103*c8dee2aaSAndroid Build Coastguard Worker break;
1104*c8dee2aaSAndroid Build Coastguard Worker }
1105*c8dee2aaSAndroid Build Coastguard Worker case 14: {
1106*c8dee2aaSAndroid Build Coastguard Worker SkScalar x, y, v;
1107*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&x, &y, &v);
1108*c8dee2aaSAndroid Build Coastguard Worker canvas->rotate(v, x, y);
1109*c8dee2aaSAndroid Build Coastguard Worker break;
1110*c8dee2aaSAndroid Build Coastguard Worker }
1111*c8dee2aaSAndroid Build Coastguard Worker case 15: {
1112*c8dee2aaSAndroid Build Coastguard Worker SkScalar x, y;
1113*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&x, &y);
1114*c8dee2aaSAndroid Build Coastguard Worker canvas->skew(x, y);
1115*c8dee2aaSAndroid Build Coastguard Worker break;
1116*c8dee2aaSAndroid Build Coastguard Worker }
1117*c8dee2aaSAndroid Build Coastguard Worker case 16: {
1118*c8dee2aaSAndroid Build Coastguard Worker SkMatrix mat;
1119*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &mat);
1120*c8dee2aaSAndroid Build Coastguard Worker canvas->concat(mat);
1121*c8dee2aaSAndroid Build Coastguard Worker break;
1122*c8dee2aaSAndroid Build Coastguard Worker }
1123*c8dee2aaSAndroid Build Coastguard Worker case 17: {
1124*c8dee2aaSAndroid Build Coastguard Worker SkMatrix mat;
1125*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &mat);
1126*c8dee2aaSAndroid Build Coastguard Worker canvas->setMatrix(mat);
1127*c8dee2aaSAndroid Build Coastguard Worker break;
1128*c8dee2aaSAndroid Build Coastguard Worker }
1129*c8dee2aaSAndroid Build Coastguard Worker case 18:
1130*c8dee2aaSAndroid Build Coastguard Worker canvas->resetMatrix();
1131*c8dee2aaSAndroid Build Coastguard Worker break;
1132*c8dee2aaSAndroid Build Coastguard Worker case 19: {
1133*c8dee2aaSAndroid Build Coastguard Worker SkRect r;
1134*c8dee2aaSAndroid Build Coastguard Worker int op;
1135*c8dee2aaSAndroid Build Coastguard Worker bool doAntiAlias;
1136*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&r, &doAntiAlias);
1137*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&op, 0, 1);
1138*c8dee2aaSAndroid Build Coastguard Worker r.sort();
1139*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect(r, (SkClipOp)op, doAntiAlias);
1140*c8dee2aaSAndroid Build Coastguard Worker break;
1141*c8dee2aaSAndroid Build Coastguard Worker }
1142*c8dee2aaSAndroid Build Coastguard Worker case 20: {
1143*c8dee2aaSAndroid Build Coastguard Worker SkRRect rr;
1144*c8dee2aaSAndroid Build Coastguard Worker int op;
1145*c8dee2aaSAndroid Build Coastguard Worker bool doAntiAlias;
1146*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceRRect(fuzz, &rr);
1147*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&doAntiAlias);
1148*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&op, 0, 1);
1149*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRRect(rr, (SkClipOp)op, doAntiAlias);
1150*c8dee2aaSAndroid Build Coastguard Worker break;
1151*c8dee2aaSAndroid Build Coastguard Worker }
1152*c8dee2aaSAndroid Build Coastguard Worker case 21: {
1153*c8dee2aaSAndroid Build Coastguard Worker SkPath path;
1154*c8dee2aaSAndroid Build Coastguard Worker FuzzNicePath(fuzz, &path, 30);
1155*c8dee2aaSAndroid Build Coastguard Worker int op;
1156*c8dee2aaSAndroid Build Coastguard Worker bool doAntiAlias;
1157*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&doAntiAlias);
1158*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&op, 0, 1);
1159*c8dee2aaSAndroid Build Coastguard Worker canvas->clipPath(path, (SkClipOp)op, doAntiAlias);
1160*c8dee2aaSAndroid Build Coastguard Worker break;
1161*c8dee2aaSAndroid Build Coastguard Worker }
1162*c8dee2aaSAndroid Build Coastguard Worker case 22: {
1163*c8dee2aaSAndroid Build Coastguard Worker SkRegion region;
1164*c8dee2aaSAndroid Build Coastguard Worker int op;
1165*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(®ion);
1166*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&op, 0, 1);
1167*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRegion(region, (SkClipOp)op);
1168*c8dee2aaSAndroid Build Coastguard Worker break;
1169*c8dee2aaSAndroid Build Coastguard Worker }
1170*c8dee2aaSAndroid Build Coastguard Worker case 23:
1171*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1172*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPaint(paint);
1173*c8dee2aaSAndroid Build Coastguard Worker break;
1174*c8dee2aaSAndroid Build Coastguard Worker case 24: {
1175*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1176*c8dee2aaSAndroid Build Coastguard Worker SkCanvas::PointMode pointMode;
1177*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&pointMode,
1178*c8dee2aaSAndroid Build Coastguard Worker SkCanvas::kPoints_PointMode, SkCanvas::kPolygon_PointMode);
1179*c8dee2aaSAndroid Build Coastguard Worker size_t count;
1180*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMaxCount = 30;
1181*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&count, 0, kMaxCount);
1182*c8dee2aaSAndroid Build Coastguard Worker SkPoint pts[kMaxCount];
1183*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(pts, count);
1184*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPoints(pointMode, count, pts, paint);
1185*c8dee2aaSAndroid Build Coastguard Worker break;
1186*c8dee2aaSAndroid Build Coastguard Worker }
1187*c8dee2aaSAndroid Build Coastguard Worker case 25: {
1188*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1189*c8dee2aaSAndroid Build Coastguard Worker SkRect r;
1190*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&r);
1191*c8dee2aaSAndroid Build Coastguard Worker if (!r.isFinite()) {
1192*c8dee2aaSAndroid Build Coastguard Worker break;
1193*c8dee2aaSAndroid Build Coastguard Worker }
1194*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(r, paint);
1195*c8dee2aaSAndroid Build Coastguard Worker break;
1196*c8dee2aaSAndroid Build Coastguard Worker }
1197*c8dee2aaSAndroid Build Coastguard Worker case 26: {
1198*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1199*c8dee2aaSAndroid Build Coastguard Worker SkRegion region;
1200*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(®ion);
1201*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRegion(region, paint);
1202*c8dee2aaSAndroid Build Coastguard Worker break;
1203*c8dee2aaSAndroid Build Coastguard Worker }
1204*c8dee2aaSAndroid Build Coastguard Worker case 27: {
1205*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1206*c8dee2aaSAndroid Build Coastguard Worker SkRect r;
1207*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&r);
1208*c8dee2aaSAndroid Build Coastguard Worker if (!r.isFinite()) {
1209*c8dee2aaSAndroid Build Coastguard Worker break;
1210*c8dee2aaSAndroid Build Coastguard Worker }
1211*c8dee2aaSAndroid Build Coastguard Worker canvas->drawOval(r, paint);
1212*c8dee2aaSAndroid Build Coastguard Worker break;
1213*c8dee2aaSAndroid Build Coastguard Worker }
1214*c8dee2aaSAndroid Build Coastguard Worker case 28: break; // must have deleted this some time earlier
1215*c8dee2aaSAndroid Build Coastguard Worker case 29: {
1216*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1217*c8dee2aaSAndroid Build Coastguard Worker SkRRect rr;
1218*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceRRect(fuzz, &rr);
1219*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRRect(rr, paint);
1220*c8dee2aaSAndroid Build Coastguard Worker break;
1221*c8dee2aaSAndroid Build Coastguard Worker }
1222*c8dee2aaSAndroid Build Coastguard Worker case 30: {
1223*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1224*c8dee2aaSAndroid Build Coastguard Worker SkRRect orr, irr;
1225*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceRRect(fuzz, &orr);
1226*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceRRect(fuzz, &irr);
1227*c8dee2aaSAndroid Build Coastguard Worker if (orr.getBounds().contains(irr.getBounds())) {
1228*c8dee2aaSAndroid Build Coastguard Worker canvas->drawDRRect(orr, irr, paint);
1229*c8dee2aaSAndroid Build Coastguard Worker }
1230*c8dee2aaSAndroid Build Coastguard Worker break;
1231*c8dee2aaSAndroid Build Coastguard Worker }
1232*c8dee2aaSAndroid Build Coastguard Worker case 31: {
1233*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1234*c8dee2aaSAndroid Build Coastguard Worker SkRect r;
1235*c8dee2aaSAndroid Build Coastguard Worker SkScalar start, sweep;
1236*c8dee2aaSAndroid Build Coastguard Worker bool useCenter;
1237*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&r, &start, &sweep, &useCenter);
1238*c8dee2aaSAndroid Build Coastguard Worker canvas->drawArc(r, start, sweep, useCenter, paint);
1239*c8dee2aaSAndroid Build Coastguard Worker break;
1240*c8dee2aaSAndroid Build Coastguard Worker }
1241*c8dee2aaSAndroid Build Coastguard Worker case 32: {
1242*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1243*c8dee2aaSAndroid Build Coastguard Worker SkPath path;
1244*c8dee2aaSAndroid Build Coastguard Worker FuzzNicePath(fuzz, &path, 60);
1245*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, paint);
1246*c8dee2aaSAndroid Build Coastguard Worker break;
1247*c8dee2aaSAndroid Build Coastguard Worker }
1248*c8dee2aaSAndroid Build Coastguard Worker case 33: {
1249*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> img = make_fuzz_image(fuzz);
1250*c8dee2aaSAndroid Build Coastguard Worker SkScalar left, top;
1251*c8dee2aaSAndroid Build Coastguard Worker bool usePaint;
1252*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&left, &top, &usePaint);
1253*c8dee2aaSAndroid Build Coastguard Worker if (usePaint) {
1254*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1255*c8dee2aaSAndroid Build Coastguard Worker }
1256*c8dee2aaSAndroid Build Coastguard Worker canvas->drawImage(img.get(), left, top, SkSamplingOptions(),
1257*c8dee2aaSAndroid Build Coastguard Worker usePaint ? &paint : nullptr);
1258*c8dee2aaSAndroid Build Coastguard Worker break;
1259*c8dee2aaSAndroid Build Coastguard Worker }
1260*c8dee2aaSAndroid Build Coastguard Worker case 35: {
1261*c8dee2aaSAndroid Build Coastguard Worker auto img = make_fuzz_image(fuzz);
1262*c8dee2aaSAndroid Build Coastguard Worker SkIRect src;
1263*c8dee2aaSAndroid Build Coastguard Worker SkRect dst;
1264*c8dee2aaSAndroid Build Coastguard Worker bool usePaint;
1265*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&src, &dst, &usePaint);
1266*c8dee2aaSAndroid Build Coastguard Worker if (usePaint) {
1267*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1268*c8dee2aaSAndroid Build Coastguard Worker }
1269*c8dee2aaSAndroid Build Coastguard Worker SkCanvas::SrcRectConstraint constraint =
1270*c8dee2aaSAndroid Build Coastguard Worker make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
1271*c8dee2aaSAndroid Build Coastguard Worker : SkCanvas::kFast_SrcRectConstraint;
1272*c8dee2aaSAndroid Build Coastguard Worker canvas->drawImageRect(img.get(), SkRect::Make(src), dst, SkSamplingOptions(),
1273*c8dee2aaSAndroid Build Coastguard Worker usePaint ? &paint : nullptr, constraint);
1274*c8dee2aaSAndroid Build Coastguard Worker break;
1275*c8dee2aaSAndroid Build Coastguard Worker }
1276*c8dee2aaSAndroid Build Coastguard Worker case 37: {
1277*c8dee2aaSAndroid Build Coastguard Worker auto img = make_fuzz_image(fuzz);
1278*c8dee2aaSAndroid Build Coastguard Worker SkIRect center;
1279*c8dee2aaSAndroid Build Coastguard Worker SkRect dst;
1280*c8dee2aaSAndroid Build Coastguard Worker bool usePaint;
1281*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&usePaint);
1282*c8dee2aaSAndroid Build Coastguard Worker if (usePaint) {
1283*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1284*c8dee2aaSAndroid Build Coastguard Worker }
1285*c8dee2aaSAndroid Build Coastguard Worker if (make_fuzz_t<bool>(fuzz)) {
1286*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(¢er);
1287*c8dee2aaSAndroid Build Coastguard Worker } else { // Make valid center, see SkLatticeIter::Valid().
1288*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(¢er.fLeft, 0, img->width() - 1);
1289*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(¢er.fTop, 0, img->height() - 1);
1290*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(¢er.fRight, center.fLeft + 1, img->width());
1291*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(¢er.fBottom, center.fTop + 1, img->height());
1292*c8dee2aaSAndroid Build Coastguard Worker }
1293*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&dst);
1294*c8dee2aaSAndroid Build Coastguard Worker canvas->drawImageNine(img.get(), center, dst, SkFilterMode::kNearest,
1295*c8dee2aaSAndroid Build Coastguard Worker usePaint ? &paint : nullptr);
1296*c8dee2aaSAndroid Build Coastguard Worker break;
1297*c8dee2aaSAndroid Build Coastguard Worker }
1298*c8dee2aaSAndroid Build Coastguard Worker case 44: {
1299*c8dee2aaSAndroid Build Coastguard Worker auto img = make_fuzz_image(fuzz);
1300*c8dee2aaSAndroid Build Coastguard Worker bool usePaint;
1301*c8dee2aaSAndroid Build Coastguard Worker SkRect dst;
1302*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&usePaint, &dst);
1303*c8dee2aaSAndroid Build Coastguard Worker if (usePaint) {
1304*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1305*c8dee2aaSAndroid Build Coastguard Worker }
1306*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMax = 6;
1307*c8dee2aaSAndroid Build Coastguard Worker int xDivs[kMax], yDivs[kMax];
1308*c8dee2aaSAndroid Build Coastguard Worker SkCanvas::Lattice lattice{xDivs, yDivs, nullptr, 0, 0, nullptr, nullptr};
1309*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&lattice.fXCount, 2, kMax);
1310*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&lattice.fYCount, 2, kMax);
1311*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(xDivs, lattice.fXCount);
1312*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(yDivs, lattice.fYCount);
1313*c8dee2aaSAndroid Build Coastguard Worker canvas->drawImageLattice(img.get(), lattice, dst, SkFilterMode::kLinear,
1314*c8dee2aaSAndroid Build Coastguard Worker usePaint ? &paint : nullptr);
1315*c8dee2aaSAndroid Build Coastguard Worker break;
1316*c8dee2aaSAndroid Build Coastguard Worker }
1317*c8dee2aaSAndroid Build Coastguard Worker case 45: {
1318*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1319*c8dee2aaSAndroid Build Coastguard Worker font = fuzz_font(fuzz);
1320*c8dee2aaSAndroid Build Coastguard Worker SkTextEncoding encoding = fuzz_paint_text_encoding(fuzz);
1321*c8dee2aaSAndroid Build Coastguard Worker SkScalar x, y;
1322*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&x, &y);
1323*c8dee2aaSAndroid Build Coastguard Worker SkTDArray<uint8_t> text = make_fuzz_text(fuzz, font, encoding);
1324*c8dee2aaSAndroid Build Coastguard Worker canvas->drawSimpleText(text.begin(), SkToSizeT(text.size()), encoding, x, y,
1325*c8dee2aaSAndroid Build Coastguard Worker font, paint);
1326*c8dee2aaSAndroid Build Coastguard Worker break;
1327*c8dee2aaSAndroid Build Coastguard Worker }
1328*c8dee2aaSAndroid Build Coastguard Worker case 46: {
1329*c8dee2aaSAndroid Build Coastguard Worker // was drawPosText
1330*c8dee2aaSAndroid Build Coastguard Worker break;
1331*c8dee2aaSAndroid Build Coastguard Worker }
1332*c8dee2aaSAndroid Build Coastguard Worker case 47: {
1333*c8dee2aaSAndroid Build Coastguard Worker // was drawPosTextH
1334*c8dee2aaSAndroid Build Coastguard Worker break;
1335*c8dee2aaSAndroid Build Coastguard Worker }
1336*c8dee2aaSAndroid Build Coastguard Worker case 48: {
1337*c8dee2aaSAndroid Build Coastguard Worker // was drawtextonpath
1338*c8dee2aaSAndroid Build Coastguard Worker break;
1339*c8dee2aaSAndroid Build Coastguard Worker }
1340*c8dee2aaSAndroid Build Coastguard Worker case 49: {
1341*c8dee2aaSAndroid Build Coastguard Worker // was drawtextonpath
1342*c8dee2aaSAndroid Build Coastguard Worker break;
1343*c8dee2aaSAndroid Build Coastguard Worker }
1344*c8dee2aaSAndroid Build Coastguard Worker case 50: {
1345*c8dee2aaSAndroid Build Coastguard Worker // was drawTextRSXform
1346*c8dee2aaSAndroid Build Coastguard Worker break;
1347*c8dee2aaSAndroid Build Coastguard Worker }
1348*c8dee2aaSAndroid Build Coastguard Worker case 51: {
1349*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTextBlob> blob = make_fuzz_textblob(fuzz);
1350*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1351*c8dee2aaSAndroid Build Coastguard Worker SkScalar x, y;
1352*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&x, &y);
1353*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(blob, x, y, paint);
1354*c8dee2aaSAndroid Build Coastguard Worker break;
1355*c8dee2aaSAndroid Build Coastguard Worker }
1356*c8dee2aaSAndroid Build Coastguard Worker case 52: {
1357*c8dee2aaSAndroid Build Coastguard Worker SkMatrix matrix;
1358*c8dee2aaSAndroid Build Coastguard Worker bool usePaint, useMatrix;
1359*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&usePaint, &useMatrix);
1360*c8dee2aaSAndroid Build Coastguard Worker if (usePaint) {
1361*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1362*c8dee2aaSAndroid Build Coastguard Worker }
1363*c8dee2aaSAndroid Build Coastguard Worker if (useMatrix) {
1364*c8dee2aaSAndroid Build Coastguard Worker FuzzNiceMatrix(fuzz, &matrix);
1365*c8dee2aaSAndroid Build Coastguard Worker }
1366*c8dee2aaSAndroid Build Coastguard Worker auto pic = make_fuzz_picture(fuzz, depth - 1);
1367*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPicture(pic, useMatrix ? &matrix : nullptr,
1368*c8dee2aaSAndroid Build Coastguard Worker usePaint ? &paint : nullptr);
1369*c8dee2aaSAndroid Build Coastguard Worker break;
1370*c8dee2aaSAndroid Build Coastguard Worker }
1371*c8dee2aaSAndroid Build Coastguard Worker case 53: {
1372*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1373*c8dee2aaSAndroid Build Coastguard Worker SkVertices::VertexMode vertexMode;
1374*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode blendMode;
1375*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&vertexMode, 0, SkVertices::kTriangleFan_VertexMode);
1376*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&blendMode, 0, SkBlendMode::kLastMode);
1377*c8dee2aaSAndroid Build Coastguard Worker constexpr int kMaxCount = 100;
1378*c8dee2aaSAndroid Build Coastguard Worker int vertexCount;
1379*c8dee2aaSAndroid Build Coastguard Worker SkPoint vertices[kMaxCount];
1380*c8dee2aaSAndroid Build Coastguard Worker SkPoint texs[kMaxCount];
1381*c8dee2aaSAndroid Build Coastguard Worker SkColor colors[kMaxCount];
1382*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&vertexCount, 3, kMaxCount);
1383*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(vertices, vertexCount);
1384*c8dee2aaSAndroid Build Coastguard Worker bool useTexs, useColors;
1385*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useTexs, &useColors);
1386*c8dee2aaSAndroid Build Coastguard Worker if (useTexs) {
1387*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(texs, vertexCount);
1388*c8dee2aaSAndroid Build Coastguard Worker }
1389*c8dee2aaSAndroid Build Coastguard Worker if (useColors) {
1390*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(colors, vertexCount);
1391*c8dee2aaSAndroid Build Coastguard Worker }
1392*c8dee2aaSAndroid Build Coastguard Worker int indexCount = 0;
1393*c8dee2aaSAndroid Build Coastguard Worker uint16_t indices[kMaxCount * 2];
1394*c8dee2aaSAndroid Build Coastguard Worker if (make_fuzz_t<bool>(fuzz)) {
1395*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&indexCount, vertexCount, vertexCount + kMaxCount);
1396*c8dee2aaSAndroid Build Coastguard Worker for (int index = 0; index < indexCount; ++index) {
1397*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&indices[index], 0, vertexCount - 1);
1398*c8dee2aaSAndroid Build Coastguard Worker }
1399*c8dee2aaSAndroid Build Coastguard Worker }
1400*c8dee2aaSAndroid Build Coastguard Worker canvas->drawVertices(SkVertices::MakeCopy(vertexMode, vertexCount, vertices,
1401*c8dee2aaSAndroid Build Coastguard Worker useTexs ? texs : nullptr,
1402*c8dee2aaSAndroid Build Coastguard Worker useColors ? colors : nullptr,
1403*c8dee2aaSAndroid Build Coastguard Worker indexCount, indices),
1404*c8dee2aaSAndroid Build Coastguard Worker blendMode, paint);
1405*c8dee2aaSAndroid Build Coastguard Worker break;
1406*c8dee2aaSAndroid Build Coastguard Worker }
1407*c8dee2aaSAndroid Build Coastguard Worker case 54: {
1408*c8dee2aaSAndroid Build Coastguard Worker SkColor color;
1409*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode blendMode;
1410*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&blendMode, 0, SkBlendMode::kSrcOver);
1411*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&color);
1412*c8dee2aaSAndroid Build Coastguard Worker canvas->drawColor(color, blendMode);
1413*c8dee2aaSAndroid Build Coastguard Worker break;
1414*c8dee2aaSAndroid Build Coastguard Worker }
1415*c8dee2aaSAndroid Build Coastguard Worker case 55: {
1416*c8dee2aaSAndroid Build Coastguard Worker SkColor4f color;
1417*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode blendMode;
1418*c8dee2aaSAndroid Build Coastguard Worker float R, G, B, Alpha;
1419*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&blendMode, 0, SkBlendMode::kSrcOver);
1420*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&R, -1, 2);
1421*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&G, -1, 2);
1422*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&B, -1, 2);
1423*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&Alpha, 0, 1);
1424*c8dee2aaSAndroid Build Coastguard Worker color = {R, G, B, Alpha};
1425*c8dee2aaSAndroid Build Coastguard Worker canvas->drawColor(color, blendMode);
1426*c8dee2aaSAndroid Build Coastguard Worker break;
1427*c8dee2aaSAndroid Build Coastguard Worker }
1428*c8dee2aaSAndroid Build Coastguard Worker case 56: {
1429*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1430*c8dee2aaSAndroid Build Coastguard Worker SkPoint p0, p1;
1431*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&p0, &p1);
1432*c8dee2aaSAndroid Build Coastguard Worker canvas->drawLine(p0, p1, paint);
1433*c8dee2aaSAndroid Build Coastguard Worker break;
1434*c8dee2aaSAndroid Build Coastguard Worker }
1435*c8dee2aaSAndroid Build Coastguard Worker case 57: {
1436*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1437*c8dee2aaSAndroid Build Coastguard Worker SkIRect r;
1438*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&r);
1439*c8dee2aaSAndroid Build Coastguard Worker canvas->drawIRect(r, paint);
1440*c8dee2aaSAndroid Build Coastguard Worker break;
1441*c8dee2aaSAndroid Build Coastguard Worker }
1442*c8dee2aaSAndroid Build Coastguard Worker case 58: {
1443*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1444*c8dee2aaSAndroid Build Coastguard Worker SkScalar radius;
1445*c8dee2aaSAndroid Build Coastguard Worker SkPoint center;
1446*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&radius, ¢er);
1447*c8dee2aaSAndroid Build Coastguard Worker canvas->drawCircle(center, radius, paint);
1448*c8dee2aaSAndroid Build Coastguard Worker break;
1449*c8dee2aaSAndroid Build Coastguard Worker }
1450*c8dee2aaSAndroid Build Coastguard Worker case 59: {
1451*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1452*c8dee2aaSAndroid Build Coastguard Worker SkRect oval;
1453*c8dee2aaSAndroid Build Coastguard Worker SkScalar startAngle, sweepAngle;
1454*c8dee2aaSAndroid Build Coastguard Worker bool useCenter;
1455*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&oval, &startAngle, &sweepAngle, &useCenter);
1456*c8dee2aaSAndroid Build Coastguard Worker canvas->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
1457*c8dee2aaSAndroid Build Coastguard Worker break;
1458*c8dee2aaSAndroid Build Coastguard Worker }
1459*c8dee2aaSAndroid Build Coastguard Worker case 60: {
1460*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1461*c8dee2aaSAndroid Build Coastguard Worker SkRect rect;
1462*c8dee2aaSAndroid Build Coastguard Worker SkScalar rx, ry;
1463*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&rect, &rx, &ry);
1464*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRoundRect(rect, rx, ry, paint);
1465*c8dee2aaSAndroid Build Coastguard Worker break;
1466*c8dee2aaSAndroid Build Coastguard Worker }
1467*c8dee2aaSAndroid Build Coastguard Worker case 61: {
1468*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1469*c8dee2aaSAndroid Build Coastguard Worker font = fuzz_font(fuzz);
1470*c8dee2aaSAndroid Build Coastguard Worker std::string str = make_fuzz_string(fuzz);
1471*c8dee2aaSAndroid Build Coastguard Worker SkScalar x, y;
1472*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&x, &y);
1473*c8dee2aaSAndroid Build Coastguard Worker canvas->drawString(str.c_str(), x, y, font, paint);
1474*c8dee2aaSAndroid Build Coastguard Worker break;
1475*c8dee2aaSAndroid Build Coastguard Worker }
1476*c8dee2aaSAndroid Build Coastguard Worker case 62: {
1477*c8dee2aaSAndroid Build Coastguard Worker fuzz_paint(fuzz, &paint, depth - 1);
1478*c8dee2aaSAndroid Build Coastguard Worker SkPoint cubics[12];
1479*c8dee2aaSAndroid Build Coastguard Worker SkColor colors[4];
1480*c8dee2aaSAndroid Build Coastguard Worker SkPoint texCoords[4];
1481*c8dee2aaSAndroid Build Coastguard Worker bool useTexCoords;
1482*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(cubics, 12);
1483*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(colors, 4);
1484*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&useTexCoords);
1485*c8dee2aaSAndroid Build Coastguard Worker if (useTexCoords) {
1486*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(texCoords, 4);
1487*c8dee2aaSAndroid Build Coastguard Worker }
1488*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode mode;
1489*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&mode, SkBlendMode::kLastMode);
1490*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPatch(cubics, colors, useTexCoords ? texCoords : nullptr
1491*c8dee2aaSAndroid Build Coastguard Worker , mode, paint);
1492*c8dee2aaSAndroid Build Coastguard Worker break;
1493*c8dee2aaSAndroid Build Coastguard Worker }
1494*c8dee2aaSAndroid Build Coastguard Worker default:
1495*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(false);
1496*c8dee2aaSAndroid Build Coastguard Worker break;
1497*c8dee2aaSAndroid Build Coastguard Worker }
1498*c8dee2aaSAndroid Build Coastguard Worker }
1499*c8dee2aaSAndroid Build Coastguard Worker }
1500*c8dee2aaSAndroid Build Coastguard Worker
make_fuzz_picture(Fuzz * fuzz,int depth)1501*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkPicture> make_fuzz_picture(Fuzz* fuzz, int depth) {
1502*c8dee2aaSAndroid Build Coastguard Worker SkScalar w, h;
1503*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&w, &h);
1504*c8dee2aaSAndroid Build Coastguard Worker SkPictureRecorder pictureRecorder;
1505*c8dee2aaSAndroid Build Coastguard Worker fuzz_canvas(fuzz, pictureRecorder.beginRecording(w, h), depth - 1);
1506*c8dee2aaSAndroid Build Coastguard Worker return pictureRecorder.finishRecordingAsPicture();
1507*c8dee2aaSAndroid Build Coastguard Worker }
1508*c8dee2aaSAndroid Build Coastguard Worker
DEF_FUZZ(NullCanvas,fuzz)1509*c8dee2aaSAndroid Build Coastguard Worker DEF_FUZZ(NullCanvas, fuzz) {
1510*c8dee2aaSAndroid Build Coastguard Worker fuzz_canvas(fuzz, SkMakeNullCanvas().get());
1511*c8dee2aaSAndroid Build Coastguard Worker }
1512*c8dee2aaSAndroid Build Coastguard Worker
1513*c8dee2aaSAndroid Build Coastguard Worker constexpr SkISize kCanvasSize = {128, 160};
1514*c8dee2aaSAndroid Build Coastguard Worker
DEF_FUZZ(RasterN32Canvas,fuzz)1515*c8dee2aaSAndroid Build Coastguard Worker DEF_FUZZ(RasterN32Canvas, fuzz) {
1516*c8dee2aaSAndroid Build Coastguard Worker auto surface = SkSurfaces::Raster(
1517*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo::MakeN32Premul(kCanvasSize.width(), kCanvasSize.height()));
1518*c8dee2aaSAndroid Build Coastguard Worker if (!surface || !surface->getCanvas()) { fuzz->signalBug(); }
1519*c8dee2aaSAndroid Build Coastguard Worker fuzz_canvas(fuzz, surface->getCanvas());
1520*c8dee2aaSAndroid Build Coastguard Worker }
1521*c8dee2aaSAndroid Build Coastguard Worker
DEF_FUZZ(RasterN32CanvasViaSerialization,fuzz)1522*c8dee2aaSAndroid Build Coastguard Worker DEF_FUZZ(RasterN32CanvasViaSerialization, fuzz) {
1523*c8dee2aaSAndroid Build Coastguard Worker SkPictureRecorder recorder;
1524*c8dee2aaSAndroid Build Coastguard Worker fuzz_canvas(fuzz, recorder.beginRecording(SkIntToScalar(kCanvasSize.width()),
1525*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(kCanvasSize.height())));
1526*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPicture> pic(recorder.finishRecordingAsPicture());
1527*c8dee2aaSAndroid Build Coastguard Worker if (!pic) { fuzz->signalBug(); }
1528*c8dee2aaSAndroid Build Coastguard Worker SkSerialProcs sProcs;
1529*c8dee2aaSAndroid Build Coastguard Worker sProcs.fImageProc = [](SkImage* img, void*) -> sk_sp<SkData> {
1530*c8dee2aaSAndroid Build Coastguard Worker return SkPngEncoder::Encode(nullptr, img, SkPngEncoder::Options{});
1531*c8dee2aaSAndroid Build Coastguard Worker };
1532*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> data = pic->serialize(&sProcs);
1533*c8dee2aaSAndroid Build Coastguard Worker if (!data) { fuzz->signalBug(); }
1534*c8dee2aaSAndroid Build Coastguard Worker SkReadBuffer rb(data->data(), data->size());
1535*c8dee2aaSAndroid Build Coastguard Worker SkCodecs::Register(SkPngDecoder::Decoder());
1536*c8dee2aaSAndroid Build Coastguard Worker auto deserialized = SkPicturePriv::MakeFromBuffer(rb);
1537*c8dee2aaSAndroid Build Coastguard Worker if (!deserialized) { fuzz->signalBug(); }
1538*c8dee2aaSAndroid Build Coastguard Worker auto surface = SkSurfaces::Raster(
1539*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo::MakeN32Premul(kCanvasSize.width(), kCanvasSize.height()));
1540*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(surface && surface->getCanvas());
1541*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->drawPicture(deserialized);
1542*c8dee2aaSAndroid Build Coastguard Worker }
1543*c8dee2aaSAndroid Build Coastguard Worker
DEF_FUZZ(ImageFilter,fuzz)1544*c8dee2aaSAndroid Build Coastguard Worker DEF_FUZZ(ImageFilter, fuzz) {
1545*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bitmap;
1546*c8dee2aaSAndroid Build Coastguard Worker if (!bitmap.tryAllocN32Pixels(256, 256)) {
1547*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGF("Could not allocate 256x256 bitmap in ImageFilter");
1548*c8dee2aaSAndroid Build Coastguard Worker return;
1549*c8dee2aaSAndroid Build Coastguard Worker }
1550*c8dee2aaSAndroid Build Coastguard Worker
1551*c8dee2aaSAndroid Build Coastguard Worker auto fil = make_fuzz_imageFilter(fuzz, 20);
1552*c8dee2aaSAndroid Build Coastguard Worker
1553*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
1554*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(fil);
1555*c8dee2aaSAndroid Build Coastguard Worker SkCanvas canvas(bitmap);
1556*c8dee2aaSAndroid Build Coastguard Worker canvas.saveLayer(SkRect::MakeWH(500, 500), &paint);
1557*c8dee2aaSAndroid Build Coastguard Worker }
1558*c8dee2aaSAndroid Build Coastguard Worker
1559*c8dee2aaSAndroid Build Coastguard Worker
1560*c8dee2aaSAndroid Build Coastguard Worker //SkRandom _rand;
1561*c8dee2aaSAndroid Build Coastguard Worker #define SK_ADD_RANDOM_BIT_FLIPS
1562*c8dee2aaSAndroid Build Coastguard Worker
DEF_FUZZ(SerializedImageFilter,fuzz)1563*c8dee2aaSAndroid Build Coastguard Worker DEF_FUZZ(SerializedImageFilter, fuzz) {
1564*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bitmap;
1565*c8dee2aaSAndroid Build Coastguard Worker if (!bitmap.tryAllocN32Pixels(256, 256)) {
1566*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGF("Could not allocate 256x256 bitmap in SerializedImageFilter");
1567*c8dee2aaSAndroid Build Coastguard Worker return;
1568*c8dee2aaSAndroid Build Coastguard Worker }
1569*c8dee2aaSAndroid Build Coastguard Worker
1570*c8dee2aaSAndroid Build Coastguard Worker auto filter = make_fuzz_imageFilter(fuzz, 20);
1571*c8dee2aaSAndroid Build Coastguard Worker if (!filter) {
1572*c8dee2aaSAndroid Build Coastguard Worker return;
1573*c8dee2aaSAndroid Build Coastguard Worker }
1574*c8dee2aaSAndroid Build Coastguard Worker auto data = filter->serialize();
1575*c8dee2aaSAndroid Build Coastguard Worker const unsigned char* ptr = static_cast<const unsigned char*>(data->data());
1576*c8dee2aaSAndroid Build Coastguard Worker size_t len = data->size();
1577*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_ADD_RANDOM_BIT_FLIPS
1578*c8dee2aaSAndroid Build Coastguard Worker unsigned char* p = const_cast<unsigned char*>(ptr);
1579*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < len; ++i, ++p) {
1580*c8dee2aaSAndroid Build Coastguard Worker uint8_t j;
1581*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&j, 1, 250);
1582*c8dee2aaSAndroid Build Coastguard Worker if (j == 1) { // 0.4% of the time, flip a bit or byte
1583*c8dee2aaSAndroid Build Coastguard Worker uint8_t k;
1584*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&k, 1, 10);
1585*c8dee2aaSAndroid Build Coastguard Worker if (k == 1) { // Then 10% of the time, change a whole byte
1586*c8dee2aaSAndroid Build Coastguard Worker uint8_t s;
1587*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&s, 0, 2);
1588*c8dee2aaSAndroid Build Coastguard Worker switch(s) {
1589*c8dee2aaSAndroid Build Coastguard Worker case 0:
1590*c8dee2aaSAndroid Build Coastguard Worker *p ^= 0xFF; // Flip entire byte
1591*c8dee2aaSAndroid Build Coastguard Worker break;
1592*c8dee2aaSAndroid Build Coastguard Worker case 1:
1593*c8dee2aaSAndroid Build Coastguard Worker *p = 0xFF; // Set all bits to 1
1594*c8dee2aaSAndroid Build Coastguard Worker break;
1595*c8dee2aaSAndroid Build Coastguard Worker case 2:
1596*c8dee2aaSAndroid Build Coastguard Worker *p = 0x00; // Set all bits to 0
1597*c8dee2aaSAndroid Build Coastguard Worker break;
1598*c8dee2aaSAndroid Build Coastguard Worker }
1599*c8dee2aaSAndroid Build Coastguard Worker } else {
1600*c8dee2aaSAndroid Build Coastguard Worker uint8_t s;
1601*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&s, 0, 7);
1602*c8dee2aaSAndroid Build Coastguard Worker *p ^= (1 << 7);
1603*c8dee2aaSAndroid Build Coastguard Worker }
1604*c8dee2aaSAndroid Build Coastguard Worker }
1605*c8dee2aaSAndroid Build Coastguard Worker }
1606*c8dee2aaSAndroid Build Coastguard Worker #endif // SK_ADD_RANDOM_BIT_FLIPS
1607*c8dee2aaSAndroid Build Coastguard Worker auto deserializedFil = SkImageFilter::Deserialize(ptr, len);
1608*c8dee2aaSAndroid Build Coastguard Worker
1609*c8dee2aaSAndroid Build Coastguard Worker // uncomment below to write out a serialized image filter (to make corpus
1610*c8dee2aaSAndroid Build Coastguard Worker // for -t filter_fuzz)
1611*c8dee2aaSAndroid Build Coastguard Worker // SkString s("./serialized_filters/sf");
1612*c8dee2aaSAndroid Build Coastguard Worker // s.appendU32(_rand.nextU());
1613*c8dee2aaSAndroid Build Coastguard Worker // auto file = sk_fopen(s.c_str(), SkFILE_Flags::kWrite_SkFILE_Flag);
1614*c8dee2aaSAndroid Build Coastguard Worker // sk_fwrite(data->bytes(), data->size(), file);
1615*c8dee2aaSAndroid Build Coastguard Worker // sk_fclose(file);
1616*c8dee2aaSAndroid Build Coastguard Worker
1617*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
1618*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(deserializedFil);
1619*c8dee2aaSAndroid Build Coastguard Worker
1620*c8dee2aaSAndroid Build Coastguard Worker SkCanvas canvas(bitmap);
1621*c8dee2aaSAndroid Build Coastguard Worker canvas.saveLayer(SkRect::MakeWH(256, 256), &paint);
1622*c8dee2aaSAndroid Build Coastguard Worker canvas.restore();
1623*c8dee2aaSAndroid Build Coastguard Worker }
1624*c8dee2aaSAndroid Build Coastguard Worker
1625*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_GANESH)
fuzz_ganesh(Fuzz * fuzz,GrDirectContext * context)1626*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_ganesh(Fuzz* fuzz, GrDirectContext* context) {
1627*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(context);
1628*c8dee2aaSAndroid Build Coastguard Worker auto surface = SkSurfaces::RenderTarget(
1629*c8dee2aaSAndroid Build Coastguard Worker context,
1630*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kNo,
1631*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo::Make(kCanvasSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
1632*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(surface && surface->getCanvas());
1633*c8dee2aaSAndroid Build Coastguard Worker fuzz_canvas(fuzz, surface->getCanvas());
1634*c8dee2aaSAndroid Build Coastguard Worker }
1635*c8dee2aaSAndroid Build Coastguard Worker
DEF_FUZZ(MockGPUCanvas,fuzz)1636*c8dee2aaSAndroid Build Coastguard Worker DEF_FUZZ(MockGPUCanvas, fuzz) {
1637*c8dee2aaSAndroid Build Coastguard Worker sk_gpu_test::GrContextFactory f;
1638*c8dee2aaSAndroid Build Coastguard Worker fuzz_ganesh(fuzz, f.get(skgpu::ContextType::kMock));
1639*c8dee2aaSAndroid Build Coastguard Worker }
1640*c8dee2aaSAndroid Build Coastguard Worker #endif
1641*c8dee2aaSAndroid Build Coastguard Worker
1642*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
dump_GPU_info(GrDirectContext * context)1643*c8dee2aaSAndroid Build Coastguard Worker static void dump_GPU_info(GrDirectContext* context) {
1644*c8dee2aaSAndroid Build Coastguard Worker const GrGLInterface* gl = static_cast<GrGLGpu*>(context->priv().getGpu())
1645*c8dee2aaSAndroid Build Coastguard Worker ->glInterface();
1646*c8dee2aaSAndroid Build Coastguard Worker const GrGLubyte* output;
1647*c8dee2aaSAndroid Build Coastguard Worker GR_GL_CALL_RET(gl, output, GetString(GR_GL_RENDERER));
1648*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("GL_RENDERER %s\n", (const char*) output);
1649*c8dee2aaSAndroid Build Coastguard Worker
1650*c8dee2aaSAndroid Build Coastguard Worker GR_GL_CALL_RET(gl, output, GetString(GR_GL_VENDOR));
1651*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("GL_VENDOR %s\n", (const char*) output);
1652*c8dee2aaSAndroid Build Coastguard Worker
1653*c8dee2aaSAndroid Build Coastguard Worker GR_GL_CALL_RET(gl, output, GetString(GR_GL_VERSION));
1654*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("GL_VERSION %s\n", (const char*) output);
1655*c8dee2aaSAndroid Build Coastguard Worker }
1656*c8dee2aaSAndroid Build Coastguard Worker
DEF_FUZZ(NativeGLCanvas,fuzz)1657*c8dee2aaSAndroid Build Coastguard Worker DEF_FUZZ(NativeGLCanvas, fuzz) {
1658*c8dee2aaSAndroid Build Coastguard Worker sk_gpu_test::GrContextFactory f;
1659*c8dee2aaSAndroid Build Coastguard Worker auto context = f.get(skgpu::ContextType::kGL);
1660*c8dee2aaSAndroid Build Coastguard Worker if (!context) {
1661*c8dee2aaSAndroid Build Coastguard Worker context = f.get(skgpu::ContextType::kGLES);
1662*c8dee2aaSAndroid Build Coastguard Worker }
1663*c8dee2aaSAndroid Build Coastguard Worker if (FLAGS_gpuInfo) {
1664*c8dee2aaSAndroid Build Coastguard Worker dump_GPU_info(context);
1665*c8dee2aaSAndroid Build Coastguard Worker }
1666*c8dee2aaSAndroid Build Coastguard Worker fuzz_ganesh(fuzz, context);
1667*c8dee2aaSAndroid Build Coastguard Worker }
1668*c8dee2aaSAndroid Build Coastguard Worker #endif
1669*c8dee2aaSAndroid Build Coastguard Worker
DEF_FUZZ(PDFCanvas,fuzz)1670*c8dee2aaSAndroid Build Coastguard Worker DEF_FUZZ(PDFCanvas, fuzz) {
1671*c8dee2aaSAndroid Build Coastguard Worker SkNullWStream stream;
1672*c8dee2aaSAndroid Build Coastguard Worker auto doc = SkPDF::MakeDocument(&stream);
1673*c8dee2aaSAndroid Build Coastguard Worker fuzz_canvas(fuzz, doc->beginPage(SkIntToScalar(kCanvasSize.width()),
1674*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(kCanvasSize.height())));
1675*c8dee2aaSAndroid Build Coastguard Worker }
1676*c8dee2aaSAndroid Build Coastguard Worker
1677*c8dee2aaSAndroid Build Coastguard Worker // not a "real" thing to fuzz, used to debug errors found while fuzzing.
DEF_FUZZ(_DumpCanvas,fuzz)1678*c8dee2aaSAndroid Build Coastguard Worker DEF_FUZZ(_DumpCanvas, fuzz) {
1679*c8dee2aaSAndroid Build Coastguard Worker DebugCanvas debugCanvas(kCanvasSize.width(), kCanvasSize.height());
1680*c8dee2aaSAndroid Build Coastguard Worker fuzz_canvas(fuzz, &debugCanvas);
1681*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> nullCanvas = SkMakeNullCanvas();
1682*c8dee2aaSAndroid Build Coastguard Worker UrlDataManager dataManager(SkString("data"));
1683*c8dee2aaSAndroid Build Coastguard Worker SkDynamicMemoryWStream stream;
1684*c8dee2aaSAndroid Build Coastguard Worker SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
1685*c8dee2aaSAndroid Build Coastguard Worker writer.beginObject(); // root
1686*c8dee2aaSAndroid Build Coastguard Worker debugCanvas.toJSON(writer, dataManager, nullCanvas.get());
1687*c8dee2aaSAndroid Build Coastguard Worker writer.endObject(); // root
1688*c8dee2aaSAndroid Build Coastguard Worker writer.flush();
1689*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> json = stream.detachAsData();
1690*c8dee2aaSAndroid Build Coastguard Worker fwrite(json->data(), json->size(), 1, stdout);
1691*c8dee2aaSAndroid Build Coastguard Worker }
1692*c8dee2aaSAndroid Build Coastguard Worker
DEF_FUZZ(SVGCanvas,fuzz)1693*c8dee2aaSAndroid Build Coastguard Worker DEF_FUZZ(SVGCanvas, fuzz) {
1694*c8dee2aaSAndroid Build Coastguard Worker SkNullWStream stream;
1695*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds = SkRect::MakeIWH(150, 150);
1696*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> canvas = SkSVGCanvas::Make(bounds, &stream);
1697*c8dee2aaSAndroid Build Coastguard Worker fuzz_canvas(fuzz, canvas.get());
1698*c8dee2aaSAndroid Build Coastguard Worker }
1699