• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
12 #include <ctype.h>
13 
14 /** This benchmark tests rendering rotated rectangles. It can optionally apply AA and/or change the
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 
start_color(ColorType ct)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 
advance_color(SkColor old,ColorType ct,int step)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 
to_lower(const char * str)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 
68 class RotRectBench: public Benchmark {
69 public:
RotRectBench(bool aa,ColorType ct,SkXfermode::Mode mode)70     RotRectBench(bool aa, ColorType ct, SkXfermode::Mode mode)
71         : fAA(aa)
72         , fColorType(ct)
73         , fMode(mode) {
74         this->makeName();
75     }
76 
77 protected:
onGetName()78     const char* onGetName() override { return fName.c_str(); }
79 
onDraw(int loops,SkCanvas * canvas)80     void onDraw(int loops, SkCanvas* canvas) override {
81         SkPaint paint;
82         paint.setAntiAlias(fAA);
83         paint.setXfermodeMode(fMode);
84         SkColor color = start_color(fColorType);
85 
86         int w = this->getSize().x();
87         int h = this->getSize().y();
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);
104             color = advance_color(color, fColorType, i);
105 
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:
makeName()123     void makeName() {
124         fName = "rotated_rects";
125         if (fAA) {
126             fName.append("_aa");
127         } else {
128             fName.append("_bw");
129         }
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;
146         }
147         fName.appendf("_%s", to_lower(SkXfermode::ModeName(fMode)).c_str());
148     }
149 
150     bool             fAA;
151     ColorType        fColorType;
152     SkXfermode::Mode fMode;
153     SkString         fName;
154 
155     typedef Benchmark INHERITED;
156 };
157 
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);)
195