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

Side by Side Diff: bench/benchmain.cpp

Issue 23478013: Major bench refactoring. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: merge with head agani Created 7 years, 3 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 | « bench/XfermodeBench.cpp ('k') | gyp/bench.gypi » ('j') | 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 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9
10 #include "BenchTimer.h"
11
12 #if SK_SUPPORT_GPU 9 #if SK_SUPPORT_GPU
13 #include "GrContext.h" 10 #include "GrContext.h"
14 #include "GrContextFactory.h" 11 #include "GrContextFactory.h"
15 #include "gl/GrGLDefines.h"
16 #include "GrRenderTarget.h" 12 #include "GrRenderTarget.h"
17 #include "SkGpuDevice.h" 13 #include "SkGpuDevice.h"
14 #include "gl/GrGLDefines.h"
18 #else 15 #else
19 class GrContext; 16 class GrContext;
20 #endif // SK_SUPPORT_GPU 17 #endif // SK_SUPPORT_GPU
21 18
19 #include "BenchTimer.h"
22 #include "SkBenchLogger.h" 20 #include "SkBenchLogger.h"
23 #include "SkBenchmark.h" 21 #include "SkBenchmark.h"
24 #include "SkBitmapDevice.h" 22 #include "SkBitmapDevice.h"
25 #include "SkCanvas.h" 23 #include "SkCanvas.h"
26 #include "SkCommandLineFlags.h" 24 #include "SkCommandLineFlags.h"
27 #include "SkDeferredCanvas.h" 25 #include "SkDeferredCanvas.h"
28 #include "SkColorPriv.h"
29 #include "SkGraphics.h" 26 #include "SkGraphics.h"
30 #include "SkImageEncoder.h" 27 #include "SkImageEncoder.h"
31 #include "SkNWayCanvas.h" 28 #include "SkOSFile.h"
32 #include "SkPicture.h" 29 #include "SkPicture.h"
33 #include "SkString.h" 30 #include "SkString.h"
34 #include "SkTArray.h"
35 #include "TimerData.h"
36 31
37 enum benchModes { 32 enum BenchMode {
38 kNormal_benchModes, 33 kNormal_BenchMode,
39 kDeferred_benchModes, 34 kDeferred_BenchMode,
40 kDeferredSilent_benchModes, 35 kDeferredSilent_BenchMode,
41 kRecord_benchModes, 36 kRecord_BenchMode,
42 kPictureRecord_benchModes 37 kPictureRecord_BenchMode
43 }; 38 };
44 39 const char* BenchMode_Name[] = { "normal", "deferred", "deferredSilent", "record ", "picturerecord" };
45 #ifdef SK_DEBUG
46 static const bool kDebugOnly = true;
47 #else
48 static const bool kDebugOnly = false;
49 #endif
50 40
51 /////////////////////////////////////////////////////////////////////////////// 41 ///////////////////////////////////////////////////////////////////////////////
52 42
53 static void erase(SkBitmap& bm) { 43 static void erase(SkBitmap& bm) {
54 if (bm.config() == SkBitmap::kA8_Config) { 44 if (bm.config() == SkBitmap::kA8_Config) {
55 bm.eraseColor(SK_ColorTRANSPARENT); 45 bm.eraseColor(SK_ColorTRANSPARENT);
56 } else { 46 } else {
57 bm.eraseColor(SK_ColorWHITE); 47 bm.eraseColor(SK_ColorWHITE);
58 } 48 }
59 } 49 }
60 50
61 #if 0
62 static bool equal(const SkBitmap& bm1, const SkBitmap& bm2) {
63 if (bm1.width() != bm2.width() ||
64 bm1.height() != bm2.height() ||
65 bm1.config() != bm2.config()) {
66 return false;
67 }
68
69 size_t pixelBytes = bm1.width() * bm1.bytesPerPixel();
70 for (int y = 0; y < bm1.height(); y++) {
71 if (memcmp(bm1.getAddr(0, y), bm2.getAddr(0, y), pixelBytes)) {
72 return false;
73 }
74 }
75 return true;
76 }
77 #endif
78
79 class Iter { 51 class Iter {
80 public: 52 public:
81 Iter(void* param) { 53 Iter() : fBench(BenchRegistry::Head()) {}
82 fBench = BenchRegistry::Head();
83 fParam = param;
84 }
85 54
86 SkBenchmark* next() { 55 SkBenchmark* next() {
87 if (fBench) { 56 if (fBench) {
88 BenchRegistry::Factory f = fBench->factory(); 57 BenchRegistry::Factory f = fBench->factory();
89 fBench = fBench->next(); 58 fBench = fBench->next();
90 return f(fParam); 59 return f(NULL);
91 } 60 }
92 return NULL; 61 return NULL;
93 } 62 }
94 63
95 private: 64 private:
96 const BenchRegistry* fBench; 65 const BenchRegistry* fBench;
97 void* fParam;
98 }; 66 };
99 67
100 class AutoPrePostDraw { 68 class AutoPrePostDraw {
101 public: 69 public:
102 AutoPrePostDraw(SkBenchmark* bench) : fBench(bench) { 70 AutoPrePostDraw(SkBenchmark* bench) : fBench(bench) {
103 fBench->preDraw(); 71 fBench->preDraw();
104 } 72 }
105 ~AutoPrePostDraw() { 73 ~AutoPrePostDraw() {
106 fBench->postDraw(); 74 fBench->postDraw();
107 } 75 }
(...skipping 29 matching lines...) Expand all
137 size_t size = copy.getSize() >> 2; 105 size_t size = copy.getSize() >> 2;
138 SkPMColor* p = copy.getAddr32(0, 0); 106 SkPMColor* p = copy.getAddr32(0, 0);
139 for (size_t i = 0; i < size; i++) { 107 for (size_t i = 0; i < size; i++) {
140 int c = (*p >> SK_A32_SHIFT) & 0xFF; 108 int c = (*p >> SK_A32_SHIFT) & 0xFF;
141 c = 255 - c; 109 c = 255 - c;
142 c |= (c << 24) | (c << 16) | (c << 8); 110 c |= (c << 24) | (c << 16) | (c << 8);
143 *p++ = c | (SK_A32_MASK << SK_A32_SHIFT); 111 *p++ = c | (SK_A32_MASK << SK_A32_SHIFT);
144 } 112 }
145 } 113 }
146 114
147 SkString str; 115 SkString filename;
148 make_filename(name, &str); 116 make_filename(name, &filename);
149 str.appendf("_%s.png", config); 117 filename.appendf("_%s.png", config);
150 str.prepend(dir); 118 SkString path = SkOSPath::SkPathJoin(dir, filename.c_str());
151 ::remove(str.c_str()); 119 ::remove(path.c_str());
152 SkImageEncoder::EncodeFile(str.c_str(), copy, SkImageEncoder::kPNG_Type, 120 SkImageEncoder::EncodeFile(path.c_str(), copy, SkImageEncoder::kPNG_Type, 10 0);
153 100);
154 } 121 }
155 122
156 static void performClip(SkCanvas* canvas, int w, int h) { 123 static void performClip(SkCanvas* canvas, int w, int h) {
157 SkRect r; 124 SkRect r;
158 125
159 r.set(SkIntToScalar(10), SkIntToScalar(10), 126 r.set(SkIntToScalar(10), SkIntToScalar(10),
160 SkIntToScalar(w*2/3), SkIntToScalar(h*2/3)); 127 SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
161 canvas->clipRect(r, SkRegion::kIntersect_Op); 128 canvas->clipRect(r, SkRegion::kIntersect_Op);
162 129
163 r.set(SkIntToScalar(w/3), SkIntToScalar(h/3), 130 r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
(...skipping 13 matching lines...) Expand all
177 static void performScale(SkCanvas* canvas, int w, int h) { 144 static void performScale(SkCanvas* canvas, int w, int h) {
178 const SkScalar x = SkIntToScalar(w) / 2; 145 const SkScalar x = SkIntToScalar(w) / 2;
179 const SkScalar y = SkIntToScalar(h) / 2; 146 const SkScalar y = SkIntToScalar(h) / 2;
180 147
181 canvas->translate(x, y); 148 canvas->translate(x, y);
182 // just enough so we can't take the sprite case 149 // just enough so we can't take the sprite case
183 canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100); 150 canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
184 canvas->translate(-x, -y); 151 canvas->translate(-x, -y);
185 } 152 }
186 153
187 static bool parse_bool_arg(char * const* argv, char* const* stop, bool* var) {
188 if (argv < stop) {
189 *var = atoi(*argv) != 0;
190 return true;
191 }
192 return false;
193 }
194
195 enum Backend { 154 enum Backend {
196 kNonRendering_Backend, 155 kNonRendering_Backend,
197 kRaster_Backend, 156 kRaster_Backend,
198 kGPU_Backend, 157 kGPU_Backend,
199 kPDF_Backend, 158 kPDF_Backend,
200 }; 159 };
201 160
202 static SkBaseDevice* make_device(SkBitmap::Config config, const SkIPoint& size, 161 static SkBaseDevice* make_device(SkBitmap::Config config, const SkIPoint& size,
203 Backend backend, int sampleCount, GrContext* co ntext) { 162 Backend backend, int sampleCount, GrContext* co ntext) {
204 SkBaseDevice* device = NULL; 163 SkBaseDevice* device = NULL;
(...skipping 25 matching lines...) Expand all
230 case kPDF_Backend: 189 case kPDF_Backend:
231 default: 190 default:
232 SkDEBUGFAIL("unsupported"); 191 SkDEBUGFAIL("unsupported");
233 } 192 }
234 return device; 193 return device;
235 } 194 }
236 195
237 #if SK_SUPPORT_GPU 196 #if SK_SUPPORT_GPU
238 GrContextFactory gContextFactory; 197 GrContextFactory gContextFactory;
239 typedef GrContextFactory::GLContextType GLContextType; 198 typedef GrContextFactory::GLContextType GLContextType;
240 static const GLContextType kDontCareGLCtxType = GrContextFactory::kNative_GLCont extType; 199 static const GLContextType kNative = GrContextFactory::kNative_GLContextType;
200 #if SK_ANGLE
201 static const GLContextType kANGLE = GrContextFactory::kANGLE_GLContextType;
202 #else
203 static const GLContextType kANGLE = kNative;
204 #endif
205 static const GLContextType kDebug = GrContextFactory::kDebug_GLContextType;
206 static const GLContextType kNull = GrContextFactory::kNull_GLContextType;
241 #else 207 #else
242 typedef int GLContextType; 208 typedef int GLContextType;
243 static const GLContextType kDontCareGLCtxType = 0; 209 static const GLContextType kNative = 0, kANGLE = 0, kDebug = 0, kNull = 0;
244 #endif 210 #endif
245 211
246 static const struct { 212 #ifdef SK_DEBUG
247 SkBitmap::Config fConfig; 213 static const bool kIsDebug = true;
248 const char* fName; 214 #else
249 int fSampleCnt; 215 static const bool kIsDebug = false;
250 Backend fBackend; 216 #endif
251 GLContextType fContextType; 217
252 bool fRunByDefault; 218 static const struct Config {
219 SkBitmap::Config config;
220 const char* name;
221 int sampleCount;
222 Backend backend;
223 GLContextType contextType;
224 bool runByDefault;
253 } gConfigs[] = { 225 } gConfigs[] = {
254 { SkBitmap::kNo_Config, "NONRENDERING", 0, kNonRendering_Backend, kD ontCareGLCtxType, true }, 226 { SkBitmap::kNo_Config, "NONRENDERING", 0, kNonRendering_Backend, kNa tive, true},
255 { SkBitmap::kARGB_8888_Config, "8888", 0, kRaster_Backend, kD ontCareGLCtxType, true }, 227 { SkBitmap::kARGB_8888_Config, "8888", 0, kRaster_Backend, kNa tive, true},
256 { SkBitmap::kRGB_565_Config, "565", 0, kRaster_Backend, kD ontCareGLCtxType, true }, 228 { SkBitmap::kRGB_565_Config, "565", 0, kRaster_Backend, kNa tive, true},
257 #if SK_SUPPORT_GPU 229 #if SK_SUPPORT_GPU
258 { SkBitmap::kARGB_8888_Config, "GPU", 0, kGPU_Backend, Gr ContextFactory::kNative_GLContextType, true }, 230 { SkBitmap::kARGB_8888_Config, "GPU", 0, kGPU_Backend, kNa tive, true},
259 { SkBitmap::kARGB_8888_Config, "MSAA4", 4, kGPU_Backend, Gr ContextFactory::kNative_GLContextType, false }, 231 { SkBitmap::kARGB_8888_Config, "MSAA4", 4, kGPU_Backend, kNa tive, false},
260 { SkBitmap::kARGB_8888_Config, "MSAA16", 16, kGPU_Backend, Gr ContextFactory::kNative_GLContextType, false }, 232 { SkBitmap::kARGB_8888_Config, "MSAA16", 16, kGPU_Backend, kNa tive, false},
261 #if SK_ANGLE 233 #if SK_ANGLE
262 { SkBitmap::kARGB_8888_Config, "ANGLE", 0, kGPU_Backend, Gr ContextFactory::kANGLE_GLContextType, true }, 234 { SkBitmap::kARGB_8888_Config, "ANGLE", 0, kGPU_Backend, kAN GLE, true},
263 #endif // SK_ANGLE 235 #endif // SK_ANGLE
264 { SkBitmap::kARGB_8888_Config, "Debug", 0, kGPU_Backend, Gr ContextFactory::kDebug_GLContextType, kDebugOnly }, 236 { SkBitmap::kARGB_8888_Config, "Debug", 0, kGPU_Backend, kDe bug, kIsDebug},
265 { SkBitmap::kARGB_8888_Config, "NULLGPU", 0, kGPU_Backend, Gr ContextFactory::kNull_GLContextType, true }, 237 { SkBitmap::kARGB_8888_Config, "NULLGPU", 0, kGPU_Backend, kNu ll, true},
266 #endif // SK_SUPPORT_GPU 238 #endif // SK_SUPPORT_GPU
267 }; 239 };
268 240
269 static int findConfig(const char config[]) { 241 DEFINE_string(outDir, "", "If given, image of each bench will be put in outDir." );
270 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) { 242 DEFINE_string(timers, "cg", "Timers to display. "
271 if (!strcmp(config, gConfigs[i].fName)) { 243 "Options: w(all) W(all, truncated) c(pu) C(pu, truncated) g(pu)");
272 return i;
273 }
274 }
275 return -1;
276 }
277 244
278 static void help() { 245 DEFINE_bool(rotate, false, "Rotate canvas before bench run?");
279 SkString configsStr; 246 DEFINE_bool(scale, false, "Scale canvas before bench run?");
280 static const size_t kConfigCount = SK_ARRAY_COUNT(gConfigs); 247 DEFINE_bool(clip, false, "Clip canvas before bench run?");
281 for (size_t i = 0; i < kConfigCount; ++i) {
282 configsStr.appendf("%s%s", gConfigs[i].fName, ((i == kConfigCount - 1) ? "" : "|"));
283 }
284 248
285 SkDebugf("Usage: bench [-o outDir] [--repeat nr] [--logPerIter] " 249 DEFINE_bool(forceAA, true, "Force anti-aliasing?");
286 "[--timers [wcgWC]*] [--rotate]\n" 250 DEFINE_bool(forceFilter, false, "Force bitmap filtering?");
287 " [--scale] [--clip] [--min] [--forceAA 1|0] [--forceFilter 1|0] \n" 251 DEFINE_string(forceDither, "default", "Force dithering: true, false, or default? ");
288 " [--forceDither 1|0] [--forceBlend 1|0]" 252 DEFINE_bool(forceBlend, false, "Force alpha blending?");
289 #if SK_SUPPORT_GPU 253
290 " [--gpuCacheSize <bytes> <count>]" 254 DEFINE_int32(gpuCacheBytes, -1, "GPU cache size limit in bytes. 0 to disable ca che.");
291 #endif 255 DEFINE_int32(gpuCacheCount, -1, "GPU cache size limit in object count. 0 to dis able cache.");
292 "\n" 256
293 " [--strokeWidth width] [--match name]\n" 257 DEFINE_string(match, "", "[~][^]substring[$] [...] of test name to run.\n"
294 " [--mode normal|deferred|deferredSilent|record|picturerecord]\n " 258 "Multiple matches may be separated by spaces.\n"
295 " [--config "); 259 "~ causes a matching test to always be skipped\n"
296 SkDebugf("%s]\n", configsStr.c_str()); 260 "^ requires the start of the test to match\n"
297 SkDebugf(" [-Dfoo bar] [--logFile filename] [-h|--help]"); 261 "$ requires the end of the test to match\n"
298 SkDebugf("\n\n"); 262 "^ and $ requires an exact match\n"
299 SkDebugf(" -o outDir : Image of each bench will be put in outDir.\n"); 263 "If a test does not match any list entry,\n"
300 SkDebugf(" --repeat nr : Each bench repeats for nr times.\n"); 264 "it is skipped unless some list entry starts with ~\n" );
301 SkDebugf(" --logPerIter : " 265 DEFINE_string(mode, "normal",
302 "Log each repeat timer instead of mean, default is disabled.\n"); 266 "normal: draw to a normal canvas;\n"
303 SkDebugf(" --timers [wcgWC]* : " 267 "deferred: draw to a deferred canvas;\n"
304 "Display wall, cpu, gpu, truncated wall or truncated cpu time for e ach bench.\n"); 268 "deferredSilent: deferred with silent playback;\n"
305 SkDebugf(" --rotate : Rotate before each bench runs.\n"); 269 "record: draw to an SkPicture;\n"
306 SkDebugf(" --scale : Scale before each bench runs.\n"); 270 "picturerecord: draw from an SkPicture to an SkPicture.\n");
307 SkDebugf(" --clip : Clip before each bench runs.\n"); 271 DEFINE_string(config, "", "Run configs given. If empty, runs the defaults set i n gConfigs.");
308 SkDebugf(" --min : Print the minimum times (instead of average).\n"); 272 DEFINE_string(logFile, "", "Also write stdout here.");
309 SkDebugf(" --forceAA 1|0 : " 273 DEFINE_int32(benchMs, 20, "Target time in ms to run each benchmark config.");
310 "Enable/disable anti-aliased, default is enabled.\n"); 274 DEFINE_string(timeFormat, "%9.2f", "Format to print results, in milliseconds per 1000 loops.");
311 SkDebugf(" --forceFilter 1|0 : "
312 "Enable/disable bitmap filtering, default is disabled.\n");
313 SkDebugf(" --forceDither 1|0 : "
314 "Enable/disable dithering, default is disabled.\n");
315 SkDebugf(" --forceBlend 1|0 : "
316 "Enable/disable dithering, default is disabled.\n");
317 #if SK_SUPPORT_GPU
318 SkDebugf(" --gpuCacheSize <bytes> <count>: "
319 "limits gpu cache to bytes size or object count.\n");
320 SkDebugf(" -1 for either value means use the default. 0 for either disa bles the cache.\n");
321 #endif
322 SkDebugf(" --strokeWidth width : The width for path stroke.\n");
323 SkDebugf(" --match [~][^]substring[$] [...] of test name to run.\n"
324 " Multiple matches may be separated by spaces.\n"
325 " ~ causes a matching test to always be skipped\n"
326 " ^ requires the start of the test to match\n"
327 " $ requires the end of the test to match\n"
328 " ^ and $ requires an exact match\n"
329 " If a test does not match any list entry,\n"
330 " it is skipped unless some list entry starts with ~\n" );
331 SkDebugf(" --mode normal|deferred|deferredSilent|record|picturerecord :\n "
332 " Run in the corresponding mode\n"
333 " normal, Use a normal canvas to draw to;\n"
334 " deferred, Use a deferrred canvas when drawing;\n"
335 " deferredSilent, deferred with silent playback;\n"
336 " record, Benchmark the time to record to an SkPict ure;\n"
337 " picturerecord, Benchmark the time to do record fr om a \n"
338 " SkPicture to a SkPicture.\n");
339 SkDebugf(" --logFile filename : destination for writing log output, in ad dition to stdout.\n");
340 SkDebugf(" --config %s:\n", configsStr.c_str());
341 SkDebugf(" Run bench in corresponding config mode.\n");
342 SkDebugf(" -Dfoo bar : Add extra definition to bench.\n");
343 SkDebugf(" -h|--help : Show this help message.\n");
344 }
345 275
346 int tool_main(int argc, char** argv); 276 int tool_main(int argc, char** argv);
347 int tool_main(int argc, char** argv) { 277 int tool_main(int argc, char** argv) {
348 #if SK_ENABLE_INST_COUNT 278 #if SK_ENABLE_INST_COUNT
349 gPrintInstCount = true; 279 gPrintInstCount = true;
350 #endif 280 #endif
351 SkAutoGraphics ag; 281 SkAutoGraphics ag;
282 SkCommandLineFlags::Parse(argc, argv);
352 283
353 SkTDict<const char*> defineDict(1024); 284 // First, parse some flags.
354 int repeatDraw = 1;
355
356 int forceAlpha = 0xFF;
357 bool forceAA = true;
358 bool forceFilter = false;
359 SkTriState::State forceDither = SkTriState::kDefault;
360
361 static const uint32_t kDefaultTimerTypes = TimerData::kCpu_Flag | TimerData: :kGpu_Flag;
362 static const TimerData::Result kDefaultTimerResult = TimerData::kAvg_Result;
363 uint32_t timerTypes = kDefaultTimerTypes;
364 TimerData::Result timerResult = kDefaultTimerResult;
365
366 bool doScale = false;
367 bool doRotate = false;
368 bool doClip = false;
369 bool hasStrokeWidth = false;
370
371 #if SK_SUPPORT_GPU
372 struct {
373 int fBytes;
374 int fCount;
375 } gpuCacheSize = { -1, -1 }; // -1s mean use the default
376 #endif
377
378 float strokeWidth;
379 SkTDArray<const char*> fMatches;
380 benchModes benchMode = kNormal_benchModes;
381 SkString perIterTimeformat("%.2f");
382 SkString normalTimeFormat("%6.2f");
383
384 SkString outDir;
385 SkBitmap::Config outConfig = SkBitmap::kNo_Config;
386 const char* configName = "";
387 Backend backend = kRaster_Backend; // for warning
388 int sampleCount = 0;
389 SkTDArray<int> configs;
390 bool userConfig = false;
391 285
392 SkBenchLogger logger; 286 SkBenchLogger logger;
287 if (FLAGS_logFile.count()) {
288 logger.SetLogFile(FLAGS_logFile[0]);
289 }
393 290
394 char* const* stop = argv + argc; 291 const uint8_t alpha = FLAGS_forceBlend ? 0x80 : 0xFF;
395 for (++argv; argv < stop; ++argv) { 292 SkTriState::State dither = SkTriState::kDefault;
396 if (strcmp(*argv, "-o") == 0) { 293 for (size_t i = 0; i < 3; i++) {
397 argv++; 294 if (strcmp(SkTriState::Name[i], FLAGS_forceDither[0]) == 0) {
398 if (argv < stop && **argv) { 295 dither = static_cast<SkTriState::State>(i);
399 outDir.set(*argv);
400 if (outDir.c_str()[outDir.size() - 1] != '/') {
401 outDir.append("/");
402 }
403 }
404 } else if (strcmp(*argv, "--repeat") == 0) {
405 argv++;
406 if (argv < stop) {
407 repeatDraw = atoi(*argv);
408 if (repeatDraw < 1) {
409 repeatDraw = 1;
410 }
411 } else {
412 logger.logError("missing arg for --repeat\n");
413 help();
414 return -1;
415 }
416 } else if (strcmp(*argv, "--logPerIter") == 0) {
417 timerResult = TimerData::kPerIter_Result;
418 } else if (strcmp(*argv, "--timers") == 0) {
419 argv++;
420 if (argv < stop) {
421 timerTypes = 0;
422 for (char* t = *argv; *t; ++t) {
423 switch (*t) {
424 case 'w': timerTypes |= TimerData::kWall_Flag; break;
425 case 'c': timerTypes |= TimerData::kCpu_Flag; break;
426 case 'W': timerTypes |= TimerData::kTruncatedWall_Flag; brea k;
427 case 'C': timerTypes |= TimerData::kTruncatedCpu_Flag; break ;
428 case 'g': timerTypes |= TimerData::kGpu_Flag; break;
429 }
430 }
431 } else {
432 logger.logError("missing arg for --timers\n");
433 help();
434 return -1;
435 }
436 } else if (!strcmp(*argv, "--rotate")) {
437 doRotate = true;
438 } else if (!strcmp(*argv, "--scale")) {
439 doScale = true;
440 } else if (!strcmp(*argv, "--clip")) {
441 doClip = true;
442 } else if (!strcmp(*argv, "--min")) {
443 timerResult = TimerData::kMin_Result;
444 } else if (strcmp(*argv, "--forceAA") == 0) {
445 if (!parse_bool_arg(++argv, stop, &forceAA)) {
446 logger.logError("missing arg for --forceAA\n");
447 help();
448 return -1;
449 }
450 } else if (strcmp(*argv, "--forceFilter") == 0) {
451 if (!parse_bool_arg(++argv, stop, &forceFilter)) {
452 logger.logError("missing arg for --forceFilter\n");
453 help();
454 return -1;
455 }
456 } else if (strcmp(*argv, "--forceDither") == 0) {
457 bool tmp;
458 if (!parse_bool_arg(++argv, stop, &tmp)) {
459 logger.logError("missing arg for --forceDither\n");
460 help();
461 return -1;
462 }
463 forceDither = tmp ? SkTriState::kTrue : SkTriState::kFalse;
464 } else if (strcmp(*argv, "--forceBlend") == 0) {
465 bool wantAlpha = false;
466 if (!parse_bool_arg(++argv, stop, &wantAlpha)) {
467 logger.logError("missing arg for --forceBlend\n");
468 help();
469 return -1;
470 }
471 forceAlpha = wantAlpha ? 0x80 : 0xFF;
472 #if SK_SUPPORT_GPU
473 } else if (strcmp(*argv, "--gpuCacheSize") == 0) {
474 if (stop - argv > 2) {
475 gpuCacheSize.fBytes = atoi(*++argv);
476 gpuCacheSize.fCount = atoi(*++argv);
477 } else {
478 SkDebugf("missing arg for --gpuCacheSize\n");
479 help();
480 return -1;
481 }
482 #endif
483 } else if (strcmp(*argv, "--mode") == 0) {
484 argv++;
485 if (argv < stop) {
486 if (strcmp(*argv, "normal") == 0) {
487 benchMode = kNormal_benchModes;
488 } else if (strcmp(*argv, "deferred") == 0) {
489 benchMode = kDeferred_benchModes;
490 } else if (strcmp(*argv, "deferredSilent") == 0) {
491 benchMode = kDeferredSilent_benchModes;
492 } else if (strcmp(*argv, "record") == 0) {
493 benchMode = kRecord_benchModes;
494 } else if (strcmp(*argv, "picturerecord") == 0) {
495 benchMode = kPictureRecord_benchModes;
496 } else {
497 logger.logError("bad arg for --mode\n");
498 help();
499 return -1;
500 }
501 } else {
502 logger.logError("missing arg for --mode\n");
503 help();
504 return -1;
505 }
506 } else if (strcmp(*argv, "--strokeWidth") == 0) {
507 argv++;
508 if (argv < stop) {
509 const char *strokeWidthStr = *argv;
510 if (sscanf(strokeWidthStr, "%f", &strokeWidth) != 1) {
511 logger.logError("bad arg for --strokeWidth\n");
512 help();
513 return -1;
514 }
515 hasStrokeWidth = true;
516 } else {
517 logger.logError("missing arg for --strokeWidth\n");
518 help();
519 return -1;
520 }
521 } else if (strcmp(*argv, "--match") == 0) {
522 argv++;
523 while (argv < stop && (*argv)[0] != '-') {
524 *fMatches.append() = *argv++;
525 }
526 argv--;
527 if (!fMatches.count()) {
528 logger.logError("missing arg for --match\n");
529 help();
530 return -1;
531 }
532 } else if (strcmp(*argv, "--config") == 0) {
533 argv++;
534 if (argv < stop) {
535 int index = findConfig(*argv);
536 if (index >= 0) {
537 *configs.append() = index;
538 userConfig = true;
539 } else {
540 SkString str;
541 str.printf("unrecognized config %s\n", *argv);
542 logger.logError(str);
543 help();
544 return -1;
545 }
546 } else {
547 logger.logError("missing arg for --config\n");
548 help();
549 return -1;
550 }
551 } else if (strcmp(*argv, "--logFile") == 0) {
552 argv++;
553 if (argv < stop) {
554 if (!logger.SetLogFile(*argv)) {
555 SkString str;
556 str.printf("Could not open %s for writing.", *argv);
557 logger.logError(str);
558 return -1;
559 }
560 } else {
561 logger.logError("missing arg for --logFile\n");
562 help();
563 return -1;
564 }
565 } else if (strlen(*argv) > 2 && strncmp(*argv, "-D", 2) == 0) {
566 argv++;
567 if (argv < stop) {
568 defineDict.set(argv[-1] + 2, *argv);
569 } else {
570 logger.logError("incomplete '-Dfoo bar' definition\n");
571 help();
572 return -1;
573 }
574 } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
575 help();
576 return 0;
577 } else {
578 SkString str;
579 str.printf("unrecognized arg %s\n", *argv);
580 logger.logError(str);
581 help();
582 return -1;
583 } 296 }
584 } 297 }
585 if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchMod es) 298
586 && !outDir.isEmpty()) { 299 BenchMode benchMode = kNormal_BenchMode;
587 logger.logError("'--mode record' and '--mode picturerecord' are not" 300 for (size_t i = 0; i < SK_ARRAY_COUNT(BenchMode_Name); i++) {
588 " compatible with -o.\n"); 301 if (strcmp(FLAGS_mode[0], BenchMode_Name[i]) == 0) {
589 return -1; 302 benchMode = static_cast<BenchMode>(i);
303 }
590 } 304 }
591 if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchMod es)) { 305
592 perIterTimeformat.set("%.4f"); 306 SkTDArray<int> configs;
593 normalTimeFormat.set("%6.4f"); 307 // Try user-given configs first.
308 for (int i = 0; i < FLAGS_config.count(); i++) {
309 for (size_t j = 0; j < SK_ARRAY_COUNT(gConfigs); j++) {
310 if (0 == strcmp(FLAGS_config[i], gConfigs[j].name)) {
311 *configs.append() = j;
312 }
313 }
594 } 314 }
595 if (!userConfig) { 315 // If there weren't any, fill in with defaults.
596 // if no config is specified by user, add the default configs 316 if (configs.count() == 0) {
597 for (unsigned int i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) { 317 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
598 if (gConfigs[i].fRunByDefault) { 318 if (gConfigs[i].runByDefault) {
599 *configs.append() = i; 319 *configs.append() = i;
600 } 320 }
601 } 321 }
602 } 322 }
603 if (kNormal_benchModes != benchMode) { 323 // Filter out things we can't run.
324 if (kNormal_BenchMode != benchMode) {
604 // Non-rendering configs only run in normal mode 325 // Non-rendering configs only run in normal mode
605 for (int i = 0; i < configs.count(); ++i) { 326 for (int i = 0; i < configs.count(); ++i) {
606 int configIdx = configs[i]; 327 const Config& config = gConfigs[configs[i]];
607 if (kNonRendering_Backend == gConfigs[configIdx].fBackend) { 328 if (kNonRendering_Backend == config.backend) {
608 configs.remove(i, 1); 329 configs.remove(i, 1);
609 --i; 330 --i;
610 } 331 }
611 } 332 }
612 } 333 }
613
614 #if SK_SUPPORT_GPU 334 #if SK_SUPPORT_GPU
615 for (int i = 0; i < configs.count(); ++i) { 335 for (int i = 0; i < configs.count(); ++i) {
616 int configIdx = configs[i]; 336 const Config& config = gConfigs[configs[i]];
617 337
618 if (kGPU_Backend == gConfigs[configIdx].fBackend && gConfigs[configIdx]. fSampleCnt > 0) { 338 if (kGPU_Backend == config.backend) {
619 GrContext* context = gContextFactory.get(gConfigs[configIdx].fContex tType); 339 GrContext* context = gContextFactory.get(config.contextType);
620 if (NULL == context) { 340 if (NULL == context) {
621 SkString error; 341 SkString error;
622 error.printf("Error creating GrContext for config %s. Config wil l be skipped.\n", 342 error.printf("Error creating GrContext for config %s. Config wil l be skipped.\n",
623 gConfigs[configIdx].fName); 343 config.name);
624 logger.logError(error.c_str()); 344 logger.logError(error);
625 configs.remove(i); 345 configs.remove(i);
626 --i; 346 --i;
627 continue; 347 continue;
628 } 348 }
629 if (gConfigs[configIdx].fSampleCnt > context->getMaxSampleCount()){ 349 if (config.sampleCount > context->getMaxSampleCount()){
630 SkString error; 350 SkString error;
631 error.printf("Sample count (%d) for config %s is unsupported. " 351 error.printf("Sample count (%d) for config %s is unsupported. "
632 "Config will be skipped.\n", 352 "Config will be skipped.\n",
633 gConfigs[configIdx].fSampleCnt, gConfigs[configIdx] .fName); 353 config.sampleCount, config.name);
634 logger.logError(error.c_str()); 354 logger.logError(error);
635 configs.remove(i); 355 configs.remove(i);
636 --i; 356 --i;
637 continue; 357 continue;
638 } 358 }
639 } 359 }
640 } 360 }
641 #endif 361 #endif
642 362
643 // report our current settings 363 // All flags should be parsed now. Report our settings.
644 { 364 if (kIsDebug) {
645 SkString str; 365 logger.logError("bench was built in Debug mode, so we're going to hide t he times."
646 const char* deferredMode = benchMode == kDeferred_benchModes ? "yes" : 366 " It's for your own good!\n");
647 (benchMode == kDeferredSilent_benchModes ? "silent" : "no"); 367 }
648 str.printf("skia bench: alpha=0x%02X antialias=%d filter=%d " 368 SkString str("skia bench:");
649 "deferred=%s logperiter=%d", 369 str.appendf(" mode=%s", FLAGS_mode[0]);
650 forceAlpha, forceAA, forceFilter, deferredMode, 370 str.appendf(" alpha=0x%02X antialias=%d filter=%d dither=%s",
651 TimerData::kPerIter_Result == timerResult); 371 alpha, FLAGS_forceAA, FLAGS_forceFilter, SkTriState::Name[dither ]);
652 str.appendf(" rotate=%d scale=%d clip=%d min=%d", 372 str.appendf(" rotate=%d scale=%d clip=%d", FLAGS_rotate, FLAGS_scale, FLAGS_ clip);
653 doRotate, doScale, doClip, TimerData::kMin_Result == timerRes ult); 373
654 str.appendf(" record=%d picturerecord=%d", 374 #if defined(SK_SCALAR_IS_FIXED)
655 benchMode == kRecord_benchModes, 375 str.append(" scalar=fixed");
656 benchMode == kPictureRecord_benchModes); 376 #else
657 const char * ditherName; 377 str.append(" scalar=float");
658 switch (forceDither) {
659 case SkTriState::kDefault: ditherName = "default"; break;
660 case SkTriState::kTrue: ditherName = "true"; break;
661 case SkTriState::kFalse: ditherName = "false"; break;
662 default: ditherName = "<invalid>"; break;
663 }
664 str.appendf(" dither=%s", ditherName);
665
666 if (hasStrokeWidth) {
667 str.appendf(" strokeWidth=%f", strokeWidth);
668 } else {
669 str.append(" strokeWidth=none");
670 }
671
672 #if defined(SK_SCALAR_IS_FLOAT)
673 str.append(" scalar=float");
674 #elif defined(SK_SCALAR_IS_FIXED)
675 str.append(" scalar=fixed");
676 #endif 378 #endif
677 379
678 #if defined(SK_BUILD_FOR_WIN32) 380 #if defined(SK_BUILD_FOR_WIN32)
679 str.append(" system=WIN32"); 381 str.append(" system=WIN32");
680 #elif defined(SK_BUILD_FOR_MAC) 382 #elif defined(SK_BUILD_FOR_MAC)
681 str.append(" system=MAC"); 383 str.append(" system=MAC");
682 #elif defined(SK_BUILD_FOR_ANDROID) 384 #elif defined(SK_BUILD_FOR_ANDROID)
683 str.append(" system=ANDROID"); 385 str.append(" system=ANDROID");
684 #elif defined(SK_BUILD_FOR_UNIX) 386 #elif defined(SK_BUILD_FOR_UNIX)
685 str.append(" system=UNIX"); 387 str.append(" system=UNIX");
686 #else 388 #else
687 str.append(" system=other"); 389 str.append(" system=other");
688 #endif 390 #endif
689 391
690 #if defined(SK_DEBUG) 392 #if defined(SK_DEBUG)
691 str.append(" DEBUG"); 393 str.append(" DEBUG");
692 #endif 394 #endif
693 str.append("\n"); 395 str.append("\n");
694 logger.logProgress(str); 396 logger.logProgress(str);
695 } 397
696 398
697 SkTArray<BenchTimer*> timers(SK_ARRAY_COUNT(gConfigs)); 399 // Set texture cache limits if non-default.
698 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) { 400 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
699 #if SK_SUPPORT_GPU 401 #if SK_SUPPORT_GPU
700 SkGLContextHelper* glCtx = NULL; 402 const Config& config = gConfigs[i];
701 if (kGPU_Backend == gConfigs[i].fBackend) { 403 if (kGPU_Backend != config.backend) {
702 GrContext* context = gContextFactory.get(gConfigs[i].fContextType); 404 continue;
703 if (NULL != context) { 405 }
704 // Set the user specified cache limits if non-default. 406 GrContext* context = gContextFactory.get(config.contextType);
705 size_t bytes; 407 if (NULL == context) {
706 int count; 408 continue;
707 context->getTextureCacheLimits(&count, &bytes); 409 }
708 if (-1 != gpuCacheSize.fBytes) { 410
709 bytes = static_cast<size_t>(gpuCacheSize.fBytes); 411 size_t bytes;
710 } 412 int count;
711 if (-1 != gpuCacheSize.fCount) { 413 context->getTextureCacheLimits(&count, &bytes);
712 count = gpuCacheSize.fCount; 414 if (-1 != FLAGS_gpuCacheBytes) {
713 } 415 bytes = static_cast<size_t>(FLAGS_gpuCacheBytes);
714 context->setTextureCacheLimits(count, bytes); 416 }
715 } 417 if (-1 != FLAGS_gpuCacheCount) {
716 glCtx = gContextFactory.getGLContext(gConfigs[i].fContextType); 418 count = FLAGS_gpuCacheCount;
717 } 419 }
718 timers.push_back(SkNEW_ARGS(BenchTimer, (glCtx))); 420 context->setTextureCacheLimits(count, bytes);
719 #else 421 #endif
720 timers.push_back(SkNEW(BenchTimer)); 422 }
721 #endif 423
722 } 424 // Find the longest name of the benches we're going to run to make the outpu t pretty.
723 425 Iter names;
724 Iter iter(&defineDict);
725 SkBenchmark* bench; 426 SkBenchmark* bench;
427 int longestName = 0;
428 while ((bench = names.next()) != NULL) {
429 SkAutoTUnref<SkBenchmark> benchUnref(bench);
430 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
431 continue;
432 }
433 const int length = strlen(bench->getName());
434 longestName = length > longestName ? length : longestName;
435 }
436
437 // Run each bench in each configuration it supports and we asked for.
438 Iter iter;
726 while ((bench = iter.next()) != NULL) { 439 while ((bench = iter.next()) != NULL) {
727 SkAutoTUnref<SkBenchmark> benchUnref(bench); 440 SkAutoTUnref<SkBenchmark> benchUnref(bench);
728 441 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
729 SkIPoint dim = bench->getSize(); 442 continue;
730 if (dim.fX <= 0 || dim.fY <= 0) { 443 }
731 continue; 444
732 } 445 bench->setForceAlpha(alpha);
733 446 bench->setForceAA(FLAGS_forceAA);
734 bench->setForceAlpha(forceAlpha); 447 bench->setForceFilter(FLAGS_forceFilter);
735 bench->setForceAA(forceAA); 448 bench->setDither(dither);
736 bench->setForceFilter(forceFilter);
737 bench->setDither(forceDither);
738 if (hasStrokeWidth) {
739 bench->setStrokeWidth(strokeWidth);
740 }
741
742 // only run benchmarks if their name contains matchStr
743 if (SkCommandLineFlags::ShouldSkip(fMatches, bench->getName())) {
744 continue;
745 }
746
747 bool loggedBenchStart = false;
748
749 AutoPrePostDraw appd(bench); 449 AutoPrePostDraw appd(bench);
750 450
751 for (int x = 0; x < configs.count(); ++x) { 451 bool loggedBenchName = false;
752 int configIndex = configs[x]; 452 for (int i = 0; i < configs.count(); ++i) {
753 453 const int configIndex = configs[i];
754 bool setupFailed = false; 454 const Config& config = gConfigs[configIndex];
755 455
756 if (kNonRendering_Backend == gConfigs[configIndex].fBackend) { 456 if ((kNonRendering_Backend == config.backend) == bench->isRendering( )) {
757 if (bench->isRendering()) { 457 continue;
758 continue; 458 }
759 } 459
760 } else {
761 if (!bench->isRendering()) {
762 continue;
763 }
764 }
765
766 outConfig = gConfigs[configIndex].fConfig;
767 configName = gConfigs[configIndex].fName;
768 backend = gConfigs[configIndex].fBackend;
769 sampleCount = gConfigs[configIndex].fSampleCnt;
770 GrContext* context = NULL; 460 GrContext* context = NULL;
771 BenchTimer* timer = timers[configIndex];
772
773 #if SK_SUPPORT_GPU 461 #if SK_SUPPORT_GPU
774 SkGLContextHelper* glContext = NULL; 462 SkGLContextHelper* glContext = NULL;
775 if (kGPU_Backend == backend) { 463 if (kGPU_Backend == config.backend) {
776 context = gContextFactory.get(gConfigs[configIndex].fContextType ); 464 context = gContextFactory.get(config.contextType);
777 if (NULL == context) { 465 if (NULL == context) {
778 continue; 466 continue;
779 } 467 }
780 glContext = gContextFactory.getGLContext(gConfigs[configIndex].f ContextType); 468 glContext = gContextFactory.getGLContext(config.contextType);
781 } 469 }
782 #endif 470 #endif
783 SkBaseDevice* device = NULL; 471 SkAutoTUnref<SkBaseDevice> device;
784 SkCanvas* canvas = NULL; 472 SkAutoTUnref<SkCanvas> canvas;
785 SkPicture pictureRecordFrom; 473 SkPicture recordFrom, recordTo;
786 SkPicture pictureRecordTo; 474 const SkIPoint dim = bench->getSize();
787 475
788 if (kNonRendering_Backend != backend) { 476 const SkPicture::RecordingFlags kRecordFlags =
789 device = make_device(outConfig, dim, backend, sampleCount, conte xt); 477 SkPicture::kUsePathBoundsForClip_RecordingFlag;
790 if (NULL == device) { 478
479 if (kNonRendering_Backend != config.backend) {
480 device.reset(make_device(config.config,
481 dim,
482 config.backend,
483 config.sampleCount,
484 context));
485 if (!device.get()) {
791 SkString error; 486 SkString error;
792 error.printf("Device creation failure for config %s. Will sk ip.\n", configName); 487 error.printf("Device creation failure for config %s. Will sk ip.\n", config.name);
793 logger.logError(error.c_str()); 488 logger.logError(error);
794 setupFailed = true; 489 continue;
490 }
491
492 switch(benchMode) {
493 case kDeferredSilent_BenchMode:
494 case kDeferred_BenchMode:
495 canvas.reset(SkDeferredCanvas::Create(device.get()));
496 break;
497 case kRecord_BenchMode:
498 canvas.reset(SkRef(recordTo.beginRecording(dim.fX, dim.f Y, kRecordFlags)));
499 break;
500 case kPictureRecord_BenchMode:
501 bench->draw(recordFrom.beginRecording(dim.fX, dim.fY, kR ecordFlags));
502 recordFrom.endRecording();
503 canvas.reset(SkRef(recordTo.beginRecording(dim.fX, dim.f Y, kRecordFlags)));
504 break;
505 case kNormal_BenchMode:
506 canvas.reset(new SkCanvas(device.get()));
507 break;
508 default:
509 SkASSERT(false);
510 }
511 }
512
513 if (NULL != canvas) {
514 canvas->clear(SK_ColorWHITE);
515 if (FLAGS_clip) { performClip(canvas, dim.fX, dim.fY); }
516 if (FLAGS_scale) { performScale(canvas, dim.fX, dim.fY); }
517 if (FLAGS_rotate) { performRotate(canvas, dim.fX, dim.fY); }
518 }
519
520 if (!loggedBenchName) {
521 loggedBenchName = true;
522 SkString str;
523 str.printf("running bench [%3d %3d] %*s ",
524 dim.fX, dim.fY, longestName, bench->getName());
525 logger.logProgress(str);
526 }
527
528 #if SK_SUPPORT_GPU
529 SkGLContextHelper* contextHelper = NULL;
530 if (kGPU_Backend == config.backend) {
531 contextHelper = gContextFactory.getGLContext(config.contextType) ;
532 }
533 BenchTimer timer(contextHelper);
534 #else
535 BenchTimer timer;
536 #endif
537
538 bench->setLoops(0);
539 do {
540 // Ramp up 1 -> 4 -> 16 -> ... -> ~1 billion.
541 const int loops = bench->getLoops();
542 if (loops >= (1<<30)) {
543 // If you find it takes more than a billion loops to get up to 20ms of runtime,
544 // you've got a computer clocked at several THz or have a br oken benchmark. ;)
545 // "1B ought to be enough for anybody."
546 SkString str;
547 str.printf("Can't ramp %s to %dms.\n", bench->getName(), FLA GS_benchMs);
548 logger.logError(str);
549 break;
550 }
551 bench->setLoops(loops == 0 ? 1 : loops * 4);
552
553 if ((benchMode == kRecord_BenchMode || benchMode == kPictureReco rd_BenchMode)) {
554 // Clear the recorded commands so that they do not accumulat e.
555 canvas.reset(recordTo.beginRecording(dim.fX, dim.fY, kRecord Flags));
556 }
557
558 timer.start();
559 if (NULL != canvas) {
560 canvas->save();
561 }
562 if (benchMode == kPictureRecord_BenchMode) {
563 recordFrom.draw(canvas);
795 } else { 564 } else {
796 switch(benchMode) { 565 bench->draw(canvas);
797 case kDeferredSilent_benchModes: 566 }
798 case kDeferred_benchModes: 567
799 canvas = SkDeferredCanvas::Create(device); 568 if (kDeferredSilent_BenchMode == benchMode) {
800 break; 569 static_cast<SkDeferredCanvas*>(canvas.get())->silentFlush();
801 case kRecord_benchModes: 570 } else if (NULL != canvas) {
802 canvas = pictureRecordTo.beginRecording(dim.fX, dim. fY, 571 canvas->flush();
803 SkPicture::kUsePathBoundsForClip_RecordingFlag); 572 }
804 canvas->ref(); 573
805 break;
806 case kPictureRecord_benchModes: {
807 // This sets up picture-to-picture recording.
808 // The C++ drawing calls for the benchmark are recor ded into
809 // pictureRecordFrom. As the benchmark, we will time how
810 // long it takes to playback pictureRecordFrom into
811 // pictureRecordTo.
812 SkCanvas* tempCanvas = pictureRecordFrom.beginRecord ing(dim.fX, dim.fY,
813 SkPicture::kUsePathBoundsForClip_RecordingFlag);
814 bench->draw(tempCanvas);
815 pictureRecordFrom.endRecording();
816 canvas = pictureRecordTo.beginRecording(dim.fX, dim. fY,
817 SkPicture::kUsePathBoundsForClip_RecordingFlag);
818 canvas->ref();
819 break;
820 }
821 case kNormal_benchModes:
822 canvas = new SkCanvas(device);
823 break;
824 default:
825 SkASSERT(0);
826 }
827 device->unref();
828 canvas->clear(SK_ColorWHITE);
829 }
830 }
831 SkAutoUnref canvasUnref(canvas);
832 if (!setupFailed) {
833 if (NULL != canvas) { 574 if (NULL != canvas) {
834 if (doClip) { 575 canvas->restore();
835 performClip(canvas, dim.fX, dim.fY); 576 }
836 } 577
837 if (doScale) { 578
838 performScale(canvas, dim.fX, dim.fY); 579 // Stop truncated timers before GL calls complete, and stop the full timers after.
839 } 580 timer.truncatedEnd();
840 if (doRotate) { 581 #if SK_SUPPORT_GPU
841 performRotate(canvas, dim.fX, dim.fY); 582 if (NULL != glContext) {
842 } 583 context->flush();
843 } 584 SK_GL(*glContext, Finish());
844 585 }
845 if (!loggedBenchStart) { 586 #endif
846 loggedBenchStart = true; 587 timer.end();
847 SkString str; 588 } while (!kIsDebug && timer.fWall < FLAGS_benchMs); // One loop onl y in debug mode.
848 str.printf("running bench [%d %d] %28s", dim.fX, dim.fY, ben ch->getName()); 589
849 logger.logProgress(str); 590 if (FLAGS_outDir.count() && kNonRendering_Backend != config.backend) {
850 } 591 saveFile(bench->getName(),
851 592 config.name,
852 // warm up caches if needed 593 FLAGS_outDir[0],
853 if (repeatDraw > 1 && NULL != canvas) { 594 device->accessBitmap(false));
854 #if SK_SUPPORT_GPU 595 }
855 // purge the GPU resources to reduce variance 596
856 if (NULL != context) { 597 if (kIsDebug) {
857 context->freeGpuResources(); 598 // Let's not mislead ourselves by looking at Debug build bench t imes!
858 } 599 continue;
859 #endif 600 }
860 SkAutoCanvasRestore acr(canvas, true); 601
861 if (benchMode == kPictureRecord_benchModes) { 602 // Normalize to ms per 1000 iterations.
862 pictureRecordFrom.draw(canvas); 603 const double normalize = 1000.0 / bench->getLoops();
863 } else { 604 const struct { char shortName; const char* longName; double ms; } ti mes[] = {
864 bench->draw(canvas); 605 {'w', "msecs", normalize * timer.fWall},
865 } 606 {'W', "Wmsecs", normalize * timer.fTruncatedWall},
866 607 {'c', "cmsecs", normalize * timer.fCpu},
867 if (kDeferredSilent_benchModes == benchMode) { 608 {'C', "Cmsecs", normalize * timer.fTruncatedCpu},
868 static_cast<SkDeferredCanvas*>(canvas)->silentFlush(); 609 {'g', "gmsecs", normalize * timer.fGpu},
869 } else { 610 };
870 canvas->flush(); 611
871 } 612 SkString result;
872 #if SK_SUPPORT_GPU 613 result.appendf(" %s:", config.name);
873 if (NULL != context) { 614 for (size_t i = 0; i < SK_ARRAY_COUNT(times); i++) {
874 context->flush(); 615 if (strchr(FLAGS_timers[0], times[i].shortName) && times[i].ms > 0) {
875 SK_GL(*glContext, Finish()); 616 result.appendf(" %s = ", times[i].longName);
876 } 617 result.appendf(FLAGS_timeFormat[0], times[i].ms);
877 #endif 618 }
878 } 619 }
879 620 logger.logProgress(result);
880 // record timer values for each repeat, and their sum 621 }
881 TimerData timerData(repeatDraw); 622 if (loggedBenchName) {
882 for (int i = 0; i < repeatDraw; i++) { 623 logger.logProgress("\n");
883 if ((benchMode == kRecord_benchModes || benchMode == kPictur eRecord_benchModes)) { 624 }
884 // This will clear the recorded commands so that they do not 625 }
885 // accumulate. 626 #if SK_SUPPORT_GPU
886 canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
887 SkPicture::kUsePathBoundsForClip_RecordingFlag);
888 }
889
890 timer->start(bench->getDurationScale());
891 if (NULL != canvas) {
892 canvas->save();
893 }
894 if (benchMode == kPictureRecord_benchModes) {
895 pictureRecordFrom.draw(canvas);
896 } else {
897 bench->draw(canvas);
898 }
899
900 if (kDeferredSilent_benchModes == benchMode) {
901 static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
902 } else if (NULL != canvas) {
903 canvas->flush();
904 }
905
906 if (NULL != canvas) {
907 canvas->restore();
908 }
909
910 // stop the truncated timer after the last canvas call but
911 // don't wait for all the GL calls to complete
912 timer->truncatedEnd();
913 #if SK_SUPPORT_GPU
914 if (NULL != glContext) {
915 context->flush();
916 SK_GL(*glContext, Finish());
917 }
918 #endif
919 // stop the inclusive and gpu timers once all the GL calls
920 // have completed
921 timer->end();
922
923 SkAssertResult(timerData.appendTimes(timer));
924
925 }
926 const char* timeFormat;
927 if (repeatDraw > 1 && TimerData::kPerIter_Result == timerResult) {
928 timeFormat = perIterTimeformat.c_str();
929 } else {
930 timeFormat = normalTimeFormat.c_str();
931 }
932 uint32_t filteredTimerTypes = timerTypes;
933 if (NULL == context) {
934 filteredTimerTypes &= ~TimerData::kGpu_Flag;
935 }
936 SkString result = timerData.getResult(timeFormat,
937 timerResult,
938 configName,
939 filteredTimerTypes);
940 logger.logProgress(result);
941
942 if (outDir.size() > 0 && kNonRendering_Backend != backend) {
943 saveFile(bench->getName(), configName, outDir.c_str(),
944 device->accessBitmap(false));
945 }
946 }
947 }
948 if (loggedBenchStart) {
949 logger.logProgress(SkString("\n"));
950 }
951 }
952 #if SK_SUPPORT_GPU
953 #if GR_CACHE_STATS
954 for (int i = 0; i <= GrContextFactory::kLastGLContextType; ++i) {
955 GrContextFactory::GLContextType ctxType = (GrContextFactory::GLContextTy pe)i;
956 GrContext* context = gContextFactory.get(ctxType);
957 if (NULL != context) {
958 SkDebugf("Cache Stats for %s context:\n", GrContextFactory::GLContex tTypeName(ctxType));
959 context->printCacheStats();
960 SkDebugf("\n");
961 }
962 }
963 #endif
964 // Destroy the GrContext before the inst tracking printing at main() exit oc curs.
965 gContextFactory.destroyContexts(); 627 gContextFactory.destroyContexts();
966 #endif 628 #endif
967 for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
968 SkDELETE(timers[i]);
969 }
970
971 return 0; 629 return 0;
972 } 630 }
973 631
974 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) 632 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
975 int main(int argc, char * const argv[]) { 633 int main(int argc, char * const argv[]) {
976 return tool_main(argc, (char**) argv); 634 return tool_main(argc, (char**) argv);
977 } 635 }
978 #endif 636 #endif
OLDNEW
« no previous file with comments | « bench/XfermodeBench.cpp ('k') | gyp/bench.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698