blob: d9ee5823bfd9957cfad57eb6eaf4b09eb4324931 [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"
Mike Reedd4706732016-11-15 16:44:34 -05009#include "SkBlendModePriv.h"
bsalomon3342ed52014-07-30 08:58:20 -070010#include "SkCanvas.h"
11#include "SkPaint.h"
12
bsalomon65635622014-08-08 07:43:29 -070013#include <ctype.h>
14
bsalomon3342ed52014-07-30 08:58:20 -070015/** This benchmark tests rendering rotated rectangles. It can optionally apply AA and/or change the
bsalomon65635622014-08-08 07:43:29 -070016 paint color between each rect in different ways using the ColorType enum. The xfermode used can
halcanary9d524f22016-03-29 09:03:52 -070017 be specified as well.
bsalomon65635622014-08-08 07:43:29 -070018 */
19
20enum ColorType {
21 kConstantOpaque_ColorType,
22 kConstantTransparent_ColorType,
23 kChangingOpaque_ColorType,
24 kChangingTransparent_ColorType,
25 kAlternatingOpaqueAndTransparent_ColorType,
26};
27
28static inline SkColor start_color(ColorType ct) {
29 switch (ct) {
30 case kConstantOpaque_ColorType:
31 case kChangingOpaque_ColorType:
32 case kAlternatingOpaqueAndTransparent_ColorType:
33 return 0xFFA07040;
34 case kConstantTransparent_ColorType:
35 case kChangingTransparent_ColorType:
36 return 0x80A07040;
37 }
38 SkFAIL("Shouldn't reach here.");
39 return 0;
40}
41
42static inline SkColor advance_color(SkColor old, ColorType ct, int step) {
43 if (kAlternatingOpaqueAndTransparent_ColorType == ct) {
44 ct = (step & 0x1) ? kChangingOpaque_ColorType : kChangingTransparent_ColorType ;
45 }
46 switch (ct) {
47 case kConstantOpaque_ColorType:
48 case kConstantTransparent_ColorType:
49 return old;
50 case kChangingOpaque_ColorType:
51 return 0xFF000000 | (old + 0x00010307);
52 case kChangingTransparent_ColorType:
53 return (0x00FFFFFF & (old + 0x00010307)) | 0x80000000;
54 case kAlternatingOpaqueAndTransparent_ColorType:
55 SkFAIL("Can't get here");
56 }
57 SkFAIL("Shouldn't reach here.");
58 return 0;
59}
60
61static SkString to_lower(const char* str) {
62 SkString lower(str);
63 for (size_t i = 0; i < lower.size(); i++) {
64 lower[i] = tolower(lower[i]);
65 }
66 return lower;
67}
68
bsalomon3342ed52014-07-30 08:58:20 -070069class RotRectBench: public Benchmark {
70public:
reed374772b2016-10-05 17:33:02 -070071 RotRectBench(bool aa, ColorType ct, SkBlendMode mode)
bsalomon3342ed52014-07-30 08:58:20 -070072 : fAA(aa)
bsalomon65635622014-08-08 07:43:29 -070073 , fColorType(ct)
74 , fMode(mode) {
bsalomon3342ed52014-07-30 08:58:20 -070075 this->makeName();
76 }
77
78protected:
mtklein36352bf2015-03-25 18:17:31 -070079 const char* onGetName() override { return fName.c_str(); }
bsalomon3342ed52014-07-30 08:58:20 -070080
mtkleina1ebeb22015-10-01 09:43:39 -070081 void onDraw(int loops, SkCanvas* canvas) override {
bsalomon3342ed52014-07-30 08:58:20 -070082 SkPaint paint;
83 paint.setAntiAlias(fAA);
reed374772b2016-10-05 17:33:02 -070084 paint.setBlendMode(fMode);
bsalomon65635622014-08-08 07:43:29 -070085 SkColor color = start_color(fColorType);
bsalomon3342ed52014-07-30 08:58:20 -070086
tomhudsonc589f6c2015-03-23 07:46:13 -070087 int w = this->getSize().x();
88 int h = this->getSize().y();
bsalomon3342ed52014-07-30 08:58:20 -070089
90 static const SkScalar kRectW = 25.1f;
91 static const SkScalar kRectH = 25.9f;
92
93 SkMatrix rotate;
94 // This value was chosen so that we frequently hit the axis-aligned case.
95 rotate.setRotate(30.f, kRectW / 2, kRectH / 2);
96 SkMatrix m = rotate;
97
98 SkScalar tx = 0, ty = 0;
99
100 for (int i = 0; i < loops; ++i) {
101 canvas->save();
102 canvas->translate(tx, ty);
103 canvas->concat(m);
104 paint.setColor(color);
bsalomon65635622014-08-08 07:43:29 -0700105 color = advance_color(color, fColorType, i);
106
bsalomon3342ed52014-07-30 08:58:20 -0700107 canvas->drawRect(SkRect::MakeWH(kRectW, kRectH), paint);
108 canvas->restore();
109
110 tx += kRectW + 2;
111 if (tx > w) {
112 tx = 0;
113 ty += kRectH + 2;
114 if (ty > h) {
115 ty = 0;
116 }
117 }
118
119 m.postConcat(rotate);
120 }
121 }
122
123private:
124 void makeName() {
125 fName = "rotated_rects";
126 if (fAA) {
127 fName.append("_aa");
128 } else {
129 fName.append("_bw");
130 }
bsalomon65635622014-08-08 07:43:29 -0700131 switch (fColorType) {
132 case kConstantOpaque_ColorType:
133 fName.append("_same_opaque");
134 break;
135 case kConstantTransparent_ColorType:
136 fName.append("_same_transparent");
137 break;
138 case kChangingOpaque_ColorType:
139 fName.append("_changing_opaque");
140 break;
141 case kChangingTransparent_ColorType:
142 fName.append("_changing_transparent");
143 break;
144 case kAlternatingOpaqueAndTransparent_ColorType:
145 fName.append("_alternating_transparent_and_opaque");
146 break;
bsalomon3342ed52014-07-30 08:58:20 -0700147 }
Mike Reedd4706732016-11-15 16:44:34 -0500148 fName.appendf("_%s", to_lower(SkBlendMode_Name(fMode)).c_str());
bsalomon3342ed52014-07-30 08:58:20 -0700149 }
150
reed374772b2016-10-05 17:33:02 -0700151 bool fAA;
152 ColorType fColorType;
153 SkBlendMode fMode;
154 SkString fName;
bsalomon3342ed52014-07-30 08:58:20 -0700155
156 typedef Benchmark INHERITED;
157};
158
bsalomon65635622014-08-08 07:43:29 -0700159// Choose kSrcOver because it always allows coverage and alpha to be conflated. kSrc only allows
160// conflation when opaque, and kDarken because it isn't possilbe with standard GL blending.
reed374772b2016-10-05 17:33:02 -0700161DEF_BENCH(return new RotRectBench(true, kConstantOpaque_ColorType, SkBlendMode::kSrcOver);)
162DEF_BENCH(return new RotRectBench(true, kConstantTransparent_ColorType, SkBlendMode::kSrcOver);)
163DEF_BENCH(return new RotRectBench(true, kChangingOpaque_ColorType, SkBlendMode::kSrcOver);)
164DEF_BENCH(return new RotRectBench(true, kChangingTransparent_ColorType, SkBlendMode::kSrcOver);)
165DEF_BENCH(return new RotRectBench(true, kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kSrcOver);)
bsalomon65635622014-08-08 07:43:29 -0700166
reed374772b2016-10-05 17:33:02 -0700167DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType, SkBlendMode::kSrcOver);)
168DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType, SkBlendMode::kSrcOver);)
169DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType, SkBlendMode::kSrcOver);)
170DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType, SkBlendMode::kSrcOver);)
171DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kSrcOver);)
bsalomon65635622014-08-08 07:43:29 -0700172
reed374772b2016-10-05 17:33:02 -0700173DEF_BENCH(return new RotRectBench(true, kConstantOpaque_ColorType, SkBlendMode::kSrc);)
174DEF_BENCH(return new RotRectBench(true, kConstantTransparent_ColorType, SkBlendMode::kSrc);)
175DEF_BENCH(return new RotRectBench(true, kChangingOpaque_ColorType, SkBlendMode::kSrc);)
176DEF_BENCH(return new RotRectBench(true, kChangingTransparent_ColorType, SkBlendMode::kSrc);)
177DEF_BENCH(return new RotRectBench(true, kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kSrc);)
bsalomon65635622014-08-08 07:43:29 -0700178
reed374772b2016-10-05 17:33:02 -0700179DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType, SkBlendMode::kSrc);)
180DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType, SkBlendMode::kSrc);)
181DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType, SkBlendMode::kSrc);)
182DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType, SkBlendMode::kSrc);)
183DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kSrc);)
bsalomon65635622014-08-08 07:43:29 -0700184
reed374772b2016-10-05 17:33:02 -0700185DEF_BENCH(return new RotRectBench(true, kConstantOpaque_ColorType, SkBlendMode::kDarken);)
186DEF_BENCH(return new RotRectBench(true, kConstantTransparent_ColorType, SkBlendMode::kDarken);)
187DEF_BENCH(return new RotRectBench(true, kChangingOpaque_ColorType, SkBlendMode::kDarken);)
188DEF_BENCH(return new RotRectBench(true, kChangingTransparent_ColorType, SkBlendMode::kDarken);)
189DEF_BENCH(return new RotRectBench(true, kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kDarken);)
bsalomon65635622014-08-08 07:43:29 -0700190
reed374772b2016-10-05 17:33:02 -0700191DEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType, SkBlendMode::kDarken);)
192DEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType, SkBlendMode::kDarken);)
193DEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType, SkBlendMode::kDarken);)
194DEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType, SkBlendMode::kDarken);)
195DEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkBlendMode::kDarken);)