diff options
author | cdalton <cdalton@nvidia.com> | 2016-02-10 14:54:21 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-10 14:54:21 -0800 |
commit | 4a6e40d9d2e0eb81e00d8b2bd20532aa28f61afb (patch) | |
tree | 0c3b292d130b40135b587b57a960c1b77913e733 /gm/shapes.cpp | |
parent | 12d47ce49e65e27f39fa20b78445e637c95b19b8 (diff) |
Add bench and gm for shapes
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1677253002
patch from issue 1686673002 at patchset 20001 (http://crrev.com/1686673002#ps20001)
Review URL: https://codereview.chromium.org/1677253002
Diffstat (limited to 'gm/shapes.cpp')
-rw-r--r-- | gm/shapes.cpp | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/gm/shapes.cpp b/gm/shapes.cpp new file mode 100644 index 0000000000..02b6a9827b --- /dev/null +++ b/gm/shapes.cpp @@ -0,0 +1,164 @@ + +/* + * 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 "gm.h" +#include "SkRandom.h" +#include "SkRRect.h" + +namespace skiagm { + +/* + * This is the base class for two GMs that cover various corner cases with primitive Skia shapes + * (zero radius, near-zero radius, inner shape overlap, etc.) It uses an xfermode of darken to help + * double-blended and/or dropped pixels stand out. + */ +class ShapesGM : public GM { +protected: + ShapesGM(const char* name, bool antialias) : fName(name), fAntialias(antialias) { + fShapes.push_back().setOval(SkRect::MakeXYWH(-5, 25, 200, 100)); + fRotations.push_back(21); + + fShapes.push_back().setRect(SkRect::MakeXYWH(95, 75, 125, 100)); + fRotations.push_back(94); + + fShapes.push_back().setRectXY(SkRect::MakeXYWH(0, 75, 150, 100), 1e-5f, 1e-5f); + fRotations.push_back(132); + + fShapes.push_back().setRectXY(SkRect::MakeXYWH(15, -20, 100, 100), 20, 15); + fRotations.push_back(282); + + fSimpleShapeCount = fShapes.count(); + + fShapes.push_back().setNinePatch(SkRect::MakeXYWH(140, -50, 90, 110), 10, 5, 25, 35); + fRotations.push_back(0); + + fShapes.push_back().setNinePatch(SkRect::MakeXYWH(160, -60, 60, 90), 10, 60, 50, 30); + fRotations.push_back(-35); + + fShapes.push_back().setNinePatch(SkRect::MakeXYWH(220, -120, 60, 90), 1, 89, 59, 1); + fRotations.push_back(65); + + SkVector radii[4] = {{4, 6}, {12, 8}, {24, 16}, {32, 48}}; + fShapes.push_back().setRectRadii(SkRect::MakeXYWH(150, -129, 80, 160), radii); + fRotations.push_back(265); + + SkVector radii2[4] = {{0, 0}, {80, 60}, {0, 0}, {80, 60}}; + fShapes.push_back().setRectRadii(SkRect::MakeXYWH(180, -30, 80, 60), radii2); + fRotations.push_back(295); + + if (!antialias) { + fName.append("_bw"); + } + } + + SkString onShortName() override final { return fName; } + SkISize onISize() override { return SkISize::Make(500, 500); } + + void onOnceBeforeDraw() override { + fPaint.setXfermodeMode(SkXfermode::kDarken_Mode); + fPaint.setAntiAlias(fAntialias); + } + + void onDraw(SkCanvas* canvas) override { + canvas->clear(SK_ColorWHITE); + + canvas->save(); + canvas->translate(canvas->imageInfo().width() / 2.f, canvas->imageInfo().height() / 2.f); + this->drawShapes(canvas); + canvas->restore(); + } + + virtual void drawShapes(SkCanvas* canvas) const = 0; + +protected: + SkString fName; + bool fAntialias; + SkPaint fPaint; + SkTArray<SkRRect> fShapes; + SkTArray<SkScalar> fRotations; + int fSimpleShapeCount; + +private: + typedef GM INHERITED; +}; + +class SimpleShapesGM : public ShapesGM { +public: + SimpleShapesGM(bool antialias) : INHERITED("simpleshapes", antialias) {} + +private: + void drawShapes(SkCanvas* canvas) const override { + SkRandom rand(2); + for (int i = 0; i < fShapes.count(); i++) { + SkPaint paint(fPaint); + paint.setColor(rand.nextU() & ~0x808080); + paint.setAlpha(128); // Use alpha to detect double blends. + const SkRRect& shape = fShapes[i]; + canvas->save(); + canvas->rotate(fRotations[i]); + switch (shape.getType()) { + case SkRRect::kRect_Type: + canvas->drawRect(shape.rect(), paint); + break; + case SkRRect::kOval_Type: + canvas->drawOval(shape.rect(), paint); + break; + default: + canvas->drawRRect(shape, paint); + break; + } + canvas->restore(); + } + } + + typedef ShapesGM INHERITED; +}; + +class InnerShapesGM : public ShapesGM { +public: + InnerShapesGM(bool antialias) : INHERITED("innershapes", antialias) {} + +private: + void drawShapes(SkCanvas* canvas) const override { + SkRandom rand; + for (int i = 0; i < fShapes.count(); i++) { + const SkRRect& outer = fShapes[i]; + const SkRRect& inner = fShapes[(i * 7 + 11) % fSimpleShapeCount]; + float s = 0.95f * SkTMin(outer.rect().width() / inner.rect().width(), + outer.rect().height() / inner.rect().height()); + SkMatrix innerXform; + float dx = (rand.nextF() - 0.5f) * (outer.rect().width() - s * inner.rect().width()); + float dy = (rand.nextF() - 0.5f) * (outer.rect().height() - s * inner.rect().height()); + innerXform.setTranslate(outer.rect().centerX() + dx, outer.rect().centerY() + dy); + if (s < 1) { + innerXform.preScale(s, s); + } + innerXform.preTranslate(-inner.rect().centerX(), -inner.rect().centerY()); + SkRRect xformedInner; + inner.transform(innerXform, &xformedInner); + SkPaint paint(fPaint); + paint.setColor(rand.nextU() & ~0x808080); + paint.setAlpha(128); // Use alpha to detect double blends. + canvas->save(); + canvas->rotate(fRotations[i]); + canvas->drawDRRect(outer, xformedInner, paint); + canvas->restore(); + } + } + + typedef ShapesGM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +DEF_GM( return new SimpleShapesGM(true); ) +DEF_GM( return new SimpleShapesGM(false); ) +DEF_GM( return new InnerShapesGM(true); ) +DEF_GM( return new InnerShapesGM(false); ) + +} |