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