diff options
author | joshualitt <joshualitt@chromium.org> | 2015-06-30 07:43:14 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-30 07:43:14 -0700 |
commit | 962cc98eb49c5bb9b8c8382e7709e6f4b32ebce0 (patch) | |
tree | bafb71b84193dad66ffff47ce95140209773dc0f /tools/VisualBench | |
parent | 2757e3f09d7aae00ebe6c12b55668a89bd71aee1 (diff) |
Add benchmarkstream to visualbench
BUG=skia:
Review URL: https://codereview.chromium.org/1215033002
Diffstat (limited to 'tools/VisualBench')
-rw-r--r-- | tools/VisualBench/VisualBench.cpp | 81 | ||||
-rw-r--r-- | tools/VisualBench/VisualBench.h | 9 | ||||
-rw-r--r-- | tools/VisualBench/VisualBenchmarkStream.cpp | 103 | ||||
-rw-r--r-- | tools/VisualBench/VisualBenchmarkStream.h | 37 | ||||
-rw-r--r-- | tools/VisualBench/VisualSKPBench.cpp | 33 | ||||
-rw-r--r-- | tools/VisualBench/VisualSKPBench.h | 37 |
6 files changed, 242 insertions, 58 deletions
diff --git a/tools/VisualBench/VisualBench.cpp b/tools/VisualBench/VisualBench.cpp index ac53b43167..6501aa36b2 100644 --- a/tools/VisualBench/VisualBench.cpp +++ b/tools/VisualBench/VisualBench.cpp @@ -12,7 +12,6 @@ #include "SkApplication.h" #include "SkCanvas.h" #include "SkCommandLineFlags.h" -#include "SkCommonFlags.h" #include "SkForceLinking.h" #include "SkGraphics.h" #include "SkGr.h" @@ -35,6 +34,7 @@ DEFINE_double(flushMs, 20, "Target flush time in millseconds."); DEFINE_double(loopMs, 5, "Target loop time in millseconds."); DEFINE_int32(msaa, 0, "Number of msaa samples."); DEFINE_bool2(fullscreen, f, true, "Run fullscreen."); +DEFINE_bool2(verbose, v, false, "enable verbose output from the test driver."); static SkString humanize(double ms) { if (FLAGS_verbose) { @@ -47,34 +47,19 @@ static SkString humanize(double ms) { VisualBench::VisualBench(void* hwnd, int argc, char** argv) : INHERITED(hwnd) - , fCurrentPictureIdx(-1) , fCurrentSample(0) , fCurrentFrame(0) , fFlushes(1) , fLoops(1) - , fState(kPreWarmLoops_State) { + , fState(kPreWarmLoops_State) + , fBenchmark(NULL) { SkCommandLineFlags::Parse(argc, argv); - // read all the skp file names. - for (int i = 0; i < FLAGS_skps.count(); i++) { - if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { - fRecords.push_back().fFilename = FLAGS_skps[i]; - } else { - SkOSFile::Iter it(FLAGS_skps[i], ".skp"); - SkString path; - while (it.next(&path)) { - fRecords.push_back().fFilename = SkOSPath::Join(FLAGS_skps[i], path.c_str());; - } - } - } - - if (fRecords.empty()) { - SkDebugf("no valid skps found\n"); - } - this->setTitle(); this->setupBackend(); + fBenchmarkStream.reset(SkNEW(VisualBenchmarkStream)); + // Print header SkDebugf("curr/maxrss\tloops\tflushes\tmin\tmedian\tmean\tmax\tstddev\tbench\n"); } @@ -134,22 +119,20 @@ void VisualBench::setupRenderTarget() { inline void VisualBench::renderFrame(SkCanvas* canvas) { for (int flush = 0; flush < fFlushes; flush++) { - for (int loop = 0; loop < fLoops; loop++) { - canvas->drawPicture(fPicture); - } + fBenchmark->draw(fLoops, canvas); canvas->flush(); } INHERITED::present(); } void VisualBench::printStats() { - const SkTArray<double>& measurements = fRecords[fCurrentPictureIdx].fMeasurements; - SkString shortName = SkOSPath::Basename(fRecords[fCurrentPictureIdx].fFilename.c_str()); + const SkTArray<double>& measurements = fRecords.back().fMeasurements; + const char* shortName = fBenchmark->getUniqueName(); if (FLAGS_verbose) { for (int i = 0; i < measurements.count(); i++) { SkDebugf("%s ", HUMANIZE(measurements[i])); } - SkDebugf("%s\n", shortName.c_str()); + SkDebugf("%s\n", shortName); } else { SkASSERT(measurements.count()); Stats stats(measurements); @@ -164,37 +147,28 @@ void VisualBench::printStats() { HUMANIZE(stats.mean), HUMANIZE(stats.max), stdDevPercent, - shortName.c_str()); + shortName); } } -bool VisualBench::advanceRecordIfNecessary() { - if (fPicture) { +bool VisualBench::advanceRecordIfNecessary(SkCanvas* canvas) { + if (fBenchmark) { return true; } - ++fCurrentPictureIdx; - while (true) { - if (fCurrentPictureIdx >= fRecords.count()) { - return false; - } - if (this->loadPicture()) { - return true; - } - fRecords.removeShuffle(fCurrentPictureIdx); - } -} -bool VisualBench::loadPicture() { - const char* fileName = fRecords[fCurrentPictureIdx].fFilename.c_str(); - SkFILEStream stream(fileName); - if (stream.isValid()) { - fPicture.reset(SkPicture::CreateFromStream(&stream)); - if (SkToBool(fPicture)) { - return true; - } + while ((fBenchmark = fBenchmarkStream->next()) && + (SkCommandLineFlags::ShouldSkip(FLAGS_match, fBenchmark->getUniqueName()) || + !fBenchmark->isSuitableFor(Benchmark::kGPU_Backend))) {} + + if (!fBenchmark) { + return false; } - SkDebugf("couldn't load picture at \"%s\"\n", fileName); - return false; + + canvas->clear(0xffffffff); + fBenchmark->preDraw(); + fBenchmark->perCanvasPreDraw(canvas); + fRecords.push_back(); + return true; } void VisualBench::preWarm(State nextState) { @@ -209,7 +183,7 @@ void VisualBench::preWarm(State nextState) { } void VisualBench::draw(SkCanvas* canvas) { - if (!this->advanceRecordIfNecessary()) { + if (!this->advanceRecordIfNecessary(canvas)) { this->closeWindow(); return; } @@ -251,12 +225,13 @@ void VisualBench::draw(SkCanvas* canvas) { case kTiming_State: { if (fCurrentFrame >= FLAGS_frames) { fTimer.end(); - fRecords[fCurrentPictureIdx].fMeasurements.push_back( + fRecords.back().fMeasurements.push_back( fTimer.fWall / (FLAGS_frames * fLoops * fFlushes)); if (fCurrentSample++ >= FLAGS_samples) { fState = kPreWarmLoops_State; this->printStats(); - fPicture.reset(NULL); + fBenchmark->perCanvasPostDraw(canvas); + fBenchmark = NULL; fCurrentSample = 0; fFlushes = 1; fLoops = 1; diff --git a/tools/VisualBench/VisualBench.h b/tools/VisualBench/VisualBench.h index 332fe82eb4..683151f566 100644 --- a/tools/VisualBench/VisualBench.h +++ b/tools/VisualBench/VisualBench.h @@ -15,6 +15,7 @@ #include "SkString.h" #include "SkSurface.h" #include "Timer.h" +#include "VisualBenchmarkStream.h" #include "gl/SkGLContext.h" class GrContext; @@ -44,12 +45,10 @@ private: void setupRenderTarget(); bool onHandleChar(SkUnichar unichar) override; void printStats(); - bool loadPicture(); - bool advanceRecordIfNecessary(); + bool advanceRecordIfNecessary(SkCanvas*); inline void renderFrame(SkCanvas*); struct Record { - SkString fFilename; SkTArray<double> fMeasurements; }; @@ -61,8 +60,6 @@ private: }; void preWarm(State nextState); - int fCurrentPictureIdx; - SkAutoTUnref<SkPicture> fPicture; int fCurrentSample; int fCurrentFrame; int fFlushes; @@ -70,6 +67,8 @@ private: SkTArray<Record> fRecords; WallTimer fTimer; State fState; + SkAutoTDelete<VisualBenchmarkStream> fBenchmarkStream; + Benchmark* fBenchmark; // support framework SkAutoTUnref<SkSurface> fSurface; diff --git a/tools/VisualBench/VisualBenchmarkStream.cpp b/tools/VisualBench/VisualBenchmarkStream.cpp new file mode 100644 index 0000000000..841fb5d11b --- /dev/null +++ b/tools/VisualBench/VisualBenchmarkStream.cpp @@ -0,0 +1,103 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + */ + +#include <VisualBench/VisualBenchmarkStream.h> +#include "GMBench.h" +#include "SkOSFile.h" +#include "SkPictureRecorder.h" +#include "SkStream.h" +#include "VisualSKPBench.h" + +DEFINE_string2(match, m, NULL, + "[~][^]substring[$] [...] of bench name to run.\n" + "Multiple matches may be separated by spaces.\n" + "~ causes a matching bench to always be skipped\n" + "^ requires the start of the bench to match\n" + "$ requires the end of the bench to match\n" + "^ and $ requires an exact match\n" + "If a bench does not match any list entry,\n" + "it is skipped unless some list entry starts with ~"); +DEFINE_string(skps, "skps", "Directory to read skps from."); + +VisualBenchmarkStream::VisualBenchmarkStream() + : fBenches(BenchRegistry::Head()) + , fGMs(skiagm::GMRegistry::Head()) + , fSourceType(NULL) + , fBenchType(NULL) + , fCurrentSKP(0) { + for (int i = 0; i < FLAGS_skps.count(); i++) { + if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { + fSKPs.push_back() = FLAGS_skps[i]; + } else { + SkOSFile::Iter it(FLAGS_skps[i], ".skp"); + SkString path; + while (it.next(&path)) { + fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str()); + } + } + } +} + +bool VisualBenchmarkStream::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; + } + + SkAutoTDelete<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* VisualBenchmarkStream::next() { + while (fBenches) { + Benchmark* bench = fBenches->factory()(NULL); + fBenches = fBenches->next(); + if (bench->isVisual()) { + fSourceType = "bench"; + fBenchType = "micro"; + return bench; + } + } + + while (fGMs) { + SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(NULL)); + fGMs = fGMs->next(); + if (gm->runAsBench()) { + fSourceType = "gm"; + fBenchType = "micro"; + return SkNEW_ARGS(GMBench, (gm.detach())); + } + } + + // Render skps + while (fCurrentSKP < fSKPs.count()) { + const SkString& path = fSKPs[fCurrentSKP++]; + SkAutoTUnref<SkPicture> pic; + if (!ReadPicture(path.c_str(), &pic)) { + continue; + } + + SkString name = SkOSPath::Basename(path.c_str()); + fSourceType = "skp"; + fBenchType = "playback"; + return SkNEW_ARGS(VisualSKPBench, (name.c_str(), pic.get())); + } + + return NULL; +} diff --git a/tools/VisualBench/VisualBenchmarkStream.h b/tools/VisualBench/VisualBenchmarkStream.h new file mode 100644 index 0000000000..4c6a1eb262 --- /dev/null +++ b/tools/VisualBench/VisualBenchmarkStream.h @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + */ + +#ifndef VisualBenchmarkStream_DEFINED +#define VisualBenchmarkStream_DEFINED + +#include "Benchmark.h" +#include "gm.h" +#include "SkCommandLineFlags.h" +#include "SkPicture.h" + +DECLARE_string(match); + +class VisualBenchmarkStream { +public: + VisualBenchmarkStream(); + + static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic); + + Benchmark* next(); + +private: + const BenchRegistry* fBenches; + const skiagm::GMRegistry* fGMs; + SkTArray<SkString> fSKPs; + + const char* fSourceType; // What we're benching: bench, GM, SKP, ... + const char* fBenchType; // How we bench it: micro, playback, ... + int fCurrentSKP; +}; + +#endif diff --git a/tools/VisualBench/VisualSKPBench.cpp b/tools/VisualBench/VisualSKPBench.cpp new file mode 100644 index 0000000000..9e03d71488 --- /dev/null +++ b/tools/VisualBench/VisualSKPBench.cpp @@ -0,0 +1,33 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + */ + +#include "VisualSKPBench.h" + +VisualSKPBench::VisualSKPBench(const char* name, const SkPicture* pic) + : fPic(SkRef(pic)) + , fName(name) { + fUniqueName.printf("%s", name); +} + +const char* VisualSKPBench::onGetName() { + return fName.c_str(); +} + +const char* VisualSKPBench::onGetUniqueName() { + return fUniqueName.c_str(); +} + +bool VisualSKPBench::isSuitableFor(Backend backend) { + return backend != kNonRendering_Backend; +} + +void VisualSKPBench::onDraw(const int loops, SkCanvas* canvas) { + for (int i = 0; i < loops; i++) { + canvas->drawPicture(fPic); + } +} diff --git a/tools/VisualBench/VisualSKPBench.h b/tools/VisualBench/VisualSKPBench.h new file mode 100644 index 0000000000..cc35deaac5 --- /dev/null +++ b/tools/VisualBench/VisualSKPBench.h @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + */ + +#ifndef VisualSKPBench_DEFINED +#define VisualSKPBench_DEFINED + +#include "Benchmark.h" +#include "SkCanvas.h" +#include "SkPicture.h" + +/** + * Runs an SkPicture as a benchmark by repeatedly drawing it + */ +class VisualSKPBench : public Benchmark { +public: + VisualSKPBench(const char* name, const SkPicture*); + +protected: + const char* onGetName() override; + const char* onGetUniqueName() override; + bool isSuitableFor(Backend backend) override; + void onDraw(const int loops, SkCanvas* canvas) override; + +private: + SkAutoTUnref<const SkPicture> fPic; + SkString fName; + SkString fUniqueName; + + typedef Benchmark INHERITED; +}; + +#endif |