blob: 88911541b2851471627e00a2e284c13aa1f1b6aa [file] [log] [blame]
reed@android.combd700c32009-01-05 03:34:50 +00001#include "SkCanvas.h"
reed@android.comf523e252009-01-26 23:15:37 +00002#include "SkColorPriv.h"
reed@android.comb398fe82009-01-07 11:47:57 +00003#include "SkImageEncoder.h"
reed@android.combd700c32009-01-05 03:34:50 +00004#include "SkString.h"
reed@android.com4bc19832009-01-19 20:08:35 +00005#include "SkTime.h"
reed@android.combd700c32009-01-05 03:34:50 +00006
7#include "SkBenchmark.h"
8
reed@android.combd700c32009-01-05 03:34:50 +00009class Iter {
10public:
11 Iter() {
12 fBench = BenchRegistry::Head();
13 }
14
15 SkBenchmark* next() {
16 if (fBench) {
17 BenchRegistry::Factory f = fBench->factory();
18 fBench = fBench->next();
reed@android.coma70ba362009-01-22 17:41:57 +000019 return f(0);
reed@android.combd700c32009-01-05 03:34:50 +000020 }
21 return NULL;
22 }
23
24private:
25 const BenchRegistry* fBench;
26};
27
28static void make_filename(const char name[], SkString* path) {
29 path->set(name);
30 for (int i = 0; name[i]; i++) {
31 switch (name[i]) {
32 case '/':
33 case '\\':
34 case ' ':
35 case ':':
36 path->writable_str()[i] = '-';
37 break;
38 default:
39 break;
40 }
41 }
42}
43
reed@android.com4c7d3d62009-01-21 03:15:13 +000044static void saveFile(const char name[], const char config[], const char dir[],
45 const SkBitmap& bm) {
reed@android.com4c7d3d62009-01-21 03:15:13 +000046 SkBitmap copy;
47 if (!bm.copyTo(&copy, SkBitmap::kARGB_8888_Config)) {
48 return;
49 }
reed@android.comf523e252009-01-26 23:15:37 +000050
51 if (bm.config() == SkBitmap::kA8_Config) {
52 // turn alpha into gray-scale
53 size_t size = copy.getSize() >> 2;
54 SkPMColor* p = copy.getAddr32(0, 0);
55 for (size_t i = 0; i < size; i++) {
56 int c = (*p >> SK_A32_SHIFT) & 0xFF;
57 c = 255 - c;
58 c |= (c << 24) | (c << 16) | (c << 8);
59 *p++ = c | (SK_A32_MASK << SK_A32_SHIFT);
60 }
61 }
reed@android.com4c7d3d62009-01-21 03:15:13 +000062
63 SkString str;
64 make_filename(name, &str);
65 str.appendf("_%s.png", config);
66 str.prepend(dir);
67 ::remove(str.c_str());
68 SkImageEncoder::EncodeFile(str.c_str(), copy, SkImageEncoder::kPNG_Type,
69 100);
reed@android.com4c7d3d62009-01-21 03:15:13 +000070}
71
72static void performClip(SkCanvas* canvas, int w, int h) {
73 SkRect r;
74
75 r.set(SkIntToScalar(10), SkIntToScalar(10),
76 SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
77 canvas->clipRect(r, SkRegion::kIntersect_Op);
78
79 r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
80 SkIntToScalar(w-10), SkIntToScalar(h-10));
81 canvas->clipRect(r, SkRegion::kXOR_Op);
82}
83
84static void performRotate(SkCanvas* canvas, int w, int h) {
85 const SkScalar x = SkIntToScalar(w) / 2;
86 const SkScalar y = SkIntToScalar(h) / 2;
87
88 canvas->translate(x, y);
89 canvas->rotate(SkIntToScalar(35));
90 canvas->translate(-x, -y);
91}
92
reed@android.com4bc19832009-01-19 20:08:35 +000093static const struct {
94 SkBitmap::Config fConfig;
95 const char* fName;
96} gConfigs[] = {
97 { SkBitmap::kARGB_8888_Config, "8888" },
98 { SkBitmap::kRGB_565_Config, "565", },
99 { SkBitmap::kARGB_4444_Config, "4444", },
100 { SkBitmap::kA8_Config, "A8", }
101};
102
reed@android.com4c7d3d62009-01-21 03:15:13 +0000103static int findConfig(const char config[]) {
104 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
105 if (!strcmp(config, gConfigs[i].fName)) {
106 return i;
107 }
108 }
109 return -1;
110}
111
reed@android.combd700c32009-01-05 03:34:50 +0000112int main (int argc, char * const argv[]) {
reed@android.com4bc19832009-01-19 20:08:35 +0000113 int repeatDraw = 1;
114 int forceAlpha = 0xFF;
115 bool forceAA = true;
reed@android.com4c7d3d62009-01-21 03:15:13 +0000116 bool doRotate = false;
117 bool doClip = false;
reed@android.com4bc19832009-01-19 20:08:35 +0000118
reed@android.comb398fe82009-01-07 11:47:57 +0000119 SkString outDir;
120 SkBitmap::Config outConfig = SkBitmap::kARGB_8888_Config;
reed@android.combd700c32009-01-05 03:34:50 +0000121
reed@android.comb398fe82009-01-07 11:47:57 +0000122 char* const* stop = argv + argc;
123 for (++argv; argv < stop; ++argv) {
124 if (strcmp(*argv, "-o") == 0) {
125 argv++;
126 if (argv < stop && **argv) {
127 outDir.set(*argv);
128 if (outDir.c_str()[outDir.size() - 1] != '/') {
129 outDir.append("/");
130 }
131 }
reed@android.com4bc19832009-01-19 20:08:35 +0000132 } else if (strcmp(*argv, "-repeat") == 0) {
133 argv++;
134 if (argv < stop) {
135 repeatDraw = atoi(*argv);
136 if (repeatDraw < 1) {
137 repeatDraw = 1;
138 }
139 } else {
140 fprintf(stderr, "missing arg for -repeat\n");
141 return -1;
142 }
reed@android.com4c7d3d62009-01-21 03:15:13 +0000143 } else if (!strcmp(*argv, "-rotate")) {
144 doRotate = true;
145 } else if (!strcmp(*argv, "-clip")) {
146 doClip = true;
reed@android.com4bc19832009-01-19 20:08:35 +0000147 } else if (strcmp(*argv, "-forceAA") == 0) {
148 forceAA = true;
149 } else if (strcmp(*argv, "-forceBW") == 0) {
150 forceAA = false;
151 } else if (strcmp(*argv, "-forceBlend") == 0) {
152 forceAlpha = 0x80;
153 } else if (strcmp(*argv, "-forceOpaque") == 0) {
154 forceAlpha = 0xFF;
reed@android.com4c7d3d62009-01-21 03:15:13 +0000155 } else {
156 int index = findConfig(*argv);
157 if (index >= 0) {
158 outConfig = gConfigs[index].fConfig;
159 }
reed@android.comb398fe82009-01-07 11:47:57 +0000160 }
161 }
reed@android.com4bc19832009-01-19 20:08:35 +0000162
163 const char* configName = "";
164 int configCount = SK_ARRAY_COUNT(gConfigs);
165
reed@android.combd700c32009-01-05 03:34:50 +0000166 Iter iter;
167 SkBenchmark* bench;
168 while ((bench = iter.next()) != NULL) {
reed@android.comb398fe82009-01-07 11:47:57 +0000169 SkIPoint dim = bench->getSize();
170 if (dim.fX <= 0 || dim.fY <= 0) {
171 continue;
172 }
reed@android.comb398fe82009-01-07 11:47:57 +0000173
reed@android.com4bc19832009-01-19 20:08:35 +0000174 bench->setForceAlpha(forceAlpha);
175 bench->setForceAA(forceAA);
176
reed@android.comf523e252009-01-26 23:15:37 +0000177 printf("running bench %16s", bench->getName());
reed@android.com4bc19832009-01-19 20:08:35 +0000178
179 for (int configIndex = 0; configIndex < configCount; configIndex++) {
180 if (configCount > 1) {
181 outConfig = gConfigs[configIndex].fConfig;
182 configName = gConfigs[configIndex].fName;
183 }
184
185 SkBitmap bm;
186 bm.setConfig(outConfig, dim.fX, dim.fY);
187 bm.allocPixels();
188
reed@android.comf523e252009-01-26 23:15:37 +0000189 if (bm.config() == SkBitmap::kA8_Config) {
190 bm.eraseColor(0);
191 } else {
192 bm.eraseColor(SK_ColorWHITE);
193 }
194
reed@android.com4bc19832009-01-19 20:08:35 +0000195 SkCanvas canvas(bm);
reed@android.comf523e252009-01-26 23:15:37 +0000196
reed@android.com4c7d3d62009-01-21 03:15:13 +0000197 if (doClip) {
198 performClip(&canvas, dim.fX, dim.fY);
199 }
200 if (doRotate) {
201 performRotate(&canvas, dim.fX, dim.fY);
202 }
203
reed@android.com4bc19832009-01-19 20:08:35 +0000204 SkMSec now = SkTime::GetMSecs();
205 for (int i = 0; i < repeatDraw; i++) {
reed@android.com4c7d3d62009-01-21 03:15:13 +0000206 SkAutoCanvasRestore acr(&canvas, true);
reed@android.com4bc19832009-01-19 20:08:35 +0000207 bench->draw(&canvas);
208 }
209 if (repeatDraw > 1) {
210 printf(" %4s:%7.2f", configName,
211 (SkTime::GetMSecs() - now) / (double)repeatDraw);
212 }
reed@android.com4c7d3d62009-01-21 03:15:13 +0000213 if (outDir.size() > 0) {
214 saveFile(bench->getName(), configName, outDir.c_str(), bm);
215 }
reed@android.com4bc19832009-01-19 20:08:35 +0000216 }
217 printf("\n");
reed@android.combd700c32009-01-05 03:34:50 +0000218 }
219
220 return 0;
221}