| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright 2014 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 "Benchmark.h" | 
 | 9 | #include "SkCanvas.h" | 
 | 10 | #include "SkPaint.h" | 
 | 11 |  | 
| bsalomon | 6563562 | 2014-08-08 07:43:29 -0700 | [diff] [blame] | 12 | #include <ctype.h> | 
 | 13 |  | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 14 | /** This benchmark tests rendering rotated rectangles. It can optionally apply AA and/or change the | 
| bsalomon | 6563562 | 2014-08-08 07:43:29 -0700 | [diff] [blame] | 15 |     paint color between each rect in different ways using the ColorType enum. The xfermode used can | 
 | 16 |     be specified as well.  | 
 | 17 |   */ | 
 | 18 |  | 
 | 19 | enum ColorType { | 
 | 20 |     kConstantOpaque_ColorType, | 
 | 21 |     kConstantTransparent_ColorType, | 
 | 22 |     kChangingOpaque_ColorType, | 
 | 23 |     kChangingTransparent_ColorType, | 
 | 24 |     kAlternatingOpaqueAndTransparent_ColorType, | 
 | 25 | }; | 
 | 26 |  | 
 | 27 | static inline SkColor start_color(ColorType ct) { | 
 | 28 |     switch (ct) { | 
 | 29 |         case kConstantOpaque_ColorType: | 
 | 30 |         case kChangingOpaque_ColorType: | 
 | 31 |         case kAlternatingOpaqueAndTransparent_ColorType: | 
 | 32 |             return 0xFFA07040; | 
 | 33 |         case kConstantTransparent_ColorType: | 
 | 34 |         case kChangingTransparent_ColorType: | 
 | 35 |             return 0x80A07040; | 
 | 36 |     } | 
 | 37 |     SkFAIL("Shouldn't reach here."); | 
 | 38 |     return 0; | 
 | 39 | } | 
 | 40 |  | 
 | 41 | static inline SkColor advance_color(SkColor old, ColorType ct, int step) { | 
 | 42 |     if (kAlternatingOpaqueAndTransparent_ColorType == ct) { | 
 | 43 |         ct = (step & 0x1) ? kChangingOpaque_ColorType : kChangingTransparent_ColorType ; | 
 | 44 |     } | 
 | 45 |     switch (ct) { | 
 | 46 |         case kConstantOpaque_ColorType: | 
 | 47 |         case kConstantTransparent_ColorType: | 
 | 48 |             return old; | 
 | 49 |         case kChangingOpaque_ColorType: | 
 | 50 |             return 0xFF000000 | (old + 0x00010307); | 
 | 51 |         case kChangingTransparent_ColorType: | 
 | 52 |             return (0x00FFFFFF & (old + 0x00010307)) | 0x80000000; | 
 | 53 |         case kAlternatingOpaqueAndTransparent_ColorType: | 
 | 54 |             SkFAIL("Can't get here"); | 
 | 55 |     } | 
 | 56 |     SkFAIL("Shouldn't reach here."); | 
 | 57 |     return 0; | 
 | 58 | } | 
 | 59 |  | 
 | 60 | static SkString to_lower(const char* str) { | 
 | 61 |     SkString lower(str); | 
 | 62 |     for (size_t i = 0; i < lower.size(); i++) { | 
 | 63 |         lower[i] = tolower(lower[i]); | 
 | 64 |     } | 
 | 65 |     return lower; | 
 | 66 | } | 
 | 67 |  | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 68 | class RotRectBench: public Benchmark { | 
 | 69 | public: | 
| bsalomon | 6563562 | 2014-08-08 07:43:29 -0700 | [diff] [blame] | 70 |     RotRectBench(bool aa, ColorType ct, SkXfermode::Mode mode) | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 71 |         : fAA(aa) | 
| bsalomon | 6563562 | 2014-08-08 07:43:29 -0700 | [diff] [blame] | 72 |         , fColorType(ct) | 
 | 73 |         , fMode(mode) { | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 74 |         this->makeName(); | 
 | 75 |     } | 
 | 76 |  | 
 | 77 | protected: | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 78 |     const char* onGetName() override { return fName.c_str(); } | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 79 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 80 |     void onDraw(const int loops, SkCanvas* canvas) override { | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 81 |         SkPaint paint; | 
 | 82 |         paint.setAntiAlias(fAA); | 
| bsalomon | 6563562 | 2014-08-08 07:43:29 -0700 | [diff] [blame] | 83 |         paint.setXfermodeMode(fMode); | 
 | 84 |         SkColor color = start_color(fColorType); | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 85 |  | 
| tomhudson | c589f6c | 2015-03-23 07:46:13 -0700 | [diff] [blame] | 86 |         int w = this->getSize().x(); | 
 | 87 |         int h = this->getSize().y(); | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 88 |  | 
 | 89 |         static const SkScalar kRectW = 25.1f; | 
 | 90 |         static const SkScalar kRectH = 25.9f; | 
 | 91 |  | 
 | 92 |         SkMatrix rotate; | 
 | 93 |         // This value was chosen so that we frequently hit the axis-aligned case. | 
 | 94 |         rotate.setRotate(30.f, kRectW / 2, kRectH / 2); | 
 | 95 |         SkMatrix m = rotate; | 
 | 96 |  | 
 | 97 |         SkScalar tx = 0, ty = 0; | 
 | 98 |  | 
 | 99 |         for (int i = 0; i < loops; ++i) { | 
 | 100 |             canvas->save(); | 
 | 101 |             canvas->translate(tx, ty); | 
 | 102 |             canvas->concat(m); | 
 | 103 |             paint.setColor(color); | 
| bsalomon | 6563562 | 2014-08-08 07:43:29 -0700 | [diff] [blame] | 104 |             color = advance_color(color, fColorType, i); | 
 | 105 |  | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 106 |             canvas->drawRect(SkRect::MakeWH(kRectW, kRectH), paint); | 
 | 107 |             canvas->restore(); | 
 | 108 |  | 
 | 109 |             tx += kRectW + 2; | 
 | 110 |             if (tx > w) { | 
 | 111 |                 tx = 0; | 
 | 112 |                 ty += kRectH + 2; | 
 | 113 |                 if (ty > h) { | 
 | 114 |                     ty = 0; | 
 | 115 |                 } | 
 | 116 |             } | 
 | 117 |  | 
 | 118 |             m.postConcat(rotate); | 
 | 119 |         } | 
 | 120 |     } | 
 | 121 |  | 
 | 122 | private: | 
 | 123 |     void makeName() { | 
 | 124 |         fName = "rotated_rects"; | 
 | 125 |         if (fAA) { | 
 | 126 |             fName.append("_aa"); | 
 | 127 |         } else { | 
 | 128 |             fName.append("_bw"); | 
 | 129 |         } | 
| bsalomon | 6563562 | 2014-08-08 07:43:29 -0700 | [diff] [blame] | 130 |         switch (fColorType) { | 
 | 131 |             case kConstantOpaque_ColorType: | 
 | 132 |                 fName.append("_same_opaque"); | 
 | 133 |                 break; | 
 | 134 |             case kConstantTransparent_ColorType: | 
 | 135 |                 fName.append("_same_transparent"); | 
 | 136 |                 break; | 
 | 137 |             case kChangingOpaque_ColorType: | 
 | 138 |                 fName.append("_changing_opaque"); | 
 | 139 |                 break; | 
 | 140 |             case kChangingTransparent_ColorType: | 
 | 141 |                 fName.append("_changing_transparent"); | 
 | 142 |                 break; | 
 | 143 |             case kAlternatingOpaqueAndTransparent_ColorType: | 
 | 144 |                 fName.append("_alternating_transparent_and_opaque"); | 
 | 145 |                 break; | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 146 |         } | 
| bsalomon | 6563562 | 2014-08-08 07:43:29 -0700 | [diff] [blame] | 147 |         fName.appendf("_%s", to_lower(SkXfermode::ModeName(fMode)).c_str()); | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 148 |     } | 
 | 149 |  | 
| bsalomon | 6563562 | 2014-08-08 07:43:29 -0700 | [diff] [blame] | 150 |     bool             fAA; | 
 | 151 |     ColorType        fColorType; | 
 | 152 |     SkXfermode::Mode fMode; | 
 | 153 |     SkString         fName; | 
| bsalomon | 3342ed5 | 2014-07-30 08:58:20 -0700 | [diff] [blame] | 154 |  | 
 | 155 |     typedef Benchmark INHERITED; | 
 | 156 | }; | 
 | 157 |  | 
| bsalomon | 6563562 | 2014-08-08 07:43:29 -0700 | [diff] [blame] | 158 | // Choose kSrcOver because it always allows coverage and alpha to be conflated. kSrc only allows | 
 | 159 | // conflation when opaque, and kDarken because it isn't possilbe with standard GL blending. | 
 | 160 | DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);) | 
 | 161 | DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kSrcOver_Mode);) | 
 | 162 | DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);) | 
 | 163 | DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kSrcOver_Mode);) | 
 | 164 | DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrcOver_Mode);) | 
 | 165 |  | 
 | 166 | DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);) | 
 | 167 | DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kSrcOver_Mode);) | 
 | 168 | DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);) | 
 | 169 | DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kSrcOver_Mode);) | 
 | 170 | DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrcOver_Mode);) | 
 | 171 |  | 
 | 172 | DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kSrc_Mode);) | 
 | 173 | DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kSrc_Mode);) | 
 | 174 | DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kSrc_Mode);) | 
 | 175 | DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kSrc_Mode);) | 
 | 176 | DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrc_Mode);) | 
 | 177 |  | 
 | 178 | DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kSrc_Mode);) | 
 | 179 | DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kSrc_Mode);) | 
 | 180 | DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kSrc_Mode);) | 
 | 181 | DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kSrc_Mode);) | 
 | 182 | DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrc_Mode);) | 
 | 183 |  | 
 | 184 | DEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kDarken_Mode);) | 
 | 185 | DEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kDarken_Mode);) | 
 | 186 | DEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kDarken_Mode);) | 
 | 187 | DEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kDarken_Mode);) | 
 | 188 | DEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kDarken_Mode);) | 
 | 189 |  | 
 | 190 | DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kDarken_Mode);) | 
 | 191 | DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kDarken_Mode);) | 
 | 192 | DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kDarken_Mode);) | 
 | 193 | DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kDarken_Mode);) | 
 | 194 | DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kDarken_Mode);) |