blob: 25ab73a0798e49817bfd7249e4224b9fe45ae535 [file] [log] [blame]
reed@android.combd700c32009-01-05 03:34:50 +00001#include "SkCanvas.h"
reed@android.comb398fe82009-01-07 11:47:57 +00002#include "SkImageEncoder.h"
reed@android.combd700c32009-01-05 03:34:50 +00003#include "SkString.h"
reed@android.com4bc19832009-01-19 20:08:35 +00004#include "SkTime.h"
reed@android.coma70ba362009-01-22 17:41:57 +00005#include "SkTRegistry.h"
reed@android.combd700c32009-01-05 03:34:50 +00006
7#include "SkBenchmark.h"
8
reed@android.coma70ba362009-01-22 17:41:57 +00009typedef SkTRegistry<SkBenchmark*, void*> BenchRegistry;
reed@android.combd700c32009-01-05 03:34:50 +000010
11class Iter {
12public:
13 Iter() {
14 fBench = BenchRegistry::Head();
15 }
16
17 SkBenchmark* next() {
18 if (fBench) {
19 BenchRegistry::Factory f = fBench->factory();
20 fBench = fBench->next();
reed@android.coma70ba362009-01-22 17:41:57 +000021 return f(0);
reed@android.combd700c32009-01-05 03:34:50 +000022 }
23 return NULL;
24 }
25
26private:
27 const BenchRegistry* fBench;
28};
29
30static void make_filename(const char name[], SkString* path) {
31 path->set(name);
32 for (int i = 0; name[i]; i++) {
33 switch (name[i]) {
34 case '/':
35 case '\\':
36 case ' ':
37 case ':':
38 path->writable_str()[i] = '-';
39 break;
40 default:
41 break;
42 }
43 }
44}
45
reed@android.com4c7d3d62009-01-21 03:15:13 +000046static void saveFile(const char name[], const char config[], const char dir[],
47 const SkBitmap& bm) {
reed@android.com4c7d3d62009-01-21 03:15:13 +000048 SkBitmap copy;
49 if (!bm.copyTo(&copy, SkBitmap::kARGB_8888_Config)) {
50 return;
51 }
52
53 SkString str;
54 make_filename(name, &str);
55 str.appendf("_%s.png", config);
56 str.prepend(dir);
57 ::remove(str.c_str());
58 SkImageEncoder::EncodeFile(str.c_str(), copy, SkImageEncoder::kPNG_Type,
59 100);
reed@android.com4c7d3d62009-01-21 03:15:13 +000060}
61
62static void performClip(SkCanvas* canvas, int w, int h) {
63 SkRect r;
64
65 r.set(SkIntToScalar(10), SkIntToScalar(10),
66 SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
67 canvas->clipRect(r, SkRegion::kIntersect_Op);
68
69 r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
70 SkIntToScalar(w-10), SkIntToScalar(h-10));
71 canvas->clipRect(r, SkRegion::kXOR_Op);
72}
73
74static void performRotate(SkCanvas* canvas, int w, int h) {
75 const SkScalar x = SkIntToScalar(w) / 2;
76 const SkScalar y = SkIntToScalar(h) / 2;
77
78 canvas->translate(x, y);
79 canvas->rotate(SkIntToScalar(35));
80 canvas->translate(-x, -y);
81}
82
reed@android.com4bc19832009-01-19 20:08:35 +000083static const struct {
84 SkBitmap::Config fConfig;
85 const char* fName;
86} gConfigs[] = {
87 { SkBitmap::kARGB_8888_Config, "8888" },
88 { SkBitmap::kRGB_565_Config, "565", },
89 { SkBitmap::kARGB_4444_Config, "4444", },
90 { SkBitmap::kA8_Config, "A8", }
91};
92
reed@android.com4c7d3d62009-01-21 03:15:13 +000093static int findConfig(const char config[]) {
94 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
95 if (!strcmp(config, gConfigs[i].fName)) {
96 return i;
97 }
98 }
99 return -1;
100}
101
reed@android.combd700c32009-01-05 03:34:50 +0000102int main (int argc, char * const argv[]) {
reed@android.com4bc19832009-01-19 20:08:35 +0000103 int repeatDraw = 1;
104 int forceAlpha = 0xFF;
105 bool forceAA = true;
reed@android.com4c7d3d62009-01-21 03:15:13 +0000106 bool doRotate = false;
107 bool doClip = false;
reed@android.com4bc19832009-01-19 20:08:35 +0000108
reed@android.comb398fe82009-01-07 11:47:57 +0000109 SkString outDir;
110 SkBitmap::Config outConfig = SkBitmap::kARGB_8888_Config;
reed@android.combd700c32009-01-05 03:34:50 +0000111
reed@android.comb398fe82009-01-07 11:47:57 +0000112 char* const* stop = argv + argc;
113 for (++argv; argv < stop; ++argv) {
114 if (strcmp(*argv, "-o") == 0) {
115 argv++;
116 if (argv < stop && **argv) {
117 outDir.set(*argv);
118 if (outDir.c_str()[outDir.size() - 1] != '/') {
119 outDir.append("/");
120 }
121 }
reed@android.com4bc19832009-01-19 20:08:35 +0000122 } else if (strcmp(*argv, "-repeat") == 0) {
123 argv++;
124 if (argv < stop) {
125 repeatDraw = atoi(*argv);
126 if (repeatDraw < 1) {
127 repeatDraw = 1;
128 }
129 } else {
130 fprintf(stderr, "missing arg for -repeat\n");
131 return -1;
132 }
reed@android.com4c7d3d62009-01-21 03:15:13 +0000133 } else if (!strcmp(*argv, "-rotate")) {
134 doRotate = true;
135 } else if (!strcmp(*argv, "-clip")) {
136 doClip = true;
reed@android.com4bc19832009-01-19 20:08:35 +0000137 } else if (strcmp(*argv, "-forceAA") == 0) {
138 forceAA = true;
139 } else if (strcmp(*argv, "-forceBW") == 0) {
140 forceAA = false;
141 } else if (strcmp(*argv, "-forceBlend") == 0) {
142 forceAlpha = 0x80;
143 } else if (strcmp(*argv, "-forceOpaque") == 0) {
144 forceAlpha = 0xFF;
reed@android.com4c7d3d62009-01-21 03:15:13 +0000145 } else {
146 int index = findConfig(*argv);
147 if (index >= 0) {
148 outConfig = gConfigs[index].fConfig;
149 }
reed@android.comb398fe82009-01-07 11:47:57 +0000150 }
151 }
reed@android.com4bc19832009-01-19 20:08:35 +0000152
153 const char* configName = "";
154 int configCount = SK_ARRAY_COUNT(gConfigs);
155
reed@android.combd700c32009-01-05 03:34:50 +0000156 Iter iter;
157 SkBenchmark* bench;
158 while ((bench = iter.next()) != NULL) {
reed@android.comb398fe82009-01-07 11:47:57 +0000159 SkIPoint dim = bench->getSize();
160 if (dim.fX <= 0 || dim.fY <= 0) {
161 continue;
162 }
reed@android.comb398fe82009-01-07 11:47:57 +0000163
reed@android.com4bc19832009-01-19 20:08:35 +0000164 bench->setForceAlpha(forceAlpha);
165 bench->setForceAA(forceAA);
166
reed@android.com4c7d3d62009-01-21 03:15:13 +0000167 printf("running bench %8s", bench->getName());
reed@android.com4bc19832009-01-19 20:08:35 +0000168
169 for (int configIndex = 0; configIndex < configCount; configIndex++) {
170 if (configCount > 1) {
171 outConfig = gConfigs[configIndex].fConfig;
172 configName = gConfigs[configIndex].fName;
173 }
174
175 SkBitmap bm;
176 bm.setConfig(outConfig, dim.fX, dim.fY);
177 bm.allocPixels();
178
179 SkCanvas canvas(bm);
180 canvas.drawColor(SK_ColorWHITE);
181
reed@android.com4c7d3d62009-01-21 03:15:13 +0000182 if (doClip) {
183 performClip(&canvas, dim.fX, dim.fY);
184 }
185 if (doRotate) {
186 performRotate(&canvas, dim.fX, dim.fY);
187 }
188
reed@android.com4bc19832009-01-19 20:08:35 +0000189 SkMSec now = SkTime::GetMSecs();
190 for (int i = 0; i < repeatDraw; i++) {
reed@android.com4c7d3d62009-01-21 03:15:13 +0000191 SkAutoCanvasRestore acr(&canvas, true);
reed@android.com4bc19832009-01-19 20:08:35 +0000192 bench->draw(&canvas);
193 }
194 if (repeatDraw > 1) {
195 printf(" %4s:%7.2f", configName,
196 (SkTime::GetMSecs() - now) / (double)repeatDraw);
197 }
reed@android.com4c7d3d62009-01-21 03:15:13 +0000198 if (outDir.size() > 0) {
199 saveFile(bench->getName(), configName, outDir.c_str(), bm);
200 }
reed@android.com4bc19832009-01-19 20:08:35 +0000201 }
202 printf("\n");
reed@android.combd700c32009-01-05 03:34:50 +0000203 }
204
205 return 0;
206}