OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include <ctype.h> | 8 #include <ctype.h> |
9 | 9 |
10 #include "nanobench.h" | 10 #include "nanobench.h" |
11 | 11 |
12 #include "Benchmark.h" | 12 #include "Benchmark.h" |
13 #include "BitmapRegionDecoderBench.h" | 13 #include "BitmapRegionDecoderBench.h" |
14 #include "CodecBench.h" | 14 #include "CodecBench.h" |
15 #include "CodecBenchPriv.h" | 15 #include "CodecBenchPriv.h" |
16 #include "CrashHandler.h" | 16 #include "CrashHandler.h" |
17 #include "DecodingBench.h" | 17 #include "DecodingBench.h" |
18 #include "GMBench.h" | 18 #include "GMBench.h" |
19 #include "ProcStats.h" | 19 #include "ProcStats.h" |
20 #include "ResultsWriter.h" | 20 #include "ResultsWriter.h" |
21 #include "RecordingBench.h" | 21 #include "RecordingBench.h" |
22 #include "SKPAnimationBench.h" | 22 #include "SKPAnimationBench.h" |
23 #include "SKPBench.h" | 23 #include "SKPBench.h" |
24 #include "SubsetSingleBench.h" | 24 #include "SubsetSingleBench.h" |
25 #include "SubsetTranslateBench.h" | 25 #include "SubsetTranslateBench.h" |
26 #include "SubsetZoomBench.h" | 26 #include "SubsetZoomBench.h" |
27 #include "Stats.h" | 27 #include "Stats.h" |
28 #include "Timer.h" | |
29 | 28 |
30 #include "SkBitmapRegionDecoderInterface.h" | 29 #include "SkBitmapRegionDecoderInterface.h" |
31 #include "SkBBoxHierarchy.h" | 30 #include "SkBBoxHierarchy.h" |
32 #include "SkCanvas.h" | 31 #include "SkCanvas.h" |
33 #include "SkCodec.h" | 32 #include "SkCodec.h" |
34 #include "SkCommonFlags.h" | 33 #include "SkCommonFlags.h" |
35 #include "SkData.h" | 34 #include "SkData.h" |
36 #include "SkForceLinking.h" | 35 #include "SkForceLinking.h" |
37 #include "SkGraphics.h" | 36 #include "SkGraphics.h" |
38 #include "SkOSFile.h" | 37 #include "SkOSFile.h" |
(...skipping 13 matching lines...) Expand all Loading... |
52 #include "gl/GrGLDefines.h" | 51 #include "gl/GrGLDefines.h" |
53 #include "GrCaps.h" | 52 #include "GrCaps.h" |
54 #include "GrContextFactory.h" | 53 #include "GrContextFactory.h" |
55 SkAutoTDelete<GrContextFactory> gGrFactory; | 54 SkAutoTDelete<GrContextFactory> gGrFactory; |
56 #endif | 55 #endif |
57 | 56 |
58 struct GrContextOptions; | 57 struct GrContextOptions; |
59 | 58 |
60 __SK_FORCE_IMAGE_DECODER_LINKING; | 59 __SK_FORCE_IMAGE_DECODER_LINKING; |
61 | 60 |
62 static const int kTimedSampling = 0; | |
63 | |
64 static const int kAutoTuneLoops = 0; | 61 static const int kAutoTuneLoops = 0; |
65 | 62 |
66 static const int kDefaultLoops = | 63 static const int kDefaultLoops = |
67 #ifdef SK_DEBUG | 64 #ifdef SK_DEBUG |
68 1; | 65 1; |
69 #else | 66 #else |
70 kAutoTuneLoops; | 67 kAutoTuneLoops; |
71 #endif | 68 #endif |
72 | 69 |
73 static SkString loops_help_txt() { | 70 static SkString loops_help_txt() { |
74 SkString help; | 71 SkString help; |
75 help.printf("Number of times to run each bench. Set this to %d to auto-" | 72 help.printf("Number of times to run each bench. Set this to %d to auto-" |
76 "tune for each bench. Timings are only reported when auto-tuning
.", | 73 "tune for each bench. Timings are only reported when auto-tuning
.", |
77 kAutoTuneLoops); | 74 kAutoTuneLoops); |
78 return help; | 75 return help; |
79 } | 76 } |
80 | 77 |
81 static SkString to_string(int n) { | 78 static SkString to_string(int n) { |
82 SkString str; | 79 SkString str; |
83 str.appendS32(n); | 80 str.appendS32(n); |
84 return str; | 81 return str; |
85 } | 82 } |
86 | 83 |
87 DEFINE_int32(loops, kDefaultLoops, loops_help_txt().c_str()); | 84 DEFINE_int32(loops, kDefaultLoops, loops_help_txt().c_str()); |
88 | 85 |
89 DEFINE_int32(samples, 10, "Number of samples to measure for each bench."); | 86 DEFINE_int32(samples, 10, "Number of samples to measure for each bench."); |
90 DEFINE_string(samplingTime, "0", "Amount of time to run each bench. Takes preced
ence over samples." | 87 DEFINE_int32(ms, 0, "If >0, run each bench for this many ms instead of obeying -
-samples."); |
91 "Must be \"0\", \"%%lfs\", or \"%%lfms\""); | |
92 DEFINE_int32(overheadLoops, 100000, "Loops to estimate timer overhead."); | 88 DEFINE_int32(overheadLoops, 100000, "Loops to estimate timer overhead."); |
93 DEFINE_double(overheadGoal, 0.0001, | 89 DEFINE_double(overheadGoal, 0.0001, |
94 "Loop until timer overhead is at most this fraction of our measurm
ents."); | 90 "Loop until timer overhead is at most this fraction of our measurm
ents."); |
95 DEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU."); | 91 DEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU."); |
96 DEFINE_int32(gpuFrameLag, 5, "If unknown, estimated maximum number of frames GPU
allows to lag."); | 92 DEFINE_int32(gpuFrameLag, 5, "If unknown, estimated maximum number of frames GPU
allows to lag."); |
97 DEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling
back to " | 93 DEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling
back to " |
98 "software path rendering."); | 94 "software path rendering."); |
99 | 95 |
100 DEFINE_string(outResultsFile, "", "If given, write results here as JSON."); | 96 DEFINE_string(outResultsFile, "", "If given, write results here as JSON."); |
101 DEFINE_int32(maxCalibrationAttempts, 3, | 97 DEFINE_int32(maxCalibrationAttempts, 3, |
102 "Try up to this many times to guess loops for a bench, or skip the
bench."); | 98 "Try up to this many times to guess loops for a bench, or skip the
bench."); |
103 DEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this."); | 99 DEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this."); |
104 DEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs."); | 100 DEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs."); |
105 DEFINE_string(scales, "1.0", "Space-separated scales for SKPs."); | 101 DEFINE_string(scales, "1.0", "Space-separated scales for SKPs."); |
106 DEFINE_string(zoom, "1.0,0", "Comma-separated zoomMax,zoomPeriodMs factors for a
periodic SKP zoom " | 102 DEFINE_string(zoom, "1.0,0", "Comma-separated zoomMax,zoomPeriodMs factors for a
periodic SKP zoom " |
107 "function that ping-pongs between 1.0 and zoomMax."
); | 103 "function that ping-pongs between 1.0 and zoomMax."
); |
108 DEFINE_bool(bbh, true, "Build a BBH for SKPs?"); | 104 DEFINE_bool(bbh, true, "Build a BBH for SKPs?"); |
109 DEFINE_bool(mpd, true, "Use MultiPictureDraw for the SKPs?"); | 105 DEFINE_bool(mpd, true, "Use MultiPictureDraw for the SKPs?"); |
110 DEFINE_bool(loopSKP, true, "Loop SKPs like we do for micro benches?"); | 106 DEFINE_bool(loopSKP, true, "Loop SKPs like we do for micro benches?"); |
111 DEFINE_int32(flushEvery, 10, "Flush --outResultsFile every Nth run."); | 107 DEFINE_int32(flushEvery, 10, "Flush --outResultsFile every Nth run."); |
112 DEFINE_bool(resetGpuContext, true, "Reset the GrContext before running each test
."); | 108 DEFINE_bool(resetGpuContext, true, "Reset the GrContext before running each test
."); |
113 DEFINE_bool(gpuStats, false, "Print GPU stats after each gpu benchmark?"); | 109 DEFINE_bool(gpuStats, false, "Print GPU stats after each gpu benchmark?"); |
114 DEFINE_bool(pngBuildTileIndex, false, "If supported, use png buildTileIndex/deco
deSubset."); | 110 DEFINE_bool(pngBuildTileIndex, false, "If supported, use png buildTileIndex/deco
deSubset."); |
115 DEFINE_bool(jpgBuildTileIndex, false, "If supported, use jpg buildTileIndex/deco
deSubset."); | 111 DEFINE_bool(jpgBuildTileIndex, false, "If supported, use jpg buildTileIndex/deco
deSubset."); |
116 | 112 |
| 113 static double now_ms() { return SkTime::GetNSecs() * 1e-6; } |
| 114 |
117 static SkString humanize(double ms) { | 115 static SkString humanize(double ms) { |
118 if (FLAGS_verbose) return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); | 116 if (FLAGS_verbose) return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); |
119 return HumanizeMs(ms); | 117 return HumanizeMs(ms); |
120 } | 118 } |
121 #define HUMANIZE(ms) humanize(ms).c_str() | 119 #define HUMANIZE(ms) humanize(ms).c_str() |
122 | 120 |
123 bool Target::init(SkImageInfo info, Benchmark* bench) { | 121 bool Target::init(SkImageInfo info, Benchmark* bench) { |
124 if (Benchmark::kRaster_Backend == config.backend) { | 122 if (Benchmark::kRaster_Backend == config.backend) { |
125 this->surface.reset(SkSurface::NewRaster(info)); | 123 this->surface.reset(SkSurface::NewRaster(info)); |
126 if (!this->surface.get()) { | 124 if (!this->surface.get()) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 }; | 201 }; |
204 | 202 |
205 #endif | 203 #endif |
206 | 204 |
207 static double time(int loops, Benchmark* bench, Target* target) { | 205 static double time(int loops, Benchmark* bench, Target* target) { |
208 SkCanvas* canvas = target->getCanvas(); | 206 SkCanvas* canvas = target->getCanvas(); |
209 if (canvas) { | 207 if (canvas) { |
210 canvas->clear(SK_ColorWHITE); | 208 canvas->clear(SK_ColorWHITE); |
211 } | 209 } |
212 bench->preDraw(canvas); | 210 bench->preDraw(canvas); |
213 WallTimer timer; | 211 double start = now_ms(); |
214 timer.start(); | |
215 canvas = target->beginTiming(canvas); | 212 canvas = target->beginTiming(canvas); |
216 bench->draw(loops, canvas); | 213 bench->draw(loops, canvas); |
217 if (canvas) { | 214 if (canvas) { |
218 canvas->flush(); | 215 canvas->flush(); |
219 } | 216 } |
220 target->endTiming(); | 217 target->endTiming(); |
221 timer.end(); | 218 double elapsed = now_ms() - start; |
222 bench->postDraw(canvas); | 219 bench->postDraw(canvas); |
223 return timer.fWall; | 220 return elapsed; |
224 } | 221 } |
225 | 222 |
226 static double estimate_timer_overhead() { | 223 static double estimate_timer_overhead() { |
227 double overhead = 0; | 224 double overhead = 0; |
228 for (int i = 0; i < FLAGS_overheadLoops; i++) { | 225 for (int i = 0; i < FLAGS_overheadLoops; i++) { |
229 WallTimer timer; | 226 double start = now_ms(); |
230 timer.start(); | 227 overhead += now_ms() - start; |
231 timer.end(); | |
232 overhead += timer.fWall; | |
233 } | 228 } |
234 return overhead / FLAGS_overheadLoops; | 229 return overhead / FLAGS_overheadLoops; |
235 } | 230 } |
236 | 231 |
237 static int detect_forever_loops(int loops) { | 232 static int detect_forever_loops(int loops) { |
238 // look for a magic run-forever value | 233 // look for a magic run-forever value |
239 if (loops < 0) { | 234 if (loops < 0) { |
240 loops = SK_MaxS32; | 235 loops = SK_MaxS32; |
241 } | 236 } |
242 return loops; | 237 return loops; |
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1153 #if SK_SUPPORT_GPU | 1148 #if SK_SUPPORT_GPU |
1154 GrContextOptions grContextOpts; | 1149 GrContextOptions grContextOpts; |
1155 grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks; | 1150 grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks; |
1156 gGrFactory.reset(new GrContextFactory(grContextOpts)); | 1151 gGrFactory.reset(new GrContextFactory(grContextOpts)); |
1157 #endif | 1152 #endif |
1158 | 1153 |
1159 if (FLAGS_veryVerbose) { | 1154 if (FLAGS_veryVerbose) { |
1160 FLAGS_verbose = true; | 1155 FLAGS_verbose = true; |
1161 } | 1156 } |
1162 | 1157 |
1163 double samplingTimeMs = 0; | |
1164 if (0 != strcmp("0", FLAGS_samplingTime[0])) { | |
1165 SkSTArray<8, char> timeUnit; | |
1166 timeUnit.push_back_n(static_cast<int>(strlen(FLAGS_samplingTime[0])) + 1
); | |
1167 if (2 != sscanf(FLAGS_samplingTime[0], "%lf%s", &samplingTimeMs, timeUni
t.begin()) || | |
1168 (0 != strcmp("s", timeUnit.begin()) && 0 != strcmp("ms", timeUnit.be
gin()))) { | |
1169 SkDebugf("Invalid --samplingTime \"%s\". Must be \"0\", \"%%lfs\", o
r \"%%lfms\"\n", | |
1170 FLAGS_samplingTime[0]); | |
1171 exit(0); | |
1172 } | |
1173 if (0 == strcmp("s", timeUnit.begin())) { | |
1174 samplingTimeMs *= 1000; | |
1175 } | |
1176 if (samplingTimeMs) { | |
1177 FLAGS_samples = kTimedSampling; | |
1178 } | |
1179 } | |
1180 | |
1181 if (kAutoTuneLoops != FLAGS_loops) { | 1158 if (kAutoTuneLoops != FLAGS_loops) { |
1182 FLAGS_samples = 1; | 1159 FLAGS_samples = 1; |
1183 FLAGS_gpuFrameLag = 0; | 1160 FLAGS_gpuFrameLag = 0; |
1184 } | 1161 } |
1185 | 1162 |
1186 if (!FLAGS_writePath.isEmpty()) { | 1163 if (!FLAGS_writePath.isEmpty()) { |
1187 SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); | 1164 SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); |
1188 if (!sk_mkdir(FLAGS_writePath[0])) { | 1165 if (!sk_mkdir(FLAGS_writePath[0])) { |
1189 SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_wri
tePath[0]); | 1166 SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_wri
tePath[0]); |
1190 FLAGS_writePath.set(0, nullptr); | 1167 FLAGS_writePath.set(0, nullptr); |
(...skipping 23 matching lines...) Expand all Loading... |
1214 | 1191 |
1215 const double overhead = estimate_timer_overhead(); | 1192 const double overhead = estimate_timer_overhead(); |
1216 SkDebugf("Timer overhead: %s\n", HUMANIZE(overhead)); | 1193 SkDebugf("Timer overhead: %s\n", HUMANIZE(overhead)); |
1217 | 1194 |
1218 SkTArray<double> samples; | 1195 SkTArray<double> samples; |
1219 | 1196 |
1220 if (kAutoTuneLoops != FLAGS_loops) { | 1197 if (kAutoTuneLoops != FLAGS_loops) { |
1221 SkDebugf("Fixed number of loops; times would only be misleading so we wo
n't print them.\n"); | 1198 SkDebugf("Fixed number of loops; times would only be misleading so we wo
n't print them.\n"); |
1222 } else if (FLAGS_quiet) { | 1199 } else if (FLAGS_quiet) { |
1223 SkDebugf("median\tbench\tconfig\n"); | 1200 SkDebugf("median\tbench\tconfig\n"); |
1224 } else if (kTimedSampling == FLAGS_samples) { | 1201 } else if (FLAGS_ms) { |
1225 SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tc
onfig\tbench\n"); | 1202 SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tc
onfig\tbench\n"); |
1226 } else { | 1203 } else { |
1227 SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconf
ig\tbench\n", | 1204 SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconf
ig\tbench\n", |
1228 FLAGS_samples, "samples"); | 1205 FLAGS_samples, "samples"); |
1229 } | 1206 } |
1230 | 1207 |
1231 SkTDArray<Config> configs; | 1208 SkTDArray<Config> configs; |
1232 create_configs(&configs); | 1209 create_configs(&configs); |
1233 | 1210 |
1234 int runs = 0; | 1211 int runs = 0; |
(...skipping 19 matching lines...) Expand all Loading... |
1254 const char* config = target->config.name; | 1231 const char* config = target->config.name; |
1255 | 1232 |
1256 target->setup(); | 1233 target->setup(); |
1257 bench->perCanvasPreDraw(canvas); | 1234 bench->perCanvasPreDraw(canvas); |
1258 | 1235 |
1259 int maxFrameLag; | 1236 int maxFrameLag; |
1260 int loops = target->needsFrameTiming(&maxFrameLag) | 1237 int loops = target->needsFrameTiming(&maxFrameLag) |
1261 ? setup_gpu_bench(target, bench.get(), maxFrameLag) | 1238 ? setup_gpu_bench(target, bench.get(), maxFrameLag) |
1262 : setup_cpu_bench(overhead, target, bench.get()); | 1239 : setup_cpu_bench(overhead, target, bench.get()); |
1263 | 1240 |
1264 if (kTimedSampling != FLAGS_samples) { | 1241 if (FLAGS_ms) { |
| 1242 samples.reset(); |
| 1243 auto stop = now_ms() + FLAGS_ms; |
| 1244 do { |
| 1245 samples.push_back(time(loops, bench, target) / loops); |
| 1246 } while (now_ms() < stop); |
| 1247 } else { |
1265 samples.reset(FLAGS_samples); | 1248 samples.reset(FLAGS_samples); |
1266 for (int s = 0; s < FLAGS_samples; s++) { | 1249 for (int s = 0; s < FLAGS_samples; s++) { |
1267 samples[s] = time(loops, bench, target) / loops; | 1250 samples[s] = time(loops, bench, target) / loops; |
1268 } | 1251 } |
1269 } else if (samplingTimeMs) { | |
1270 samples.reset(); | |
1271 if (FLAGS_verbose) { | |
1272 SkDebugf("Begin sampling %s for %ims\n", | |
1273 bench->getUniqueName(), static_cast<int>(samplingTi
meMs)); | |
1274 } | |
1275 WallTimer timer; | |
1276 timer.start(); | |
1277 do { | |
1278 samples.push_back(time(loops, bench, target) / loops); | |
1279 timer.end(); | |
1280 } while (timer.fWall < samplingTimeMs); | |
1281 } | 1252 } |
1282 | 1253 |
1283 bench->perCanvasPostDraw(canvas); | 1254 bench->perCanvasPostDraw(canvas); |
1284 | 1255 |
1285 if (Benchmark::kNonRendering_Backend != target->config.backend && | 1256 if (Benchmark::kNonRendering_Backend != target->config.backend && |
1286 !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { | 1257 !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { |
1287 SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config
); | 1258 SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config
); |
1288 pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniq
ueName()); | 1259 pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniq
ueName()); |
1289 pngFilename.append(".png"); | 1260 pngFilename.append(".png"); |
1290 write_canvas_png(target, pngFilename); | 1261 write_canvas_png(target, pngFilename); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 const double stddev_percent = 100 * sqrt(stats.var) / stats.mean
; | 1295 const double stddev_percent = 100 * sqrt(stats.var) / stats.mean
; |
1325 SkDebugf("%4d/%-4dMB\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" | 1296 SkDebugf("%4d/%-4dMB\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" |
1326 , sk_tools::getCurrResidentSetSizeMB() | 1297 , sk_tools::getCurrResidentSetSizeMB() |
1327 , sk_tools::getMaxResidentSetSizeMB() | 1298 , sk_tools::getMaxResidentSetSizeMB() |
1328 , loops | 1299 , loops |
1329 , HUMANIZE(stats.min) | 1300 , HUMANIZE(stats.min) |
1330 , HUMANIZE(stats.median) | 1301 , HUMANIZE(stats.median) |
1331 , HUMANIZE(stats.mean) | 1302 , HUMANIZE(stats.mean) |
1332 , HUMANIZE(stats.max) | 1303 , HUMANIZE(stats.max) |
1333 , stddev_percent | 1304 , stddev_percent |
1334 , kTimedSampling != FLAGS_samples ? stats.plot.c_str() | 1305 , FLAGS_ms ? to_string(samples.count()).c_str() : stats.
plot.c_str() |
1335 : to_string(samples.co
unt()).c_str() | |
1336 , config | 1306 , config |
1337 , bench->getUniqueName() | 1307 , bench->getUniqueName() |
1338 ); | 1308 ); |
1339 } | 1309 } |
1340 #if SK_SUPPORT_GPU | 1310 #if SK_SUPPORT_GPU |
1341 if (FLAGS_gpuStats && | 1311 if (FLAGS_gpuStats && |
1342 Benchmark::kGPU_Backend == configs[i].backend) { | 1312 Benchmark::kGPU_Backend == configs[i].backend) { |
1343 gGrFactory->get(configs[i].ctxType)->printCacheStats(); | 1313 gGrFactory->get(configs[i].ctxType)->printCacheStats(); |
1344 gGrFactory->get(configs[i].ctxType)->printGpuStats(); | 1314 gGrFactory->get(configs[i].ctxType)->printGpuStats(); |
1345 } | 1315 } |
(...skipping 21 matching lines...) Expand all Loading... |
1367 | 1337 |
1368 return 0; | 1338 return 0; |
1369 } | 1339 } |
1370 | 1340 |
1371 #if !defined SK_BUILD_FOR_IOS | 1341 #if !defined SK_BUILD_FOR_IOS |
1372 int main(int argc, char** argv) { | 1342 int main(int argc, char** argv) { |
1373 SkCommandLineFlags::Parse(argc, argv); | 1343 SkCommandLineFlags::Parse(argc, argv); |
1374 return nanobench_main(); | 1344 return nanobench_main(); |
1375 } | 1345 } |
1376 #endif | 1346 #endif |
OLD | NEW |