123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- /*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "bench/Benchmark.h"
- #include "include/core/SkCanvas.h"
- #include "include/core/SkPaint.h"
- #include "include/effects/SkGradientShader.h"
- #include "src/core/SkBlendModePriv.h"
- #include <ctype.h>
- /** This benchmark tests rendering rotated rectangles. It can optionally apply AA and/or change the
- paint color between each rect in different ways using the ColorType enum. The xfermode used can
- be specified as well.
- */
- enum ColorType {
- kConstantOpaque_ColorType,
- kConstantTransparent_ColorType,
- kChangingOpaque_ColorType,
- kChangingTransparent_ColorType,
- kAlternatingOpaqueAndTransparent_ColorType,
- kShaderOpaque_ColorType
- };
- static inline SkColor start_color(ColorType ct) {
- switch (ct) {
- case kConstantOpaque_ColorType:
- case kChangingOpaque_ColorType:
- case kAlternatingOpaqueAndTransparent_ColorType:
- return 0xFFA07040;
- case kConstantTransparent_ColorType:
- case kChangingTransparent_ColorType:
- return 0x80A07040;
- case kShaderOpaque_ColorType:
- return SK_ColorWHITE;
- }
- SK_ABORT("Shouldn't reach here.");
- return 0;
- }
- static inline SkColor advance_color(SkColor old, ColorType ct, int step) {
- if (kAlternatingOpaqueAndTransparent_ColorType == ct) {
- ct = (step & 0x1) ? kChangingOpaque_ColorType : kChangingTransparent_ColorType ;
- }
- switch (ct) {
- case kConstantOpaque_ColorType:
- case kConstantTransparent_ColorType:
- case kShaderOpaque_ColorType:
- return old;
- case kChangingOpaque_ColorType:
- return 0xFF000000 | (old + 0x00010307);
- case kChangingTransparent_ColorType:
- return (0x00FFFFFF & (old + 0x00010307)) | 0x80000000;
- case kAlternatingOpaqueAndTransparent_ColorType:
- SK_ABORT("Can't get here");
- }
- SK_ABORT("Shouldn't reach here.");
- return 0;
- }
- static SkString to_lower(const char* str) {
- SkString lower(str);
- for (size_t i = 0; i < lower.size(); i++) {
- lower[i] = tolower(lower[i]);
- }
- return lower;
- }
- class RotRectBench: public Benchmark {
- public:
- RotRectBench(bool aa, ColorType ct, SkBlendMode mode, bool perspective = false)
- : fAA(aa)
- , fPerspective(perspective)
- , fColorType(ct)
- , fMode(mode) {
- this->makeName();
- }
- protected:
- const char* onGetName() override { return fName.c_str(); }
- void onDraw(int loops, SkCanvas* canvas) override {
- SkPaint paint;
- paint.setAntiAlias(fAA);
- paint.setBlendMode(fMode);
- SkColor color = start_color(fColorType);
- int w = this->getSize().x();
- int h = this->getSize().y();
- static const SkScalar kRectW = 25.1f;
- static const SkScalar kRectH = 25.9f;
- if (fColorType == kShaderOpaque_ColorType) {
- // The only requirement for the shader is that it requires local coordinates
- SkPoint pts[2] = { {0.0f, 0.0f}, {kRectW, kRectH} };
- SkColor colors[] = { color, SK_ColorBLUE };
- paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
- SkTileMode::kClamp));
- }
- SkMatrix rotate;
- // This value was chosen so that we frequently hit the axis-aligned case.
- rotate.setRotate(30.f, kRectW / 2, kRectH / 2);
- SkMatrix m = rotate;
- SkScalar tx = 0, ty = 0;
- if (fPerspective) {
- // Apply some fixed perspective to change how ops may draw the rects
- SkMatrix perspective;
- perspective.setIdentity();
- perspective.setPerspX(1e-4f);
- perspective.setPerspY(1e-3f);
- perspective.setSkewX(0.1f);
- canvas->concat(perspective);
- }
- for (int i = 0; i < loops; ++i) {
- canvas->save();
- canvas->translate(tx, ty);
- canvas->concat(m);
- paint.setColor(color);
- color = advance_color(color, fColorType, i);
- canvas->drawRect(SkRect::MakeWH(kRectW, kRectH), paint);
- canvas->restore();
- tx += kRectW + 2;
- if (tx > w) {
- tx = 0;
- ty += kRectH + 2;
- if (ty > h) {
- ty = 0;
- }
- }
- m.postConcat(rotate);
- }
- }
- private:
- void makeName() {
- fName = "rotated_rects";
- if (fAA) {
- fName.append("_aa");
- } else {
- fName.append("_bw");
- }
- if (fPerspective) {
- fName.append("_persp");
- }
- switch (fColorType) {
- case kConstantOpaque_ColorType:
- fName.append("_same_opaque");
- break;
- case kConstantTransparent_ColorType:
- fName.append("_same_transparent");
- break;
- case kChangingOpaque_ColorType:
- fName.append("_changing_opaque");
- break;
- case kChangingTransparent_ColorType:
- fName.append("_changing_transparent");
- break;
- case kAlternatingOpaqueAndTransparent_ColorType:
- fName.append("_alternating_transparent_and_opaque");
- break;
- case kShaderOpaque_ColorType:
- fName.append("_shader_opaque");
- break;
- }
- fName.appendf("_%s", to_lower(SkBlendMode_Name(fMode)).c_str());
- }
- bool fAA;
- bool fPerspective;
- ColorType fColorType;
- SkBlendMode fMode;
- SkString fName;
- typedef Benchmark INHERITED;
- };
- #define DEF_FOR_COLOR_TYPES(aa, blend) \
- DEF_BENCH(return new RotRectBench(aa, kConstantOpaque_ColorType, blend);) \
- DEF_BENCH(return new RotRectBench(aa, kConstantTransparent_ColorType, blend);) \
- DEF_BENCH(return new RotRectBench(aa, kChangingOpaque_ColorType, blend);) \
- DEF_BENCH(return new RotRectBench(aa, kChangingTransparent_ColorType, blend);) \
- DEF_BENCH(return new RotRectBench(aa, kAlternatingOpaqueAndTransparent_ColorType, blend);) \
- DEF_BENCH(return new RotRectBench(aa, kShaderOpaque_ColorType, blend);)
- #define DEF_FOR_AA_MODES(blend) \
- DEF_FOR_COLOR_TYPES(true, blend) \
- DEF_FOR_COLOR_TYPES(false, blend)
- // Choose kSrcOver because it always allows coverage and alpha to be conflated. kSrc only allows
- // conflation when opaque, and kDarken because it isn't possilbe with standard GL blending.
- DEF_FOR_AA_MODES(SkBlendMode::kSrcOver)
- DEF_FOR_AA_MODES(SkBlendMode::kSrc)
- DEF_FOR_AA_MODES(SkBlendMode::kDarken)
- // Only do a limited run of perspective tests
- #define DEF_FOR_PERSP_MODES(aa) \
- DEF_BENCH(return new RotRectBench(aa, kConstantOpaque_ColorType, SkBlendMode::kSrcOver, true);)\
- DEF_BENCH(return new RotRectBench(aa, kShaderOpaque_ColorType, SkBlendMode::kSrcOver, true);)
- DEF_FOR_PERSP_MODES(true)
- DEF_FOR_PERSP_MODES(false)
|