Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(388)

Side by Side Diff: tools/bbh_shootout.cpp

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

Powered by Google App Engine
This is Rietveld 408576698