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

Side by Side Diff: tools/bbh_shootout.cpp

Issue 186973005: New version of the bbh shootout (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Review fixes Created 6 years, 9 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
« no previous file with comments | « tools/PictureRenderer.h ('k') | 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 "SkCommandLineFlags.h"
19 19
20 static const int kNumNormalRecordings = 10; 20 typedef sk_tools::PictureRenderer::BBoxHierarchyType BBoxType;
21 static const int kNumRTreeRecordings = 10; 21 static const int kBBoxTypeCount = sk_tools::PictureRenderer::kLast_BBoxHierarchy Type + 1;
22 static const int kNumPlaybacks = 1;
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 + kNumBbhPlaybackBenchma rks;
27 22
28 enum BenchmarkType { 23
29 kNormal_BenchmarkType = 0, 24 DEFINE_string2(skps, r, "", "The list of SKPs to benchmark.");
30 kRTree_BenchmarkType, 25 DEFINE_string(bbh, "", "The set of bbox types to test. If empty, all are tested. "
26 "Should be one or more of none, quadtree, rtree, tilegrid .");
27 DEFINE_int32(record, 100, "Number of times to record each SKP.");
28 DEFINE_int32(playback, 1, "Number of times to playback each SKP.");
tomhudson 2014/03/10 14:59:15 The record/playback ratio feels like the opposite
iancottrell 2014/03/10 16:22:49 We don't build a combined metric, so the ratio doe
29 DEFINE_int32(tilesize, 512, "The size of a tile.");
tomhudson 2014/03/10 14:59:15 Not quite a nit: in Chromium, cc/trees/layer_tree_
iancottrell 2014/03/10 16:22:49 Done.
30
31 struct Measurement {
32 SkString fName;
33 SkScalar fRecordAverage[kBBoxTypeCount];
34 SkScalar fPlaybackAverage[kBBoxTypeCount];
31 }; 35 };
32 36
33 struct Histogram { 37 const char* kBBoxHierarchyTypeNames[kBBoxTypeCount] = {
34 Histogram() { 38 "none", // kNone_BBoxHierarchyType
35 // Make fCpuTime negative so that we don't mess with stats: 39 "quadtree", // kQuadTree_BBoxHierarchyType
36 fCpuTime = SkIntToScalar(-1); 40 "rtree", // kRTree_BBoxHierarchyType
37 } 41 "tilegrid", // kTileGrid_BBoxHierarchyType
38 SkScalar fCpuTime;
39 SkString fPath;
40 };
41
42
43 ////////////////////////////////////////////////////////////////////////////////
44 // Defined below.
45 struct BenchmarkControl;
46
47 typedef void (*BenchmarkFunction)
48 (const BenchmarkControl&, const SkString&, SkPicture*, BenchTimer*);
49
50 static void benchmark_playback(
51 const BenchmarkControl&, const SkString&, SkPicture*, BenchTimer*);
52 static void benchmark_recording(
53 const BenchmarkControl&, const SkString&, SkPicture*, BenchTimer*);
54 ////////////////////////////////////////////////////////////////////////////////
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 kNu mBenchmarks.
68 */
69 static BenchmarkControl Make(size_t i) {
70 SkASSERT(kNumBenchmarks > i);
71 BenchmarkControl benchControl;
72 benchControl.fTileSize = GetTileSize(i);
73 benchControl.fType = GetBenchmarkType(i);
74 benchControl.fFunction = GetBenchmarkFunc(i);
75 benchControl.fName = GetBenchmarkName(i);
76 return benchControl;
77 }
78
79 enum BaseBenchmarks {
80 kNormalRecord = 0,
81 kRTreeRecord,
82 kNormalPlayback,
83 };
84
85 static SkISize fTileSizes[kNumTileSizes];
86
87 static SkISize GetTileSize(size_t i) {
88 // Two of the base benchmarks don't need a tile size. But to maintain si mplicity
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
100 static BenchmarkType GetBenchmarkType(size_t i) {
101 if (i < kNumBaseBenchmarks) {
102 switch (i) {
103 case kNormalRecord:
104 return kNormal_BenchmarkType;
105 case kNormalPlayback:
106 return kNormal_BenchmarkType;
107 case kRTreeRecord:
108 return kRTree_BenchmarkType;
109 }
110 }
111 if (i < kNumBenchmarks) {
112 return kRTree_BenchmarkType;
113 }
114 SkASSERT(0);
115 return kRTree_BenchmarkType;
116 }
117
118 static BenchmarkFunction GetBenchmarkFunc(size_t i) {
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
136 static SkString GetBenchmarkName(size_t i) {
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 }; 42 };
168 43
169 static SkPicture* pic_from_path(const char path[]) { 44 static SkPicture* pic_from_path(const char path[]) {
170 SkFILEStream stream(path); 45 SkFILEStream stream(path);
171 if (!stream.isValid()) { 46 if (!stream.isValid()) {
172 SkDebugf("-- Can't open '%s'\n", path); 47 SkDebugf("-- Can't open '%s'\n", path);
173 return NULL; 48 return NULL;
174 } 49 }
175 return SkPicture::CreateFromStream(&stream, &sk_tools::LazyDecodeBitmap); 50 return SkPicture::CreateFromStream(&stream, &sk_tools::LazyDecodeBitmap);
176 } 51 }
(...skipping 12 matching lines...) Expand all
189 renderer.end(); 64 renderer.end();
190 65
191 if (bitmap->getSize() != inBitmap.getSize()) { 66 if (bitmap->getSize() != inBitmap.getSize()) {
192 return false; 67 return false;
193 } 68 }
194 return !memcmp(bitmap->getPixels(), inBitmap.getPixels(), bitmap->getSize()) ; 69 return !memcmp(bitmap->getPixels(), inBitmap.getPixels(), bitmap->getSize()) ;
195 } 70 }
196 71
197 /** 72 /**
198 * This function is the sink to which all work ends up going. 73 * 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. 74 * Renders the picture into the renderer.
tomhudson 2014/03/10 14:59:15 Nit: I hate comments that use the same root twice
iancottrell 2014/03/10 16:22:49 Me too, but it was not my comment :) I have change
200 * The renderer is chosen upstream. If we want to measure recording, we will 75 * The renderer is chosen upstream. If we want to measure recording, we will
201 * use a RecordPictureRenderer. If we want to measure rendering, we will use a 76 * use a RecordPictureRenderer. If we want to measure rendering, we will use a
202 * TiledPictureRenderer. 77 * TiledPictureRenderer.
203 */ 78 */
204 static void do_benchmark_work(sk_tools::PictureRenderer* renderer, 79 static void do_benchmark_work(sk_tools::PictureRenderer* renderer,
205 int benchmarkType, const SkString& path, SkPicture* pic, 80 BBoxType bBoxType,
206 const int numRepeats, const char *msg, BenchTimer* timer) { 81 const SkString& path,
207 SkString msgPrefix; 82 SkPicture* pic,
208 83 const int numRepeats,
209 switch (benchmarkType){ 84 BenchTimer* timer,
210 case kNormal_BenchmarkType: 85 bool verify) {
tomhudson 2014/03/10 14:59:15 Nit: is there a more descriptive name? verifyWhat?
iancottrell 2014/03/10 16:22:49 Removed! The job of this tool is to benchmark, not
211 msgPrefix.set("Normal"); 86 const char* msgPrefix = kBBoxHierarchyTypeNames[bBoxType];
212 renderer->setBBoxHierarchyType(sk_tools::PictureRenderer::kNone_BBox HierarchyType); 87 renderer->setBBoxHierarchyType(bBoxType);
213 break; 88 renderer->setGridSize(FLAGS_tilesize, FLAGS_tilesize);
214 case kRTree_BenchmarkType:
215 msgPrefix.set("RTree");
216 renderer->setBBoxHierarchyType(sk_tools::PictureRenderer::kRTree_BBo xHierarchyType);
217 break;
218 default:
219 SkASSERT(0);
220 break;
221 }
222
223 renderer->init(pic); 89 renderer->init(pic);
224 90
225 /** 91 /**
226 * If the renderer is not tiled, assume we are measuring recording. 92 * If the renderer is not tiled, assume we are measuring recording.
227 */ 93 */
228 bool isPlayback = (NULL != renderer->getTiledRenderer()); 94 bool isPlayback = (NULL != renderer->getTiledRenderer());
95 const char* msg = isPlayback ? "playback" : "record";
229 // Will be non-null during RTree picture playback. For correctness test. 96 // Will be non-null during RTree picture playback. For correctness test.
230 SkBitmap* bitmap = NULL; 97 SkBitmap* bitmap = NULL;
231 98
232 SkDebugf("%s %s %s %d times...\n", msgPrefix.c_str(), msg, path.c_str(), num Repeats); 99 SkDebugf("%s %s %s %d times...\n", msgPrefix, msg, path.c_str(), numRepeats) ;
233 for (int i = 0; i < numRepeats; ++i) { 100 for (int i = 0; i < numRepeats; ++i) {
234 // Set up the bitmap. 101 // Set up the bitmap.
235 SkBitmap** out = NULL; 102 SkBitmap** out = NULL;
236 if (i == 0 && kRTree_BenchmarkType == benchmarkType && isPlayback) { 103 if (i == 0 && verify) {
237 out = &bitmap; 104 out = &bitmap;
238 } 105 }
239 106
240 renderer->setup(); 107 renderer->setup();
241 // Render once to fill caches. Fill bitmap during the first iteration. 108 // Render once to fill caches. Fill bitmap during the first iteration.
242 renderer->render(NULL, out); 109 renderer->render(NULL, out);
243 // Render again to measure 110 // Render again to measure
244 timer->start(); 111 timer->start();
245 bool result = renderer->render(NULL); 112 bool result = renderer->render(NULL);
246 timer->end(); 113 timer->end();
247 114
248 // We only care about a false result on playback. RecordPictureRenderer: :render will always 115 // 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; whic h is fine. 116 // return false because we are passing a NULL file name on purpose; whic h is fine.
250 if (isPlayback && !result) { 117 if (isPlayback && !result) {
251 SkDebugf("Error rendering during playback.\n"); 118 SkDebugf("Error rendering during playback.\n");
252 } 119 }
253 } 120 }
254 if (bitmap) { 121 if (bitmap) {
255 SkAutoTDelete<SkBitmap> bmDeleter(bitmap); 122 SkAutoTDelete<SkBitmap> bmDeleter(bitmap);
256 if (!compare_picture(path, *bitmap, pic)) { 123 if (!compare_picture(path, *bitmap, pic)) {
257 SkDebugf("Error: RTree produced different bitmap\n"); 124 SkDebugf("Error: %s produced different bitmap\n", msgPrefix);
258 } 125 }
259 } 126 }
260 } 127 }
261 128
262 /**
263 * Call do_benchmark_work with a tiled renderer using the default tile dimension s.
264 */
265 static void benchmark_playback(
266 const BenchmarkControl& benchControl,
267 const SkString& path, SkPicture* pic, BenchTimer* timer) {
268 sk_tools::TiledPictureRenderer renderer;
269
270 SkString message("tiled_playback");
271 message.appendf("_%dx%d", benchControl.fTileSize.fWidth, benchControl.fTileS ize.fHeight);
272 do_benchmark_work(&renderer, benchControl.fType,
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(
280 const BenchmarkControl& benchControl,
281 const SkString& path, SkPicture* pic, BenchTimer* timer) {
282 sk_tools::RecordPictureRenderer renderer;
283 int numRecordings = 0;
284 switch(benchControl.fType) {
285 case kRTree_BenchmarkType:
286 numRecordings = kNumRTreeRecordings;
287 break;
288 case kNormal_BenchmarkType:
289 numRecordings = kNumNormalRecordings;
290 break;
291 }
292 do_benchmark_work(&renderer, benchControl.fType,
293 path, pic, numRecordings, "recording", timer);
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 static void benchmark_loop(
301 int argc,
302 char **argv,
303 const BenchmarkControl& benchControl,
304 SkTArray<Histogram>& histogram) {
305 for (int index = 1; index < argc; ++index) {
306 BenchTimer timer;
307 SkString path(argv[index]);
308 SkAutoTUnref<SkPicture> pic(pic_from_path(path.c_str()));
309 if (NULL == pic) {
310 SkDebugf("Couldn't create picture. Ignoring path: %s\n", path.c_str( ));
311 continue;
312 }
313 benchControl.fFunction(benchControl, path, pic, &timer);
314 histogram[index - 1].fPath = path;
315 histogram[index - 1].fCpuTime = SkDoubleToScalar(timer.fCpu);
316 }
317 }
318
319 int tool_main(int argc, char** argv); 129 int tool_main(int argc, char** argv);
320 int tool_main(int argc, char** argv) { 130 int tool_main(int argc, char** argv) {
131 SkCommandLineFlags::Parse(argc, argv);
321 SkAutoGraphics ag; 132 SkAutoGraphics ag;
322 SkString usage; 133 bool includeBBoxType[kBBoxTypeCount];
323 usage.printf("Usage: filename [filename]*\n"); 134 for (int bBoxType = 0; bBoxType < kBBoxTypeCount; ++bBoxType) {
324 135 includeBBoxType[bBoxType] = (FLAGS_bbh.count() == 0) ||
325 if (argc < 2) { 136 FLAGS_bbh.contains(kBBoxHierarchyTypeNames[bBoxType]);
326 SkDebugf("%s\n", usage.c_str()); 137 }
327 return -1; 138 // go through all the pictures
139 SkTArray<Measurement> measurements;
140 for (int index = 0; index < FLAGS_skps.count(); ++index) {
141 const char* path = FLAGS_skps[index];
142 SkPicture* picture = pic_from_path(path);
143 if (NULL == picture) {
144 SkDebugf("Couldn't create picture. Ignoring path: %s\n", path);
145 continue;
146 }
147 Measurement& measurement = measurements.push_back();
148 measurement.fName = path;
149 for (int bBoxType = 0; bBoxType < kBBoxTypeCount; ++bBoxType) {
150 if (!includeBBoxType[bBoxType]) { continue; }
151 if (FLAGS_playback > 0) {
152 sk_tools::TiledPictureRenderer playbackRenderer;
153 BenchTimer playbackTimer;
154 do_benchmark_work(&playbackRenderer, (BBoxType)bBoxType, measure ment.fName,
155 picture, FLAGS_playback, &playbackTimer, 0 != bBoxType);
156 measurement.fPlaybackAverage[bBoxType] = playbackTimer.fCpu;
157 }
158 if (FLAGS_record > 0) {
159 sk_tools::RecordPictureRenderer recordRenderer;
160 BenchTimer recordTimer;
161 do_benchmark_work(&recordRenderer, (BBoxType)bBoxType, measureme nt.fName,
162 picture, FLAGS_record, &recordTimer, false);
163 measurement.fRecordAverage[bBoxType] = recordTimer.fCpu;
164 }
165 }
328 } 166 }
329 167
330 SkTArray<Histogram> histograms[kNumBenchmarks]; 168 Measurement globalMeasurement;
331 169 for (int bBoxType = 0; bBoxType < kBBoxTypeCount; ++bBoxType) {
332 for (size_t i = 0; i < kNumBenchmarks; ++i) { 170 if (!includeBBoxType[bBoxType]) { continue; }
333 histograms[i].reset(argc - 1); 171 globalMeasurement.fPlaybackAverage[bBoxType] = 0;
334 benchmark_loop(argc, argv, BenchmarkControl::Make(i), histograms[i]); 172 globalMeasurement.fRecordAverage[bBoxType] = 0;
173 for (int index = 0; index < measurements.count(); ++index) {
174 const Measurement& measurement = measurements[index];
175 globalMeasurement.fPlaybackAverage[bBoxType] +=
176 measurement.fPlaybackAverage[bBoxType];
177 globalMeasurement.fRecordAverage[bBoxType] +=
178 measurement.fRecordAverage[bBoxType];
179 }
180 globalMeasurement.fPlaybackAverage[bBoxType] /= measurements.count();
181 globalMeasurement.fRecordAverage[bBoxType] /= measurements.count();
335 } 182 }
336 183
337 // Output gnuplot readable histogram data.. 184 // Output gnuplot readable histogram data..
338 const char* pbTitle = "bbh_shootout_playback.dat"; 185 const char* pbTitle = "bbh_shootout_playback.dat";
339 const char* recTitle = "bbh_shootout_record.dat"; 186 const char* recTitle = "bbh_shootout_record.dat";
340 SkFILEWStream playbackOut(pbTitle); 187 SkFILEWStream playbackOut(pbTitle);
341 SkFILEWStream recordOut(recTitle); 188 SkFILEWStream recordOut(recTitle);
342 recordOut.writeText("# "); 189 recordOut.writeText("# ");
343 playbackOut.writeText("# "); 190 playbackOut.writeText("# ");
344 for (size_t i = 0; i < kNumBenchmarks; ++i) { 191 for (int bBoxType = 0; bBoxType < kBBoxTypeCount; ++bBoxType) {
192 if (!includeBBoxType[bBoxType]) { continue; }
345 SkString out; 193 SkString out;
346 out.printf("%s ", BenchmarkControl::GetBenchmarkName(i).c_str()); 194 out.printf("%s ", kBBoxHierarchyTypeNames[bBoxType]);
347 if (BenchmarkControl::GetBenchmarkFunc(i) == &benchmark_recording) { 195 recordOut.writeText(out.c_str());
348 recordOut.writeText(out.c_str()); 196 playbackOut.writeText(out.c_str());
197
198 if (FLAGS_record > 0) {
199 SkDebugf("Average %s recording time: %.3fms\n",
200 kBBoxHierarchyTypeNames[bBoxType],
201 globalMeasurement.fRecordAverage[bBoxType]);
349 } 202 }
350 if (BenchmarkControl::GetBenchmarkFunc(i) == &benchmark_playback) { 203 if (FLAGS_playback > 0) {
351 playbackOut.writeText(out.c_str()); 204 SkDebugf("Average %s playback time: %.3fms\n",
205 kBBoxHierarchyTypeNames[bBoxType],
206 globalMeasurement.fPlaybackAverage[bBoxType]);
352 } 207 }
353 } 208 }
354 recordOut.writeText("\n"); 209 recordOut.writeText("\n");
355 playbackOut.writeText("\n"); 210 playbackOut.writeText("\n");
356 // Write to file, and save recording averages. 211 // Write to file, and save recording averages.
357 SkScalar avgRecord = SkIntToScalar(0); 212 for (int index = 0; index < measurements.count(); ++index) {
358 SkScalar avgPlayback = SkIntToScalar(0); 213 const Measurement& measurement = measurements[index];
359 SkScalar avgRecordRTree = SkIntToScalar(0);
360 SkScalar avgPlaybackRTree = SkIntToScalar(0);
361 for (int i = 0; i < argc - 1; ++i) {
362 SkString pbLine; 214 SkString pbLine;
363 SkString recLine; 215 SkString recLine;
364 // ==== Write record info
365 recLine.printf("%d ", i);
366 SkScalar cpuTime = histograms[BenchmarkControl::kNormalRecord][i].fCpuTi me;
367 recLine.appendf("%f ", cpuTime);
368 avgRecord += cpuTime;
369 cpuTime = histograms[BenchmarkControl::kRTreeRecord][i].fCpuTime;
370 recLine.appendf("%f", cpuTime);
371 avgRecordRTree += cpuTime;
372 avgPlaybackRTree += cpuTime;
373 216
374 // ==== Write playback info 217 pbLine.printf("%d", index);
375 pbLine.printf("%d ", i); 218 recLine.printf("%d", index);
376 pbLine.appendf("%f ", histograms[2][i].fCpuTime); // Start with normal playback time. 219 for (int bBoxType = 0; bBoxType < kBBoxTypeCount; ++bBoxType) {
377 avgPlayback += histograms[kNumBbhPlaybackBenchmarks - 1][i].fCpuTime; 220 if (!includeBBoxType[bBoxType]) { continue; }
378 avgPlaybackRTree += histograms[kNumBbhPlaybackBenchmarks][i].fCpuTime; 221 pbLine.appendf(" %f", measurement.fPlaybackAverage[bBoxType]);
379 // Append all playback benchmark times. 222 recLine.appendf(" %f", measurement.fRecordAverage[bBoxType]);
380 for (size_t j = kNumBbhPlaybackBenchmarks; j < kNumBenchmarks; ++j) {
381 pbLine.appendf("%f ", histograms[j][i].fCpuTime);
382 } 223 }
383 pbLine.remove(pbLine.size() - 1, 1); // Remove trailing space from line .
384 pbLine.appendf("\n"); 224 pbLine.appendf("\n");
385 recLine.appendf("\n"); 225 recLine.appendf("\n");
386 playbackOut.writeText(pbLine.c_str()); 226 playbackOut.writeText(pbLine.c_str());
387 recordOut.writeText(recLine.c_str()); 227 recordOut.writeText(recLine.c_str());
388 } 228 }
389 avgRecord /= argc - 1;
390 avgRecordRTree /= argc - 1;
391 avgPlayback /= argc - 1;
392 avgPlaybackRTree /= argc - 1;
393 SkDebugf("Average base recording time: %.3fms\n", avgRecord);
394 SkDebugf("Average recording time with rtree: %.3fms\n", avgRecordRTree);
395 SkDebugf("Average base playback time: %.3fms\n", avgPlayback);
396 SkDebugf("Average playback time with rtree: %.3fms\n", avgPlaybackRTree);
397
398 SkDebugf("\nWrote data to gnuplot-readable files: %s %s\n", pbTitle, recTitl e); 229 SkDebugf("\nWrote data to gnuplot-readable files: %s %s\n", pbTitle, recTitl e);
399
400 return 0; 230 return 0;
401 } 231 }
402 232
403 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) 233 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
404 int main(int argc, char** argv) { 234 int main(int argc, char** argv) {
405 return tool_main(argc, argv); 235 return tool_main(argc, argv);
406 } 236 }
407 #endif 237 #endif
OLDNEW
« no previous file with comments | « tools/PictureRenderer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698