commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2013 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 "BenchTimer.h" |
| 9 | #include "LazyDecodeBitmap.h" |
| 10 | #include "PictureBenchmark.h" |
| 11 | #include "PictureRenderer.h" |
| 12 | #include "SkBenchmark.h" |
| 13 | #include "SkForceLinking.h" |
| 14 | #include "SkGraphics.h" |
| 15 | #include "SkStream.h" |
| 16 | #include "SkString.h" |
commit-bot@chromium.org | 49a07ad | 2013-07-22 19:28:40 +0000 | [diff] [blame] | 17 | #include "SkTArray.h" |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 18 | #include "TimerData.h" |
| 19 | |
mtklein@google.com | c289743 | 2013-09-10 19:23:38 +0000 | [diff] [blame] | 20 | static const int kNumNormalRecordings = 10; |
| 21 | static const int kNumRTreeRecordings = 10; |
| 22 | static const int kNumPlaybacks = 1; |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 23 | static const size_t kNumBaseBenchmarks = 3; |
| 24 | static const size_t kNumTileSizes = 3; |
| 25 | static const size_t kNumBbhPlaybackBenchmarks = 3; |
| 26 | static const size_t kNumBenchmarks = kNumBaseBenchmarks + kNumBbhPlaybackBenchmarks; |
| 27 | |
| 28 | enum BenchmarkType { |
| 29 | kNormal_BenchmarkType = 0, |
| 30 | kRTree_BenchmarkType, |
| 31 | }; |
| 32 | |
| 33 | struct Histogram { |
| 34 | Histogram() { |
| 35 | // Make fCpuTime negative so that we don't mess with stats: |
| 36 | fCpuTime = SkIntToScalar(-1); |
| 37 | } |
| 38 | SkScalar fCpuTime; |
| 39 | SkString fPath; |
| 40 | }; |
| 41 | |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 42 | |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 43 | //////////////////////////////////////////////////////////////////////////////// |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 44 | // Defined below. |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 45 | struct BenchmarkControl; |
| 46 | |
| 47 | typedef void (*BenchmarkFunction) |
| 48 | (const BenchmarkControl&, const SkString&, SkPicture*, BenchTimer*); |
| 49 | |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 50 | static void benchmark_playback( |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 51 | const BenchmarkControl&, const SkString&, SkPicture*, BenchTimer*); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 52 | static void benchmark_recording( |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 53 | const BenchmarkControl&, const SkString&, SkPicture*, BenchTimer*); |
| 54 | //////////////////////////////////////////////////////////////////////////////// |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 55 | |
| 56 | /** |
| 57 | * Acts as a POD containing information needed to run a benchmark. |
| 58 | * Provides static methods to poll benchmark info from an index. |
| 59 | */ |
| 60 | struct BenchmarkControl { |
| 61 | SkISize fTileSize; |
| 62 | BenchmarkType fType; |
| 63 | BenchmarkFunction fFunction; |
| 64 | SkString fName; |
| 65 | |
| 66 | /** |
| 67 | * Will construct a BenchmarkControl instance from an index between 0 an kNumBenchmarks. |
| 68 | */ |
| 69 | static BenchmarkControl Make(size_t i) { |
| 70 | SkASSERT(kNumBenchmarks > i); |
| 71 | BenchmarkControl benchControl; |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 72 | benchControl.fTileSize = GetTileSize(i); |
| 73 | benchControl.fType = GetBenchmarkType(i); |
| 74 | benchControl.fFunction = GetBenchmarkFunc(i); |
| 75 | benchControl.fName = GetBenchmarkName(i); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 76 | return benchControl; |
| 77 | } |
| 78 | |
| 79 | enum BaseBenchmarks { |
| 80 | kNormalRecord = 0, |
| 81 | kRTreeRecord, |
| 82 | kNormalPlayback, |
| 83 | }; |
| 84 | |
| 85 | static SkISize fTileSizes[kNumTileSizes]; |
| 86 | |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 87 | static SkISize GetTileSize(size_t i) { |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 88 | // Two of the base benchmarks don't need a tile size. But to maintain simplicity |
| 89 | // down the pipeline we have to let a couple of values unused. |
| 90 | if (i < kNumBaseBenchmarks) { |
| 91 | return SkISize::Make(256, 256); |
| 92 | } |
| 93 | if (i >= kNumBaseBenchmarks && i < kNumBenchmarks) { |
| 94 | return fTileSizes[i - kNumBaseBenchmarks]; |
| 95 | } |
| 96 | SkASSERT(0); |
| 97 | return SkISize::Make(0, 0); |
| 98 | } |
| 99 | |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 100 | static BenchmarkType GetBenchmarkType(size_t i) { |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 101 | if (i < kNumBaseBenchmarks) { |
| 102 | switch (i) { |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 103 | case kNormalRecord: |
| 104 | return kNormal_BenchmarkType; |
| 105 | case kNormalPlayback: |
| 106 | return kNormal_BenchmarkType; |
| 107 | case kRTreeRecord: |
| 108 | return kRTree_BenchmarkType; |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 109 | } |
| 110 | } |
| 111 | if (i < kNumBenchmarks) { |
| 112 | return kRTree_BenchmarkType; |
| 113 | } |
| 114 | SkASSERT(0); |
| 115 | return kRTree_BenchmarkType; |
| 116 | } |
| 117 | |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 118 | static BenchmarkFunction GetBenchmarkFunc(size_t i) { |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 119 | // Base functions. |
| 120 | switch (i) { |
| 121 | case kNormalRecord: |
| 122 | return benchmark_recording; |
| 123 | case kNormalPlayback: |
| 124 | return benchmark_playback; |
| 125 | case kRTreeRecord: |
| 126 | return benchmark_recording; |
| 127 | } |
| 128 | // RTree playbacks |
| 129 | if (i < kNumBenchmarks) { |
| 130 | return benchmark_playback; |
| 131 | } |
| 132 | SkASSERT(0); |
| 133 | return NULL; |
| 134 | } |
| 135 | |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 136 | static SkString GetBenchmarkName(size_t i) { |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 137 | // Base benchmark names |
| 138 | switch (i) { |
| 139 | case kNormalRecord: |
| 140 | return SkString("normal_recording"); |
| 141 | case kNormalPlayback: |
| 142 | return SkString("normal_playback"); |
| 143 | case kRTreeRecord: |
| 144 | return SkString("rtree_recording"); |
| 145 | } |
| 146 | // RTree benchmark names. |
| 147 | if (i < kNumBenchmarks) { |
| 148 | SkASSERT(i >= kNumBaseBenchmarks); |
| 149 | SkString name; |
| 150 | name.printf("rtree_playback_%dx%d", |
| 151 | fTileSizes[i - kNumBaseBenchmarks].fWidth, |
| 152 | fTileSizes[i - kNumBaseBenchmarks].fHeight); |
| 153 | return name; |
| 154 | |
| 155 | } else { |
| 156 | SkASSERT(0); |
| 157 | } |
| 158 | return SkString(""); |
| 159 | } |
| 160 | |
| 161 | }; |
| 162 | |
| 163 | SkISize BenchmarkControl::fTileSizes[kNumTileSizes] = { |
| 164 | SkISize::Make(256, 256), |
| 165 | SkISize::Make(512, 512), |
| 166 | SkISize::Make(1024, 1024), |
| 167 | }; |
| 168 | |
| 169 | static SkPicture* pic_from_path(const char path[]) { |
| 170 | SkFILEStream stream(path); |
| 171 | if (!stream.isValid()) { |
| 172 | SkDebugf("-- Can't open '%s'\n", path); |
| 173 | return NULL; |
| 174 | } |
| 175 | return SkPicture::CreateFromStream(&stream, &sk_tools::LazyDecodeBitmap); |
| 176 | } |
| 177 | |
| 178 | /** |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 179 | * Returns true when a tiled renderer with no bounding box hierarchy produces the given bitmap. |
| 180 | */ |
| 181 | static bool compare_picture(const SkString& path, const SkBitmap& inBitmap, SkPicture* pic) { |
| 182 | SkBitmap* bitmap; |
| 183 | sk_tools::TiledPictureRenderer renderer; |
| 184 | renderer.setBBoxHierarchyType(sk_tools::PictureRenderer::kNone_BBoxHierarchyType); |
| 185 | renderer.init(pic); |
| 186 | renderer.setup(); |
| 187 | renderer.render(&path, &bitmap); |
| 188 | SkAutoTDelete<SkBitmap> bmDeleter(bitmap); |
| 189 | renderer.end(); |
| 190 | |
| 191 | if (bitmap->getSize() != inBitmap.getSize()) { |
| 192 | return false; |
| 193 | } |
| 194 | return !memcmp(bitmap->getPixels(), inBitmap.getPixels(), bitmap->getSize()); |
| 195 | } |
| 196 | |
| 197 | /** |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 198 | * This function is the sink to which all work ends up going. |
| 199 | * Renders the picture into the renderer. It may or may not use an RTree. |
| 200 | * The renderer is chosen upstream. If we want to measure recording, we will |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 201 | * use a RecordPictureRenderer. If we want to measure rendering, we will use a |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 202 | * TiledPictureRenderer. |
| 203 | */ |
| 204 | static void do_benchmark_work(sk_tools::PictureRenderer* renderer, |
| 205 | int benchmarkType, const SkString& path, SkPicture* pic, |
| 206 | const int numRepeats, const char *msg, BenchTimer* timer) { |
| 207 | SkString msgPrefix; |
| 208 | |
| 209 | switch (benchmarkType){ |
| 210 | case kNormal_BenchmarkType: |
| 211 | msgPrefix.set("Normal"); |
| 212 | renderer->setBBoxHierarchyType(sk_tools::PictureRenderer::kNone_BBoxHierarchyType); |
| 213 | break; |
| 214 | case kRTree_BenchmarkType: |
| 215 | msgPrefix.set("RTree"); |
| 216 | renderer->setBBoxHierarchyType(sk_tools::PictureRenderer::kRTree_BBoxHierarchyType); |
| 217 | break; |
| 218 | default: |
| 219 | SkASSERT(0); |
| 220 | break; |
| 221 | } |
| 222 | |
| 223 | renderer->init(pic); |
| 224 | |
| 225 | /** |
| 226 | * If the renderer is not tiled, assume we are measuring recording. |
| 227 | */ |
| 228 | bool isPlayback = (NULL != renderer->getTiledRenderer()); |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 229 | // Will be non-null during RTree picture playback. For correctness test. |
| 230 | SkBitmap* bitmap = NULL; |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 231 | |
| 232 | SkDebugf("%s %s %s %d times...\n", msgPrefix.c_str(), msg, path.c_str(), numRepeats); |
| 233 | for (int i = 0; i < numRepeats; ++i) { |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 234 | // Set up the bitmap. |
| 235 | SkBitmap** out = NULL; |
| 236 | if (i == 0 && kRTree_BenchmarkType == benchmarkType && isPlayback) { |
| 237 | out = &bitmap; |
| 238 | } |
| 239 | |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 240 | renderer->setup(); |
commit-bot@chromium.org | 6241754 | 2013-08-28 16:02:47 +0000 | [diff] [blame] | 241 | // Render once to fill caches. Fill bitmap during the first iteration. |
| 242 | renderer->render(NULL, out); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 243 | // Render again to measure |
| 244 | timer->start(); |
commit-bot@chromium.org | 6241754 | 2013-08-28 16:02:47 +0000 | [diff] [blame] | 245 | bool result = renderer->render(NULL); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 246 | timer->end(); |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 247 | |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 248 | // We only care about a false result on playback. RecordPictureRenderer::render will always |
| 249 | // return false because we are passing a NULL file name on purpose; which is fine. |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 250 | if (isPlayback && !result) { |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 251 | SkDebugf("Error rendering during playback.\n"); |
| 252 | } |
| 253 | } |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 254 | if (bitmap) { |
| 255 | SkAutoTDelete<SkBitmap> bmDeleter(bitmap); |
| 256 | if (!compare_picture(path, *bitmap, pic)) { |
| 257 | SkDebugf("Error: RTree produced different bitmap\n"); |
| 258 | } |
| 259 | } |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 260 | } |
| 261 | |
| 262 | /** |
| 263 | * Call do_benchmark_work with a tiled renderer using the default tile dimensions. |
| 264 | */ |
| 265 | static void benchmark_playback( |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 266 | const BenchmarkControl& benchControl, |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 267 | const SkString& path, SkPicture* pic, BenchTimer* timer) { |
| 268 | sk_tools::TiledPictureRenderer renderer; |
| 269 | |
| 270 | SkString message("tiled_playback"); |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 271 | message.appendf("_%dx%d", benchControl.fTileSize.fWidth, benchControl.fTileSize.fHeight); |
| 272 | do_benchmark_work(&renderer, benchControl.fType, |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 273 | path, pic, kNumPlaybacks, message.c_str(), timer); |
| 274 | } |
| 275 | |
| 276 | /** |
| 277 | * Call do_benchmark_work with a RecordPictureRenderer. |
| 278 | */ |
| 279 | static void benchmark_recording( |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 280 | const BenchmarkControl& benchControl, |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 281 | const SkString& path, SkPicture* pic, BenchTimer* timer) { |
| 282 | sk_tools::RecordPictureRenderer renderer; |
| 283 | int numRecordings = 0; |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 284 | switch(benchControl.fType) { |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 285 | case kRTree_BenchmarkType: |
| 286 | numRecordings = kNumRTreeRecordings; |
| 287 | break; |
| 288 | case kNormal_BenchmarkType: |
| 289 | numRecordings = kNumNormalRecordings; |
| 290 | break; |
| 291 | } |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 292 | do_benchmark_work(&renderer, benchControl.fType, |
| 293 | path, pic, numRecordings, "recording", timer); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 294 | } |
| 295 | |
| 296 | /** |
| 297 | * Takes argc,argv along with one of the benchmark functions defined above. |
| 298 | * Will loop along all skp files and perform measurments. |
| 299 | * |
| 300 | * Returns a SkScalar representing CPU time taken during benchmark. |
| 301 | * As a side effect, it spits the timer result to stdout. |
| 302 | * Will return -1.0 on error. |
| 303 | */ |
| 304 | static bool benchmark_loop( |
| 305 | int argc, |
| 306 | char **argv, |
| 307 | const BenchmarkControl& benchControl, |
commit-bot@chromium.org | 49a07ad | 2013-07-22 19:28:40 +0000 | [diff] [blame] | 308 | SkTArray<Histogram>& histogram) { |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 309 | static const SkString timeFormat("%f"); |
commit-bot@chromium.org | 55fd612 | 2013-07-31 20:00:56 +0000 | [diff] [blame] | 310 | TimerData timerData(argc - 1); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 311 | for (int index = 1; index < argc; ++index) { |
| 312 | BenchTimer timer; |
| 313 | SkString path(argv[index]); |
| 314 | SkAutoTUnref<SkPicture> pic(pic_from_path(path.c_str())); |
| 315 | if (NULL == pic) { |
| 316 | SkDebugf("Couldn't create picture. Ignoring path: %s\n", path.c_str()); |
| 317 | continue; |
| 318 | } |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 319 | benchControl.fFunction(benchControl, path, pic, &timer); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 320 | |
commit-bot@chromium.org | 49a07ad | 2013-07-22 19:28:40 +0000 | [diff] [blame] | 321 | histogram[index - 1].fPath = path; |
| 322 | histogram[index - 1].fCpuTime = SkDoubleToScalar(timer.fCpu); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 323 | } |
| 324 | |
| 325 | const SkString timerResult = timerData.getResult( |
commit-bot@chromium.org | 55fd612 | 2013-07-31 20:00:56 +0000 | [diff] [blame] | 326 | /*doubleFormat = */ timeFormat.c_str(), |
| 327 | /*result = */ TimerData::kAvg_Result, |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 328 | /*configName = */ benchControl.fName.c_str(), |
commit-bot@chromium.org | 55fd612 | 2013-07-31 20:00:56 +0000 | [diff] [blame] | 329 | /*timerFlags = */ TimerData::kCpu_Flag); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 330 | |
| 331 | const char findStr[] = "= "; |
| 332 | int pos = timerResult.find(findStr); |
| 333 | if (-1 == pos) { |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 334 | SkDebugf("Unexpected output from TimerData::getResult(...). Unable to parse.\n"); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 335 | return false; |
| 336 | } |
| 337 | |
| 338 | SkScalar cpuTime = SkDoubleToScalar(atof(timerResult.c_str() + pos + sizeof(findStr) - 1)); |
| 339 | if (cpuTime == 0) { // atof returns 0.0 on error. |
| 340 | SkDebugf("Unable to read value from timer result.\n"); |
| 341 | return false; |
| 342 | } |
| 343 | return true; |
| 344 | } |
| 345 | |
sglez@google.com | 1d38ae9 | 2013-07-19 20:03:57 +0000 | [diff] [blame] | 346 | int tool_main(int argc, char** argv); |
| 347 | int tool_main(int argc, char** argv) { |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 348 | SkAutoGraphics ag; |
| 349 | SkString usage; |
| 350 | usage.printf("Usage: filename [filename]*\n"); |
| 351 | |
| 352 | if (argc < 2) { |
| 353 | SkDebugf("%s\n", usage.c_str()); |
| 354 | return -1; |
| 355 | } |
| 356 | |
commit-bot@chromium.org | 49a07ad | 2013-07-22 19:28:40 +0000 | [diff] [blame] | 357 | SkTArray<Histogram> histograms[kNumBenchmarks]; |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 358 | |
| 359 | for (size_t i = 0; i < kNumBenchmarks; ++i) { |
commit-bot@chromium.org | 49a07ad | 2013-07-22 19:28:40 +0000 | [diff] [blame] | 360 | histograms[i].reset(argc - 1); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 361 | bool success = benchmark_loop( |
| 362 | argc, argv, |
| 363 | BenchmarkControl::Make(i), |
commit-bot@chromium.org | 49a07ad | 2013-07-22 19:28:40 +0000 | [diff] [blame] | 364 | histograms[i]); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 365 | if (!success) { |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 366 | SkDebugf("benchmark_loop failed at index %d\n", i); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 367 | } |
| 368 | } |
| 369 | |
| 370 | // Output gnuplot readable histogram data.. |
| 371 | const char* pbTitle = "bbh_shootout_playback.dat"; |
| 372 | const char* recTitle = "bbh_shootout_record.dat"; |
| 373 | SkFILEWStream playbackOut(pbTitle); |
| 374 | SkFILEWStream recordOut(recTitle); |
| 375 | recordOut.writeText("# "); |
| 376 | playbackOut.writeText("# "); |
| 377 | for (size_t i = 0; i < kNumBenchmarks; ++i) { |
| 378 | SkString out; |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 379 | out.printf("%s ", BenchmarkControl::GetBenchmarkName(i).c_str()); |
| 380 | if (BenchmarkControl::GetBenchmarkFunc(i) == &benchmark_recording) { |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 381 | recordOut.writeText(out.c_str()); |
| 382 | } |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 383 | if (BenchmarkControl::GetBenchmarkFunc(i) == &benchmark_playback) { |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 384 | playbackOut.writeText(out.c_str()); |
| 385 | } |
| 386 | } |
| 387 | recordOut.writeText("\n"); |
| 388 | playbackOut.writeText("\n"); |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 389 | // Write to file, and save recording averages. |
| 390 | SkScalar avgRecord = SkIntToScalar(0); |
commit-bot@chromium.org | 6241754 | 2013-08-28 16:02:47 +0000 | [diff] [blame] | 391 | SkScalar avgPlayback = SkIntToScalar(0); |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 392 | SkScalar avgRecordRTree = SkIntToScalar(0); |
commit-bot@chromium.org | 6241754 | 2013-08-28 16:02:47 +0000 | [diff] [blame] | 393 | SkScalar avgPlaybackRTree = SkIntToScalar(0); |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 394 | for (int i = 0; i < argc - 1; ++i) { |
| 395 | SkString pbLine; |
| 396 | SkString recLine; |
| 397 | // ==== Write record info |
| 398 | recLine.printf("%d ", i); |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 399 | SkScalar cpuTime = histograms[BenchmarkControl::kNormalRecord][i].fCpuTime; |
| 400 | recLine.appendf("%f ", cpuTime); |
| 401 | avgRecord += cpuTime; |
| 402 | cpuTime = histograms[BenchmarkControl::kRTreeRecord][i].fCpuTime; |
| 403 | recLine.appendf("%f", cpuTime); |
| 404 | avgRecordRTree += cpuTime; |
commit-bot@chromium.org | 6241754 | 2013-08-28 16:02:47 +0000 | [diff] [blame] | 405 | avgPlaybackRTree += cpuTime; |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 406 | |
| 407 | // ==== Write playback info |
| 408 | pbLine.printf("%d ", i); |
| 409 | pbLine.appendf("%f ", histograms[2][i].fCpuTime); // Start with normal playback time. |
commit-bot@chromium.org | 6241754 | 2013-08-28 16:02:47 +0000 | [diff] [blame] | 410 | avgPlayback += histograms[kNumBbhPlaybackBenchmarks - 1][i].fCpuTime; |
| 411 | avgPlaybackRTree += histograms[kNumBbhPlaybackBenchmarks][i].fCpuTime; |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 412 | // Append all playback benchmark times. |
| 413 | for (size_t j = kNumBbhPlaybackBenchmarks; j < kNumBenchmarks; ++j) { |
| 414 | pbLine.appendf("%f ", histograms[j][i].fCpuTime); |
| 415 | } |
| 416 | pbLine.remove(pbLine.size() - 1, 1); // Remove trailing space from line. |
| 417 | pbLine.appendf("\n"); |
| 418 | recLine.appendf("\n"); |
| 419 | playbackOut.writeText(pbLine.c_str()); |
| 420 | recordOut.writeText(recLine.c_str()); |
| 421 | } |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 422 | avgRecord /= argc - 1; |
| 423 | avgRecordRTree /= argc - 1; |
commit-bot@chromium.org | 6241754 | 2013-08-28 16:02:47 +0000 | [diff] [blame] | 424 | avgPlayback /= argc - 1; |
| 425 | avgPlaybackRTree /= argc - 1; |
commit-bot@chromium.org | 2e915b3 | 2013-08-20 12:23:18 +0000 | [diff] [blame] | 426 | SkDebugf("Average base recording time: %.3fms\n", avgRecord); |
| 427 | SkDebugf("Average recording time with rtree: %.3fms\n", avgRecordRTree); |
commit-bot@chromium.org | 6241754 | 2013-08-28 16:02:47 +0000 | [diff] [blame] | 428 | SkDebugf("Average base playback time: %.3fms\n", avgPlayback); |
| 429 | SkDebugf("Average playback time with rtree: %.3fms\n", avgPlaybackRTree); |
| 430 | |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 431 | SkDebugf("\nWrote data to gnuplot-readable files: %s %s\n", pbTitle, recTitle); |
| 432 | |
| 433 | return 0; |
| 434 | } |
| 435 | |
sglez@google.com | 5f3f681 | 2013-07-19 20:21:05 +0000 | [diff] [blame] | 436 | #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
commit-bot@chromium.org | 6645cde | 2013-07-19 18:54:04 +0000 | [diff] [blame] | 437 | int main(int argc, char** argv) { |
| 438 | return tool_main(argc, argv); |
| 439 | } |
sglez@google.com | 5f3f681 | 2013-07-19 20:21:05 +0000 | [diff] [blame] | 440 | #endif |