blob: c37a6bef0990d5966ed5a1d56f8729d1f34db1ac [file] [log] [blame]
bsalomon3342ed52014-07-30 08:58:20 -07001/*
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
bsalomon65635622014-08-08 07:43:29 -070012#include <ctype.h>
13
bsalomon3342ed52014-07-30 08:58:20 -070014/** This benchmark tests rendering rotated rectangles. It can optionally apply AA and/or change the
bsalomon65635622014-08-08 07:43:29 -070015 paint color between each rect in different ways using the ColorType enum. The xfermode used can
16 be specified as well.
17 */
18
19enum ColorType {
20 kConstantOpaque_ColorType,
21 kConstantTransparent_ColorType,
22 kChangingOpaque_ColorType,
23 kChangingTransparent_ColorType,
24 kAlternatingOpaqueAndTransparent_ColorType,
25};
26
27static 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
41static 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
60static 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
bsalomon3342ed52014-07-30 08:58:20 -070068class RotRectBench: public Benchmark {
69public:
bsalomon65635622014-08-08 07:43:29 -070070 RotRectBench(bool aa, ColorType ct, SkXfermode::Mode mode)
bsalomon3342ed52014-07-30 08:58:20 -070071 : fAA(aa)
bsalomon65635622014-08-08 07:43:29 -070072 , fColorType(ct)
73 , fMode(mode) {
bsalomon3342ed52014-07-30 08:58:20 -070074 this->makeName();
75 }
76
77protected:
mtklein36352bf2015-03-25 18:17:31 -070078 const char* onGetName() override { return fName.c_str(); }
bsalomon3342ed52014-07-30 08:58:20 -070079
mtklein36352bf2015-03-25 18:17:31 -070080 void onDraw(const int loops, SkCanvas* canvas) override {
bsalomon3342ed52014-07-30 08:58:20 -070081 SkPaint paint;
82 paint.setAntiAlias(fAA);
bsalomon65635622014-08-08 07:43:29 -070083 paint.setXfermodeMode(fMode);
84 SkColor color = start_color(fColorType);
bsalomon3342ed52014-07-30 08:58:20 -070085
tomhudsonc589f6c2015-03-23 07:46:13 -070086 int w = this->getSize().x();
87 int h = this->getSize().y();
bsalomon3342ed52014-07-30 08:58:20 -070088
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);
bsalomon65635622014-08-08 07:43:29 -0700104 color = advance_color(color, fColorType, i);
105
bsalomon3342ed52014-07-30 08:58:20 -0700106 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
122private:
123 void makeName() {
124 fName = "rotated_rects";
125 if (fAA) {
126 fName.append("_aa");
127 } else {
128 fName.append("_bw");
129 }
bsalomon65635622014-08-08 07:43:29 -0700130 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;
bsalomon3342ed52014-07-30 08:58:20 -0700146 }
bsalomon65635622014-08-08 07:43:29 -0700147 fName.appendf("_%s", to_lower(SkXfermode::ModeName(fMode)).c_str());
bsalomon3342ed52014-07-30 08:58:20 -0700148 }
149
bsalomon65635622014-08-08 07:43:29 -0700150 bool fAA;
151 ColorType fColorType;
152 SkXfermode::Mode fMode;
153 SkString fName;
bsalomon3342ed52014-07-30 08:58:20 -0700154
155 typedef Benchmark INHERITED;
156};
157
bsalomon65635622014-08-08 07:43:29 -0700158// 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.
160DEF_BENCH(return new RotRectBench(true, kConstantOpaque_ColorType, SkXfermode::kSrcOver_Mode);)
161DEF_BENCH(return new RotRectBench(true, kConstantTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
162DEF_BENCH(return new RotRectBench(true, kChangingOpaque_ColorType, SkXfermode::kSrcOver_Mode);)
163DEF_BENCH(return new RotRectBench(true, kChangingTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
164DEF_BENCH(return new RotRectBench(true, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
165
166DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType, SkXfermode::kSrcOver_Mode);)
167DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
168DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType, SkXfermode::kSrcOver_Mode);)
169DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
170DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
171
172DEF_BENCH(return new RotRectBench(true, kConstantOpaque_ColorType, SkXfermode::kSrc_Mode);)
173DEF_BENCH(return new RotRectBench(true, kConstantTransparent_ColorType, SkXfermode::kSrc_Mode);)
174DEF_BENCH(return new RotRectBench(true, kChangingOpaque_ColorType, SkXfermode::kSrc_Mode);)
175DEF_BENCH(return new RotRectBench(true, kChangingTransparent_ColorType, SkXfermode::kSrc_Mode);)
176DEF_BENCH(return new RotRectBench(true, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrc_Mode);)
177
178DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType, SkXfermode::kSrc_Mode);)
179DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType, SkXfermode::kSrc_Mode);)
180DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType, SkXfermode::kSrc_Mode);)
181DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType, SkXfermode::kSrc_Mode);)
182DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrc_Mode);)
183
184DEF_BENCH(return new RotRectBench(true, kConstantOpaque_ColorType, SkXfermode::kDarken_Mode);)
185DEF_BENCH(return new RotRectBench(true, kConstantTransparent_ColorType, SkXfermode::kDarken_Mode);)
186DEF_BENCH(return new RotRectBench(true, kChangingOpaque_ColorType, SkXfermode::kDarken_Mode);)
187DEF_BENCH(return new RotRectBench(true, kChangingTransparent_ColorType, SkXfermode::kDarken_Mode);)
188DEF_BENCH(return new RotRectBench(true, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kDarken_Mode);)
189
190DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType, SkXfermode::kDarken_Mode);)
191DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType, SkXfermode::kDarken_Mode);)
192DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType, SkXfermode::kDarken_Mode);)
193DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType, SkXfermode::kDarken_Mode);)
194DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kDarken_Mode);)