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

Side by Side Diff: bench/nanobench.cpp

Issue 1039253002: Minor cleanup in nanobench (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Canvas may not be present Created 5 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 | « bench/nanobench.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 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include <ctype.h> 8 #include <ctype.h>
9 9
10 #include "nanobench.h" 10 #include "nanobench.h"
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 bool Target::init(SkImageInfo info, Benchmark* bench) { 95 bool Target::init(SkImageInfo info, Benchmark* bench) {
96 if (Benchmark::kRaster_Backend == config.backend) { 96 if (Benchmark::kRaster_Backend == config.backend) {
97 this->surface.reset(SkSurface::NewRaster(info)); 97 this->surface.reset(SkSurface::NewRaster(info));
98 if (!this->surface.get()) { 98 if (!this->surface.get()) {
99 return false; 99 return false;
100 } 100 }
101 } 101 }
102 return true; 102 return true;
103 } 103 }
104 bool Target::capturePixels(SkBitmap* bmp) { 104 bool Target::capturePixels(SkBitmap* bmp) {
105 if (!this->surface.get()) { 105 SkCanvas* canvas = this->getCanvas();
106 return false;
107 }
108 SkCanvas* canvas = this->surface->getCanvas();
109 if (!canvas) { 106 if (!canvas) {
110 return false; 107 return false;
111 } 108 }
112 bmp->setInfo(canvas->imageInfo()); 109 bmp->setInfo(canvas->imageInfo());
113 if (!canvas->readPixels(bmp, 0, 0)) { 110 if (!canvas->readPixels(bmp, 0, 0)) {
114 SkDebugf("Can't read canvas pixels.\n"); 111 SkDebugf("Can't read canvas pixels.\n");
115 return false; 112 return false;
116 } 113 }
117 return true; 114 return true;
118 } 115 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 SK_GL_RET(*this->gl, version, GetString(GR_GL_VENDOR)); 158 SK_GL_RET(*this->gl, version, GetString(GR_GL_VENDOR));
162 log->configOption("GL_VENDOR", (const char*) version); 159 log->configOption("GL_VENDOR", (const char*) version);
163 160
164 SK_GL_RET(*this->gl, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION)) ; 161 SK_GL_RET(*this->gl, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION)) ;
165 log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version); 162 log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version);
166 } 163 }
167 }; 164 };
168 165
169 #endif 166 #endif
170 167
171 static double time(int loops, Benchmark* bench, SkCanvas* canvas, Target* target ) { 168 static double time(int loops, Benchmark* bench, Target* target) {
169 SkCanvas* canvas = target->getCanvas();
172 if (canvas) { 170 if (canvas) {
173 canvas->clear(SK_ColorWHITE); 171 canvas->clear(SK_ColorWHITE);
174 } 172 }
175 WallTimer timer; 173 WallTimer timer;
176 timer.start(); 174 timer.start();
177 if (target) { 175 canvas = target->beginTiming(canvas);
178 canvas = target->beginTiming(canvas); 176 bench->draw(loops, canvas);
179 }
180 if (bench) {
181 bench->draw(loops, canvas);
182 }
183 if (canvas) { 177 if (canvas) {
184 canvas->flush(); 178 canvas->flush();
185 } 179 }
186 if (target) { 180 target->endTiming();
187 target->endTiming();
188 }
189 timer.end(); 181 timer.end();
190 return timer.fWall; 182 return timer.fWall;
191 } 183 }
192 184
193 static double estimate_timer_overhead() { 185 static double estimate_timer_overhead() {
194 double overhead = 0; 186 double overhead = 0;
195 for (int i = 0; i < FLAGS_overheadLoops; i++) { 187 for (int i = 0; i < FLAGS_overheadLoops; i++) {
196 overhead += time(1, NULL, NULL, NULL); 188 WallTimer timer;
189 timer.start();
190 timer.end();
191 overhead += timer.fWall;
197 } 192 }
198 return overhead / FLAGS_overheadLoops; 193 return overhead / FLAGS_overheadLoops;
199 } 194 }
200 195
201 static int detect_forever_loops(int loops) { 196 static int detect_forever_loops(int loops) {
202 // look for a magic run-forever value 197 // look for a magic run-forever value
203 if (loops < 0) { 198 if (loops < 0) {
204 loops = SK_MaxS32; 199 loops = SK_MaxS32;
205 } 200 }
206 return loops; 201 return loops;
(...skipping 10 matching lines...) Expand all
217 return FLAGS_maxLoops; 212 return FLAGS_maxLoops;
218 } 213 }
219 return loops; 214 return loops;
220 } 215 }
221 216
222 static bool write_canvas_png(Target* target, const SkString& filename) { 217 static bool write_canvas_png(Target* target, const SkString& filename) {
223 218
224 if (filename.isEmpty()) { 219 if (filename.isEmpty()) {
225 return false; 220 return false;
226 } 221 }
227 if (target->surface.get() && target->surface->getCanvas() && 222 if (target->getCanvas() &&
228 kUnknown_SkColorType == target->surface->getCanvas()->imageInfo().colorT ype()) { 223 kUnknown_SkColorType == target->getCanvas()->imageInfo().colorType()) {
229 return false; 224 return false;
230 } 225 }
231 226
232 SkBitmap bmp; 227 SkBitmap bmp;
233 228
234 if (!target->capturePixels(&bmp)) { 229 if (!target->capturePixels(&bmp)) {
235 return false; 230 return false;
236 } 231 }
237 232
238 SkString dir = SkOSPath::Dirname(filename.c_str()); 233 SkString dir = SkOSPath::Dirname(filename.c_str());
239 if (!sk_mkdir(dir.c_str())) { 234 if (!sk_mkdir(dir.c_str())) {
240 SkDebugf("Can't make dir %s.\n", dir.c_str()); 235 SkDebugf("Can't make dir %s.\n", dir.c_str());
241 return false; 236 return false;
242 } 237 }
243 SkFILEWStream stream(filename.c_str()); 238 SkFILEWStream stream(filename.c_str());
244 if (!stream.isValid()) { 239 if (!stream.isValid()) {
245 SkDebugf("Can't write %s.\n", filename.c_str()); 240 SkDebugf("Can't write %s.\n", filename.c_str());
246 return false; 241 return false;
247 } 242 }
248 if (!SkImageEncoder::EncodeStream(&stream, bmp, SkImageEncoder::kPNG_Type, 1 00)) { 243 if (!SkImageEncoder::EncodeStream(&stream, bmp, SkImageEncoder::kPNG_Type, 1 00)) {
249 SkDebugf("Can't encode a PNG.\n"); 244 SkDebugf("Can't encode a PNG.\n");
250 return false; 245 return false;
251 } 246 }
252 return true; 247 return true;
253 } 248 }
254 249
255 static int kFailedLoops = -2; 250 static int kFailedLoops = -2;
256 static int cpu_bench(const double overhead, Benchmark* bench, SkCanvas* canvas, double* samples) { 251 static int cpu_bench(const double overhead, Target* target, Benchmark* bench, do uble* samples) {
257 // First figure out approximately how many loops of bench it takes to make o verhead negligible. 252 // First figure out approximately how many loops of bench it takes to make o verhead negligible.
258 double bench_plus_overhead = 0.0; 253 double bench_plus_overhead = 0.0;
259 int round = 0; 254 int round = 0;
260 if (kAutoTuneLoops == FLAGS_loops) { 255 if (kAutoTuneLoops == FLAGS_loops) {
261 while (bench_plus_overhead < overhead) { 256 while (bench_plus_overhead < overhead) {
262 if (round++ == FLAGS_maxCalibrationAttempts) { 257 if (round++ == FLAGS_maxCalibrationAttempts) {
263 SkDebugf("WARNING: Can't estimate loops for %s (%s vs. %s); skip ping.\n", 258 SkDebugf("WARNING: Can't estimate loops for %s (%s vs. %s); skip ping.\n",
264 bench->getUniqueName(), HUMANIZE(bench_plus_overhead), HUMANIZE(overhead)); 259 bench->getUniqueName(), HUMANIZE(bench_plus_overhead), HUMANIZE(overhead));
265 return kFailedLoops; 260 return kFailedLoops;
266 } 261 }
267 bench_plus_overhead = time(1, bench, canvas, NULL); 262 bench_plus_overhead = time(1, bench, target);
268 } 263 }
269 } 264 }
270 265
271 // Later we'll just start and stop the timer once but loop N times. 266 // Later we'll just start and stop the timer once but loop N times.
272 // We'll pick N to make timer overhead negligible: 267 // We'll pick N to make timer overhead negligible:
273 // 268 //
274 // overhead 269 // overhead
275 // ------------------------- < FLAGS_overheadGoal 270 // ------------------------- < FLAGS_overheadGoal
276 // overhead + N * Bench Time 271 // overhead + N * Bench Time
277 // 272 //
(...skipping 10 matching lines...) Expand all
288 if (kAutoTuneLoops == loops) { 283 if (kAutoTuneLoops == loops) {
289 const double numer = overhead / FLAGS_overheadGoal - overhead; 284 const double numer = overhead / FLAGS_overheadGoal - overhead;
290 const double denom = bench_plus_overhead - overhead; 285 const double denom = bench_plus_overhead - overhead;
291 loops = (int)ceil(numer / denom); 286 loops = (int)ceil(numer / denom);
292 loops = clamp_loops(loops); 287 loops = clamp_loops(loops);
293 } else { 288 } else {
294 loops = detect_forever_loops(loops); 289 loops = detect_forever_loops(loops);
295 } 290 }
296 291
297 for (int i = 0; i < FLAGS_samples; i++) { 292 for (int i = 0; i < FLAGS_samples; i++) {
298 samples[i] = time(loops, bench, canvas, NULL) / loops; 293 samples[i] = time(loops, bench, target) / loops;
299 } 294 }
300 return loops; 295 return loops;
301 } 296 }
302 297
303 static int gpu_bench(Target* target, 298 static int gpu_bench(Target* target,
304 Benchmark* bench, 299 Benchmark* bench,
305 SkCanvas* canvas,
306 double* samples) { 300 double* samples) {
307 // First, figure out how many loops it'll take to get a frame up to FLAGS_gp uMs. 301 // First, figure out how many loops it'll take to get a frame up to FLAGS_gp uMs.
308 int loops = FLAGS_loops; 302 int loops = FLAGS_loops;
309 if (kAutoTuneLoops == loops) { 303 if (kAutoTuneLoops == loops) {
310 loops = 1; 304 loops = 1;
311 double elapsed = 0; 305 double elapsed = 0;
312 do { 306 do {
313 if (1<<30 == loops) { 307 if (1<<30 == loops) {
314 // We're about to wrap. Something's wrong with the bench. 308 // We're about to wrap. Something's wrong with the bench.
315 loops = 0; 309 loops = 0;
316 break; 310 break;
317 } 311 }
318 loops *= 2; 312 loops *= 2;
319 // If the GPU lets frames lag at all, we need to make sure we're tim ing 313 // If the GPU lets frames lag at all, we need to make sure we're tim ing
320 // _this_ round, not still timing last round. We force this by loop ing 314 // _this_ round, not still timing last round. We force this by loop ing
321 // more times than any reasonable GPU will allow frames to lag. 315 // more times than any reasonable GPU will allow frames to lag.
322 for (int i = 0; i < FLAGS_gpuFrameLag; i++) { 316 for (int i = 0; i < FLAGS_gpuFrameLag; i++) {
323 elapsed = time(loops, bench, canvas, target); 317 elapsed = time(loops, bench, target);
324 } 318 }
325 } while (elapsed < FLAGS_gpuMs); 319 } while (elapsed < FLAGS_gpuMs);
326 320
327 // We've overshot at least a little. Scale back linearly. 321 // We've overshot at least a little. Scale back linearly.
328 loops = (int)ceil(loops * FLAGS_gpuMs / elapsed); 322 loops = (int)ceil(loops * FLAGS_gpuMs / elapsed);
329 loops = clamp_loops(loops); 323 loops = clamp_loops(loops);
330 324
331 // Make sure we're not still timing our calibration. 325 // Make sure we're not still timing our calibration.
332 target->fence(); 326 target->fence();
333 } else { 327 } else {
334 loops = detect_forever_loops(loops); 328 loops = detect_forever_loops(loops);
335 } 329 }
336 330
337 // Pretty much the same deal as the calibration: do some warmup to make 331 // Pretty much the same deal as the calibration: do some warmup to make
338 // sure we're timing steady-state pipelined frames. 332 // sure we're timing steady-state pipelined frames.
339 for (int i = 0; i < FLAGS_gpuFrameLag; i++) { 333 for (int i = 0; i < FLAGS_gpuFrameLag; i++) {
340 time(loops, bench, canvas, target); 334 time(loops, bench, target);
341 } 335 }
342 336
343 // Now, actually do the timing! 337 // Now, actually do the timing!
344 for (int i = 0; i < FLAGS_samples; i++) { 338 for (int i = 0; i < FLAGS_samples; i++) {
345 samples[i] = time(loops, bench, canvas, target) / loops; 339 samples[i] = time(loops, bench, target) / loops;
346 } 340 }
347 341
348 return loops; 342 return loops;
349 } 343 }
350 344
351 static SkString to_lower(const char* str) { 345 static SkString to_lower(const char* str) {
352 SkString lower(str); 346 SkString lower(str);
353 for (size_t i = 0; i < lower.size(); i++) { 347 for (size_t i = 0; i < lower.size(); i++) {
354 lower[i] = tolower(lower[i]); 348 lower[i] = tolower(lower[i]);
355 } 349 }
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 826
833 SkTDArray<Target*> targets; 827 SkTDArray<Target*> targets;
834 create_targets(&targets, bench.get(), configs); 828 create_targets(&targets, bench.get(), configs);
835 829
836 if (!targets.isEmpty()) { 830 if (!targets.isEmpty()) {
837 log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSi ze().fY); 831 log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSi ze().fY);
838 bench->preDraw(); 832 bench->preDraw();
839 } 833 }
840 for (int j = 0; j < targets.count(); j++) { 834 for (int j = 0; j < targets.count(); j++) {
841 // During HWUI output this canvas may be NULL. 835 // During HWUI output this canvas may be NULL.
842 SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface-> getCanvas() : NULL; 836 SkCanvas* canvas = targets[j]->getCanvas();
843 const char* config = targets[j]->config.name; 837 const char* config = targets[j]->config.name;
844 838
845 targets[j]->setup(); 839 targets[j]->setup();
846 bench->perCanvasPreDraw(canvas); 840 bench->perCanvasPreDraw(canvas);
847 841
848 const int loops = 842 const int loops =
849 targets[j]->needsFrameTiming() 843 targets[j]->needsFrameTiming()
850 ? gpu_bench(targets[j], bench.get(), canvas, samples.get()) 844 ? gpu_bench(targets[j], bench.get(), samples.get())
851 : cpu_bench(overhead, bench.get(), canvas, samples.get()); 845 : cpu_bench(overhead, targets[j], bench.get(), samples.get());
852 846
853 bench->perCanvasPostDraw(canvas); 847 bench->perCanvasPostDraw(canvas);
854 848
855 if (Benchmark::kNonRendering_Backend != targets[j]->config.backend & & 849 if (Benchmark::kNonRendering_Backend != targets[j]->config.backend & &
856 !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { 850 !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) {
857 SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config ); 851 SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config );
858 pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniq ueName()); 852 pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniq ueName());
859 pngFilename.append(".png"); 853 pngFilename.append(".png");
860 write_canvas_png(targets[j], pngFilename); 854 write_canvas_png(targets[j], pngFilename);
861 } 855 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 934
941 return 0; 935 return 0;
942 } 936 }
943 937
944 #if !defined SK_BUILD_FOR_IOS 938 #if !defined SK_BUILD_FOR_IOS
945 int main(int argc, char** argv) { 939 int main(int argc, char** argv) {
946 SkCommandLineFlags::Parse(argc, argv); 940 SkCommandLineFlags::Parse(argc, argv);
947 return nanobench_main(); 941 return nanobench_main();
948 } 942 }
949 #endif 943 #endif
OLDNEW
« no previous file with comments | « bench/nanobench.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698