Chromium Code Reviews| Index: fuzz/FuzzGradients.cpp |
| diff --git a/fuzz/FuzzGradients.cpp b/fuzz/FuzzGradients.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ed83e2d1a210d53ebaf654481d3b71fcc286975b |
| --- /dev/null |
| +++ b/fuzz/FuzzGradients.cpp |
| @@ -0,0 +1,303 @@ |
| +/* |
| + * Copyright 2016 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +#include "Fuzz.h" |
| +#include "SkCanvas.h" |
| +#include "SkSurface.h" |
| +#include "SkGradientShader.h" |
| + |
| +#include <algorithm> |
| + |
| +const int MAX_COUNT = 400; |
| + |
| +bool makeMatrix(Fuzz* fuzz, SkMatrix* m) { |
| + SkScalar scaleX, skewX, transX, skewY, scaleY, transY, persp0, persp1, persp2; |
|
f(malita)
2016/08/11 16:06:20
General formatting: 4-space indentation, per Skia
kjlubick
2016/08/11 17:15:25
Done.
|
| + if (!fuzz->next<SkScalar>(&scaleX) || |
| + !fuzz->next<SkScalar>(&skewX) || |
| + !fuzz->next<SkScalar>(&transX) || |
| + !fuzz->next<SkScalar>(&skewY) || |
| + !fuzz->next<SkScalar>(&scaleY) || |
| + !fuzz->next<SkScalar>(&transY) || |
| + !fuzz->next<SkScalar>(&persp0) || |
| + !fuzz->next<SkScalar>(&persp1) || |
| + !fuzz->next<SkScalar>(&persp2)) { |
| + return false; |
| + } |
| + m->setAll(scaleX, skewX, transX, skewY, scaleY, transY, persp0, persp1, persp2); |
| + return true; |
| +} |
| + |
| +bool initColors(Fuzz* fuzz, uint32_t* count, SkColor** colors, SkScalar** pos, |
|
f(malita)
2016/08/11 16:06:20
Nit: rename to initGradientParams?
kjlubick
2016/08/11 17:15:25
Done.
|
| + SkShader::TileMode* mode) { |
| + if (fuzz->remaining() < sizeof(uint32_t)) { |
| + return false; |
| + } |
| + uint32_t t_count; |
| + SkColor* t_colors; |
| + SkScalar* t_pos; |
| + |
| + t_count = fuzz->nextRangeU(0, MAX_COUNT); |
| + if (t_count == 1) { |
| + t_count = 2; |
| + } |
| + |
| + if (fuzz->remaining() < (1 + t_count * (sizeof(SkColor) + sizeof(SkScalar)))) { |
| + return false; |
| + } |
| + t_colors = new SkColor[t_count]; |
| + t_pos = new SkScalar[t_count]; |
| + for (uint32_t i = 0; i < t_count; i++) { |
| + SkColor col; |
| + SkScalar s; |
| + fuzz->next<SkColor>(&col); |
| + fuzz->next<SkScalar>(&s); |
| + (t_colors)[i] = col; |
| + (t_pos)[i] = s; |
| + } |
| + |
| + if (t_count == 0) { |
| + *count = 0; |
| + *colors = NULL; |
| + *pos = NULL; |
| + } else { |
| + std::sort(t_pos, t_pos + t_count); |
| + t_pos[0] = 0; |
| + t_pos[t_count - 1] = 1; |
| + *count = t_count; |
| + *colors = t_colors; |
| + *pos = t_pos; |
| + } |
| + |
| + *mode = static_cast<SkShader::TileMode>(fuzz->nextRangeU(0, 3)); |
| + return true; |
| +} |
| + |
| +void fuzzLinearGradient(Fuzz* fuzz) { |
| + SkScalar a, b, c, d; |
| + bool useLocalMatrix, useGlobalMatrix; |
| + if (!fuzz->next<SkScalar>(&a) || |
| + !fuzz->next<SkScalar>(&b) || |
| + !fuzz->next<SkScalar>(&c) || |
| + !fuzz->next<SkScalar>(&d) || |
| + !fuzz->next<bool>(&useLocalMatrix) || |
| + !fuzz->next<bool>(&useGlobalMatrix)) { |
| + return; |
| + } |
| + SkPoint pts[2] = {SkPoint::Make(a,b), SkPoint::Make(c, d)}; |
| + |
| + uint32_t count; |
| + SkColor* colors; |
| + SkScalar* pos; |
|
f(malita)
2016/08/11 16:06:20
Do we ever deallocate these?
Maybe refactor using
kjlubick
2016/08/11 17:15:25
See below for explanation that when the return hap
|
| + SkShader::TileMode mode; |
| + if (!initColors(fuzz, &count, &colors, &pos, &mode)) { |
| + return; |
| + } |
| + |
| + SkPaint p; |
| + if (useLocalMatrix) { |
| + SkMatrix m; |
| + if (!makeMatrix(fuzz, &m)) { |
| + return; |
| + } |
| + uint32_t flags; |
| + if (!fuzz->next(&flags)) { |
|
f(malita)
2016/08/11 16:06:20
The (poorly documented?) flags parameter is not re
kjlubick
2016/08/11 17:15:25
Done, using your refactor below.
|
| + return; |
| + } |
| + p.setShader(SkGradientShader::MakeLinear(pts, colors, pos, count, mode, flags, &m)); |
| + } |
| + else { |
| + p.setShader(SkGradientShader::MakeLinear(pts, colors, pos, count, mode)); |
| + } |
|
f(malita)
2016/08/11 16:06:20
Nit: Skia-idiomatic refactor idea for this block,
kjlubick
2016/08/11 17:15:25
Done.
|
| + |
| + sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); |
|
f(malita)
2016/08/11 16:06:20
I think this would run much faster if we hoisted t
kjlubick
2016/08/11 17:15:25
This fuzzer code isn't like the "fuzz unit tests"
|
| + if (useGlobalMatrix) { |
| + SkMatrix gm; |
| + if (!makeMatrix(fuzz, &gm)) { |
| + return; |
| + } |
| + SkCanvas* c = surface->getCanvas(); |
| + c->setMatrix(gm); |
| + c->drawPaint(p); |
| + } else { |
| + surface->getCanvas()->drawPaint(p); |
| + } |
| +} |
| + |
| +void fuzzRadialGradient(Fuzz* fuzz) { |
| + SkScalar a, b, radius; |
| + bool useLocalMatrix, useGlobalMatrix; |
| + if (!fuzz->next<SkScalar>(&a) || |
| + !fuzz->next<SkScalar>(&b) || |
| + !fuzz->next<SkScalar>(&radius) || |
| + !fuzz->next<bool>(&useLocalMatrix) || |
| + !fuzz->next<bool>(&useGlobalMatrix)) { |
| + return; |
| + } |
| + SkPoint center = SkPoint::Make(a,b); |
| + |
| + uint32_t count; |
| + SkColor* colors; |
| + SkScalar* pos; |
| + SkShader::TileMode mode; |
| + if (!initColors(fuzz, &count, &colors, &pos, &mode)) { |
| + return; |
| + } |
| + |
| + SkPaint p; |
| + if (useLocalMatrix) { |
| + SkMatrix m; |
| + if (!makeMatrix(fuzz, &m)) { |
| + return; |
| + } |
| + uint32_t flags; |
| + if (!fuzz->next(&flags)) { |
| + return; |
| + } |
| + p.setShader(SkGradientShader::MakeRadial(center, radius, colors, pos, count, mode, flags, &m)); |
| + } else { |
| + p.setShader(SkGradientShader::MakeRadial(center, radius, colors, pos, count, mode)); |
| + } |
| + |
| + sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); |
| + if (useGlobalMatrix) { |
| + SkMatrix gm; |
| + if (!makeMatrix(fuzz, &gm)) { |
| + return; |
| + } |
| + SkCanvas* c = surface->getCanvas(); |
| + c->setMatrix(gm); |
| + c->drawPaint(p); |
| + } else { |
| + surface->getCanvas()->drawPaint(p); |
| + } |
| +} |
| + |
| +void fuzzTwoPointConicalGradient(Fuzz* fuzz) { |
| + SkScalar a, b, startRadius, c, d, endRadius; |
| + bool useLocalMatrix, useGlobalMatrix; |
| + if (!fuzz->next<SkScalar>(&a) || |
| + !fuzz->next<SkScalar>(&b) || |
| + !fuzz->next<SkScalar>(&startRadius) || |
| + !fuzz->next<SkScalar>(&c) || |
| + !fuzz->next<SkScalar>(&d) || |
| + !fuzz->next<SkScalar>(&endRadius) || |
| + !fuzz->next<bool>(&useLocalMatrix) || |
| + !fuzz->next<bool>(&useGlobalMatrix)) { |
| + return; |
| + } |
| + SkPoint start = SkPoint::Make(a, b); |
| + SkPoint end = SkPoint::Make(c, d); |
| + |
| + uint32_t count; |
| + SkColor* colors; |
| + SkScalar* pos; |
| + SkShader::TileMode mode; |
| + if (!initColors(fuzz, &count, &colors, &pos, &mode)) { |
| + return; |
| + } |
| + |
| + SkPaint p; |
| + if (useLocalMatrix) { |
| + SkMatrix m; |
| + if (!makeMatrix(fuzz, &m)) { |
| + return; |
| + } |
| + uint32_t flags; |
| + if (!fuzz->next(&flags)) { |
| + return; |
| + } |
| + p.setShader(SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius, colors, pos, count, mode, flags, &m)); |
| + } else { |
| + p.setShader(SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius, colors, pos, count, mode)); |
| + } |
| + |
| + sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); |
| + if (useGlobalMatrix) { |
| + SkMatrix gm; |
| + if (!makeMatrix(fuzz, &gm)) { |
| + return; |
| + } |
| + SkCanvas* c = surface->getCanvas(); |
| + c->setMatrix(gm); |
| + c->drawPaint(p); |
| + } else { |
| + surface->getCanvas()->drawPaint(p); |
| + } |
| +} |
| + |
| +void fuzzSweepGradient(Fuzz* fuzz) { |
| + SkScalar cx, cy; |
| + bool useLocalMatrix, useGlobalMatrix; |
| + if (!fuzz->next<SkScalar>(&cx) || |
| + !fuzz->next<SkScalar>(&cy) || |
| + !fuzz->next<bool>(&useLocalMatrix) || |
| + !fuzz->next<bool>(&useGlobalMatrix)) { |
| + return; |
| + } |
| + |
| + uint32_t count; |
| + SkColor* colors; |
| + SkScalar* pos; |
| + SkShader::TileMode mode; |
| + if (!initColors(fuzz, &count, &colors, &pos, &mode)) { |
| + return; |
| + } |
| + |
| + SkPaint p; |
| + if (useLocalMatrix) { |
| + SkMatrix m; |
| + if (!makeMatrix(fuzz, &m)) { |
| + return; |
| + } |
| + uint32_t flags; |
| + if (!fuzz->next(&flags)) { |
| + return; |
| + } |
| + p.setShader(SkGradientShader::MakeSweep(cx, cy, colors, pos, count, flags, &m)); |
| + } else { |
| + p.setShader(SkGradientShader::MakeSweep(cx, cy, colors, pos, count)); |
| + } |
| + |
| + |
| + sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); |
| + if (useGlobalMatrix) { |
| + SkMatrix gm; |
| + if (!makeMatrix(fuzz, &gm)) { |
| + return; |
| + } |
| + SkCanvas* c = surface->getCanvas(); |
| + c->setMatrix(gm); |
| + c->drawPaint(p); |
| + } else { |
| + surface->getCanvas()->drawPaint(p); |
| + } |
| +} |
| + |
| +DEF_FUZZ(Gradients, fuzz) { |
| + uint8_t i; |
| + if (!fuzz->next<uint8_t>(&i)) { |
| + return; |
| + } |
| + |
| + switch(i) { |
| + case 0: |
| + SkDebugf("LinearGradient\n"); |
| + fuzzLinearGradient(fuzz); |
| + return; |
| + case 1: |
| + SkDebugf("RadialGradient\n"); |
| + fuzzRadialGradient(fuzz); |
| + return; |
| + case 2: |
| + SkDebugf("TwoPointConicalGradient\n"); |
| + fuzzTwoPointConicalGradient(fuzz); |
| + return; |
| + } |
| + SkDebugf("SweepGradient\n"); |
| + fuzzSweepGradient(fuzz); |
| + return; |
| +} |