diff options
author | mtklein <mtklein@chromium.org> | 2014-09-10 12:19:30 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-10 12:19:30 -0700 |
commit | fd731ce804cd3223318f3feee2c98404890b65f2 (patch) | |
tree | a0d8da69bff1916ff480fa98e0e3f2a5aef7cb7a | |
parent | 33bce0a68bf24696f35b6ce102e6eed2873b69a4 (diff) |
Measure picture recording speed in nanobench.
Today we measure SkPicture playback speed, but not the time it takes to record
the SkPicture. This fixes that by reading SKPs from disk and re-recording them.
On the console, recording shows up first as the nonrendering skp benches,
followed later by the usual playback benches:
maxrss loops min median mean max stddev samples config bench
51M 2 165µs 168µs 169µs 178µs 3% ▆▄▃█▂▄▁▂▁▁ nonrendering tabl_slashdot.skp
57M 1 9.72ms 9.77ms 9.79ms 9.97ms 1% █▂▂▅▃▂▁▄▂▁ nonrendering desk_pokemonwiki.skp
57M 32 2.92µs 2.96µs 3.03µs 3.46µs 6% ▅▁▁▁▁▁▁█▂▁ nonrendering desk_yahoosports.skp
...
147M 1 3.86ms 3.87ms 3.97ms 4.81ms 7% █▁▁▁▁▁▁▁▁▁ 8888 tabl_slashdot.skp_1
147M 1 4.54ms 4.56ms 4.55ms 4.56ms 0% █▅▇▅█▅▂▁▅▁ 565 tabl_slashdot.skp_1
147M 2 3.08ms 3.24ms 4.17ms 8.18ms 50% █▁▁█▁▁▁▁▁▁ gpu tabl_slashdot.skp_1
147M 1 1.61ms 1.62ms 1.69ms 2.33ms 13% █▁▁▁▁▁▁▁▁▁ 8888 desk_pokemonwiki.skp_1
147M 1 1.44ms 1.44ms 1.45ms 1.47ms 1% ▅▂█▂▂▅▁▁▂▁ 565 desk_pokemonwiki.skp_1
...
On skiaperf.com, they'll also be separated out from playback benches by bench_type.
BUG=skia:
R=reed@google.com, mtklein@google.com, jcgregorio@google.com
Author: mtklein@chromium.org
Review URL: https://codereview.chromium.org/559153002
-rw-r--r-- | bench/RecordingBench.cpp | 48 | ||||
-rw-r--r-- | bench/RecordingBench.h | 32 | ||||
-rw-r--r-- | bench/nanobench.cpp | 68 | ||||
-rw-r--r-- | gyp/bench.gyp | 1 | ||||
-rw-r--r-- | gyp/iOSShell.gyp | 1 |
5 files changed, 129 insertions, 21 deletions
diff --git a/bench/RecordingBench.cpp b/bench/RecordingBench.cpp new file mode 100644 index 0000000000..ee626bc52c --- /dev/null +++ b/bench/RecordingBench.cpp @@ -0,0 +1,48 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "RecordingBench.h" + +#include "SkBBHFactory.h" +#include "SkPictureRecorder.h" + +static const int kTileSize = 256; + +RecordingBench::RecordingBench(const char* name, const SkPicture* pic, bool useBBH) + : fSrc(SkRef(pic)) + , fName(name) + , fUseBBH(useBBH) {} + +const char* RecordingBench::onGetName() { + return fName.c_str(); +} + +bool RecordingBench::isSuitableFor(Backend backend) { + return backend == kNonRendering_Backend; +} + +SkIPoint RecordingBench::onGetSize() { + return SkIPoint::Make(SkScalarCeilToInt(fSrc->cullRect().width()), + SkScalarCeilToInt(fSrc->cullRect().height())); +} + +void RecordingBench::onDraw(const int loops, SkCanvas*) { + SkTileGridFactory::TileGridInfo info; + info.fTileInterval.set(kTileSize, kTileSize); + info.fMargin.setEmpty(); + info.fOffset.setZero(); + SkTileGridFactory factory(info); + + const SkScalar w = fSrc->cullRect().width(), + h = fSrc->cullRect().height(); + + for (int i = 0; i < loops; i++) { + SkPictureRecorder recorder; + fSrc->playback(recorder.beginRecording(w, h, fUseBBH ? &factory : NULL)); + SkDELETE(recorder.endRecording()); + } +} diff --git a/bench/RecordingBench.h b/bench/RecordingBench.h new file mode 100644 index 0000000000..4c0340127c --- /dev/null +++ b/bench/RecordingBench.h @@ -0,0 +1,32 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef RecordingBench_DEFINED +#define RecordingBench_DEFINED + +#include "Benchmark.h" +#include "SkPicture.h" + +class RecordingBench : public Benchmark { +public: + RecordingBench(const char* name, const SkPicture*, bool useBBH); + +protected: + virtual const char* onGetName() SK_OVERRIDE; + virtual bool isSuitableFor(Backend) SK_OVERRIDE; + virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE; + virtual SkIPoint onGetSize() SK_OVERRIDE; + +private: + SkAutoTUnref<const SkPicture> fSrc; + SkString fName; + bool fUseBBH; + + typedef Benchmark INHERITED; +}; + +#endif//RecordingBench_DEFINED diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp index 853492b3e0..67646c2667 100644 --- a/bench/nanobench.cpp +++ b/bench/nanobench.cpp @@ -12,6 +12,7 @@ #include "GMBench.h" #include "ProcStats.h" #include "ResultsWriter.h" +#include "RecordingBench.h" #include "SKPBench.h" #include "Stats.h" #include "Timer.h" @@ -407,6 +408,7 @@ class BenchmarkStream { public: BenchmarkStream() : fBenches(BenchRegistry::Head()) , fGMs(skiagm::GMRegistry::Head()) + , fCurrentRecording(0) , fCurrentScale(0) , fCurrentSKP(0) { for (int i = 0; i < FLAGS_skps.count(); i++) { @@ -435,11 +437,33 @@ public: } } + static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) { + // Not strictly necessary, as it will be checked again later, + // but helps to avoid a lot of pointless work if we're going to skip it. + if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) { + return false; + } + + SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); + if (stream.get() == NULL) { + SkDebugf("Could not read %s.\n", path); + return false; + } + + pic->reset(SkPicture::CreateFromStream(stream.get())); + if (pic->get() == NULL) { + SkDebugf("Could not read %s as an SkPicture.\n", path); + return false; + } + return true; + } + Benchmark* next() { if (fBenches) { Benchmark* bench = fBenches->factory()(NULL); fBenches = fBenches->next(); fSourceType = "bench"; + fBenchType = "micro"; return bench; } @@ -448,34 +472,32 @@ public: fGMs = fGMs->next(); if (gm->getFlags() & skiagm::GM::kAsBench_Flag) { fSourceType = "gm"; + fBenchType = "micro"; return SkNEW_ARGS(GMBench, (gm.detach())); } } + // First add all .skps as RecordingBenches. + while (fCurrentRecording < fSKPs.count()) { + const SkString& path = fSKPs[fCurrentRecording++]; + SkAutoTUnref<SkPicture> pic; + if (!ReadPicture(path.c_str(), &pic)) { + continue; + } + SkString name = SkOSPath::Basename(path.c_str()); + fSourceType = "skp"; + fBenchType = "recording"; + return SkNEW_ARGS(RecordingBench, (name.c_str(), pic.get(), FLAGS_bbh)); + } + + // Then once each for each scale as SKPBenches (playback). while (fCurrentScale < fScales.count()) { while (fCurrentSKP < fSKPs.count()) { const SkString& path = fSKPs[fCurrentSKP++]; - - // Not strictly necessary, as it will be checked again later, - // but helps to avoid a lot of pointless work if we're going to skip it. - if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path.c_str())) { + SkAutoTUnref<SkPicture> pic; + if (!ReadPicture(path.c_str(), &pic)) { continue; } - - SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path.c_str())); - if (stream.get() == NULL) { - SkDebugf("Could not read %s.\n", path.c_str()); - exit(1); - } - - SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream.get())); - if (pic.get() == NULL) { - SkDebugf("Could not read %s as an SkPicture.\n", path.c_str()); - exit(1); - } - - SkString name = SkOSPath::Basename(path.c_str()); - if (FLAGS_bbh) { // The SKP we read off disk doesn't have a BBH. Re-record so it grows one. // Here we use an SkTileGrid with parameters optimized for FLAGS_clip. @@ -491,8 +513,9 @@ public: &factory)); pic.reset(recorder.endRecording()); } - + SkString name = SkOSPath::Basename(path.c_str()); fSourceType = "skp"; + fBenchType = "playback"; return SkNEW_ARGS(SKPBench, (name.c_str(), pic.get(), fClip, fScales[fCurrentScale])); } @@ -505,6 +528,7 @@ public: void fillCurrentOptions(ResultsWriter* log) const { log->configOption("source_type", fSourceType); + log->configOption("bench_type", fBenchType); if (0 == strcmp(fSourceType, "skp")) { log->configOption("clip", SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, @@ -520,7 +544,9 @@ private: SkTArray<SkScalar> fScales; SkTArray<SkString> fSKPs; - const char* fSourceType; + const char* fSourceType; // What we're benching: bench, GM, SKP, ... + const char* fBenchType; // How we bench it: micro, recording, playback, ... + int fCurrentRecording; int fCurrentScale; int fCurrentSKP; }; diff --git a/gyp/bench.gyp b/gyp/bench.gyp index d2eb1ea5fe..26849d511a 100644 --- a/gyp/bench.gyp +++ b/gyp/bench.gyp @@ -11,6 +11,7 @@ 'sources': [ '../gm/gm.cpp', '../bench/GMBench.cpp', + '../bench/RecordingBench.cpp', '../bench/SKPBench.cpp', '../bench/nanobench.cpp', ], diff --git a/gyp/iOSShell.gyp b/gyp/iOSShell.gyp index a0eb00ca69..ac2ed30303 100644 --- a/gyp/iOSShell.gyp +++ b/gyp/iOSShell.gyp @@ -19,6 +19,7 @@ ], 'sources': [ '../bench/GMBench.cpp', + '../bench/RecordingBench.cpp', '../bench/SKPBench.cpp', '../bench/nanobench.cpp', '../tests/skia_test.cpp', |