blob: d66482f5ccd3a80f27ff0a2802b673c08d59d8d5 [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.com3a859a02009-01-28 00:56:29 +00003#include "SkGraphics.h"
reed@android.comb398fe82009-01-07 11:47:57 +00004#include "SkImageEncoder.h"
reed@android.combd700c32009-01-05 03:34:50 +00005#include "SkString.h"
reed@android.com4bc19832009-01-19 20:08:35 +00006#include "SkTime.h"
reed@android.combd700c32009-01-05 03:34:50 +00007
8#include "SkBenchmark.h"
9
reed@android.combd700c32009-01-05 03:34:50 +000010class Iter {
11public:
12 Iter() {
13 fBench = BenchRegistry::Head();
14 }
15
16 SkBenchmark* next() {
17 if (fBench) {
18 BenchRegistry::Factory f = fBench->factory();
19 fBench = fBench->next();
reed@android.coma70ba362009-01-22 17:41:57 +000020 return f(0);
reed@android.combd700c32009-01-05 03:34:50 +000021 }
22 return NULL;
23 }
24
25private:
26 const BenchRegistry* fBench;
27};
28
29static void make_filename(const char name[], SkString* path) {
30 path->set(name);
31 for (int i = 0; name[i]; i++) {
32 switch (name[i]) {
33 case '/':
34 case '\\':
35 case ' ':
36 case ':':
37 path->writable_str()[i] = '-';
38 break;
39 default:
40 break;
41 }
42 }
43}
44
reed@android.com4c7d3d62009-01-21 03:15:13 +000045static void saveFile(const char name[], const char config[], const char dir[],
46 const SkBitmap& bm) {
reed@android.com4c7d3d62009-01-21 03:15:13 +000047 SkBitmap copy;
48 if (!bm.copyTo(&copy, SkBitmap::kARGB_8888_Config)) {
49 return;
50 }
reed@android.comf523e252009-01-26 23:15:37 +000051
52 if (bm.config() == SkBitmap::kA8_Config) {
53 // turn alpha into gray-scale
54 size_t size = copy.getSize() >> 2;
55 SkPMColor* p = copy.getAddr32(0, 0);
56 for (size_t i = 0; i < size; i++) {
57 int c = (*p >> SK_A32_SHIFT) & 0xFF;
58 c = 255 - c;
59 c |= (c << 24) | (c << 16) | (c << 8);
60 *p++ = c | (SK_A32_MASK << SK_A32_SHIFT);
61 }
62 }
reed@android.com4c7d3d62009-01-21 03:15:13 +000063
64 SkString str;
65 make_filename(name, &str);
66 str.appendf("_%s.png", config);
67 str.prepend(dir);
68 ::remove(str.c_str());
69 SkImageEncoder::EncodeFile(str.c_str(), copy, SkImageEncoder::kPNG_Type,
70 100);
reed@android.com4c7d3d62009-01-21 03:15:13 +000071}
72
73static void performClip(SkCanvas* canvas, int w, int h) {
74 SkRect r;
75
76 r.set(SkIntToScalar(10), SkIntToScalar(10),
77 SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
78 canvas->clipRect(r, SkRegion::kIntersect_Op);
79
80 r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
81 SkIntToScalar(w-10), SkIntToScalar(h-10));
82 canvas->clipRect(r, SkRegion::kXOR_Op);
83}
84
85static void performRotate(SkCanvas* canvas, int w, int h) {
86 const SkScalar x = SkIntToScalar(w) / 2;
87 const SkScalar y = SkIntToScalar(h) / 2;
88
89 canvas->translate(x, y);
90 canvas->rotate(SkIntToScalar(35));
91 canvas->translate(-x, -y);
92}
93
reed@android.com4bc19832009-01-19 20:08:35 +000094static const struct {
95 SkBitmap::Config fConfig;
96 const char* fName;
97} gConfigs[] = {
98 { SkBitmap::kARGB_8888_Config, "8888" },
99 { SkBitmap::kRGB_565_Config, "565", },
100 { SkBitmap::kARGB_4444_Config, "4444", },
101 { SkBitmap::kA8_Config, "A8", }
102};
103
reed@android.com4c7d3d62009-01-21 03:15:13 +0000104static int findConfig(const char config[]) {
105 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
106 if (!strcmp(config, gConfigs[i].fName)) {
107 return i;
108 }
109 }
110 return -1;
111}
112
reed@android.com3a859a02009-01-28 00:56:29 +0000113class SkAutoGraphics {
114public:
115 SkAutoGraphics(bool runUnitTests = false) {
116 SkGraphics::Init(runUnitTests);
117 }
118 ~SkAutoGraphics() {
119 SkGraphics::Term();
120 }
121};
122
reed@android.combd700c32009-01-05 03:34:50 +0000123int main (int argc, char * const argv[]) {
reed@android.com3a859a02009-01-28 00:56:29 +0000124 SkAutoGraphics ag;
125
reed@android.com4bc19832009-01-19 20:08:35 +0000126 int repeatDraw = 1;
127 int forceAlpha = 0xFF;
128 bool forceAA = true;
reed@android.com4c7d3d62009-01-21 03:15:13 +0000129 bool doRotate = false;
130 bool doClip = false;
reed@android.com4bc19832009-01-19 20:08:35 +0000131
reed@android.comb398fe82009-01-07 11:47:57 +0000132 SkString outDir;
133 SkBitmap::Config outConfig = SkBitmap::kARGB_8888_Config;
reed@android.combd700c32009-01-05 03:34:50 +0000134
reed@android.comb398fe82009-01-07 11:47:57 +0000135 char* const* stop = argv + argc;
136 for (++argv; argv < stop; ++argv) {
137 if (strcmp(*argv, "-o") == 0) {
138 argv++;
139 if (argv < stop && **argv) {
140 outDir.set(*argv);
141 if (outDir.c_str()[outDir.size() - 1] != '/') {
142 outDir.append("/");
143 }
144 }
reed@android.com4bc19832009-01-19 20:08:35 +0000145 } else if (strcmp(*argv, "-repeat") == 0) {
146 argv++;
147 if (argv < stop) {
148 repeatDraw = atoi(*argv);
149 if (repeatDraw < 1) {
150 repeatDraw = 1;
151 }
152 } else {
153 fprintf(stderr, "missing arg for -repeat\n");
154 return -1;
155 }
reed@android.com4c7d3d62009-01-21 03:15:13 +0000156 } else if (!strcmp(*argv, "-rotate")) {
157 doRotate = true;
158 } else if (!strcmp(*argv, "-clip")) {
159 doClip = true;
reed@android.com4bc19832009-01-19 20:08:35 +0000160 } else if (strcmp(*argv, "-forceAA") == 0) {
161 forceAA = true;
162 } else if (strcmp(*argv, "-forceBW") == 0) {
163 forceAA = false;
164 } else if (strcmp(*argv, "-forceBlend") == 0) {
165 forceAlpha = 0x80;
166 } else if (strcmp(*argv, "-forceOpaque") == 0) {
167 forceAlpha = 0xFF;
reed@android.com4c7d3d62009-01-21 03:15:13 +0000168 } else {
169 int index = findConfig(*argv);
170 if (index >= 0) {
171 outConfig = gConfigs[index].fConfig;
172 }
reed@android.comb398fe82009-01-07 11:47:57 +0000173 }
174 }
reed@android.com4bc19832009-01-19 20:08:35 +0000175
176 const char* configName = "";
177 int configCount = SK_ARRAY_COUNT(gConfigs);
178
reed@android.combd700c32009-01-05 03:34:50 +0000179 Iter iter;
180 SkBenchmark* bench;
181 while ((bench = iter.next()) != NULL) {
reed@android.comb398fe82009-01-07 11:47:57 +0000182 SkIPoint dim = bench->getSize();
183 if (dim.fX <= 0 || dim.fY <= 0) {
184 continue;
185 }
reed@android.comb398fe82009-01-07 11:47:57 +0000186
reed@android.com4bc19832009-01-19 20:08:35 +0000187 bench->setForceAlpha(forceAlpha);
188 bench->setForceAA(forceAA);
189
reed@android.comf523e252009-01-26 23:15:37 +0000190 printf("running bench %16s", bench->getName());
reed@android.com4bc19832009-01-19 20:08:35 +0000191
192 for (int configIndex = 0; configIndex < configCount; configIndex++) {
193 if (configCount > 1) {
194 outConfig = gConfigs[configIndex].fConfig;
195 configName = gConfigs[configIndex].fName;
196 }
197
198 SkBitmap bm;
199 bm.setConfig(outConfig, dim.fX, dim.fY);
200 bm.allocPixels();
201
reed@android.comf523e252009-01-26 23:15:37 +0000202 if (bm.config() == SkBitmap::kA8_Config) {
203 bm.eraseColor(0);
204 } else {
205 bm.eraseColor(SK_ColorWHITE);
206 }
207
reed@android.com4bc19832009-01-19 20:08:35 +0000208 SkCanvas canvas(bm);
reed@android.comf523e252009-01-26 23:15:37 +0000209
reed@android.com4c7d3d62009-01-21 03:15:13 +0000210 if (doClip) {
211 performClip(&canvas, dim.fX, dim.fY);
212 }
213 if (doRotate) {
214 performRotate(&canvas, dim.fX, dim.fY);
215 }
216
reed@android.com4bc19832009-01-19 20:08:35 +0000217 SkMSec now = SkTime::GetMSecs();
218 for (int i = 0; i < repeatDraw; i++) {
reed@android.com4c7d3d62009-01-21 03:15:13 +0000219 SkAutoCanvasRestore acr(&canvas, true);
reed@android.com4bc19832009-01-19 20:08:35 +0000220 bench->draw(&canvas);
221 }
222 if (repeatDraw > 1) {
223 printf(" %4s:%7.2f", configName,
224 (SkTime::GetMSecs() - now) / (double)repeatDraw);
225 }
reed@android.com4c7d3d62009-01-21 03:15:13 +0000226 if (outDir.size() > 0) {
227 saveFile(bench->getName(), configName, outDir.c_str(), bm);
228 }
reed@android.com4bc19832009-01-19 20:08:35 +0000229 }
230 printf("\n");
reed@android.combd700c32009-01-05 03:34:50 +0000231 }
232
233 return 0;
234}