Chromium Code Reviews| Index: tools/VisualBench.cpp |
| diff --git a/tools/VisualBench.cpp b/tools/VisualBench.cpp |
| index 3f8d8036aada0d12fd3bcb370dda2fb2c588ad58..31bc8f3595f39e74f230ad84bf6f3d33c9cf3bbb 100644 |
| --- a/tools/VisualBench.cpp |
| +++ b/tools/VisualBench.cpp |
| @@ -8,6 +8,7 @@ |
| #include "VisualBench.h" |
| +#include "ProcStats.h" |
| #include "SkApplication.h" |
| #include "SkCanvas.h" |
| #include "SkCommandLineFlags.h" |
| @@ -18,35 +19,45 @@ |
| #include "SkImageDecoder.h" |
| #include "SkOSFile.h" |
| #include "SkStream.h" |
| +#include "Stats.h" |
| #include "Timer.h" |
| #include "gl/GrGLInterface.h" |
| __SK_FORCE_IMAGE_DECODER_LINKING; |
| +DEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU allows to lag."); |
| +DEFINE_int32(maxFrames, 20, "Number of times to render each skp."); |
|
robertphillips
2015/06/01 14:26:00
Should maxFrames be repeat or samples ?
joshualitt
2015/06/01 16:16:09
Acknowledged.
|
| +DEFINE_int32(msaa, 0, "Number of msaa samples."); |
| + |
| +static SkString humanize(double ms) { |
|
robertphillips
2015/06/01 14:26:00
add brackets & newlines ?
joshualitt
2015/06/01 16:16:09
Acknowledged.
|
| + if (FLAGS_verbose) return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); |
| + return HumanizeMs(ms); |
| +} |
| + |
| +#define HUMANIZE(time) humanize(time).c_str() |
| + |
| VisualBench::VisualBench(void* hwnd, int argc, char** argv) |
| : INHERITED(hwnd) |
| - , fCurrentLoops(1) |
| , fCurrentPicture(0) |
| , fCurrentFrame(0) { |
| SkCommandLineFlags::Parse(argc, argv); |
| + // load all SKPs |
| SkTArray<SkString> skps; |
| for (int i = 0; i < FLAGS_skps.count(); i++) { |
| if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { |
| skps.push_back() = FLAGS_skps[i]; |
| + fTimings.push_back().fName = FLAGS_skps[i]; |
| } else { |
| SkOSFile::Iter it(FLAGS_skps[i], ".skp"); |
| SkString path; |
| while (it.next(&path)) { |
| skps.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str()); |
| + fTimings.push_back().fName = path.c_str(); |
| } |
| } |
| } |
| - this->setTitle(); |
| - this->setupBackend(); |
| - |
| - // Load picture for playback |
| for (int i = 0; i < skps.count(); i++) { |
| SkFILEStream stream(skps[i].c_str()); |
| if (stream.isValid()) { |
| @@ -55,6 +66,13 @@ VisualBench::VisualBench(void* hwnd, int argc, char** argv) |
| SkDebugf("couldn't load picture at \"path\"\n", skps[i].c_str()); |
| } |
| } |
| + |
| + if (fPictures.empty()) { |
| + SkDebugf("no valid skps found\n"); |
| + } |
| + |
| + this->setTitle(); |
| + this->setupBackend(); |
| } |
| VisualBench::~VisualBench() { |
| @@ -79,7 +97,7 @@ bool VisualBench::setupBackend() { |
| this->setVisibleP(true); |
| this->setClipToBounds(false); |
| - if (!this->attach(kNativeGL_BackEndType, 0 /*msaa*/, &fAttachmentInfo)) { |
| + if (!this->attach(kNativeGL_BackEndType, FLAGS_msaa, &fAttachmentInfo)) { |
| SkDebugf("Not possible to create backend.\n"); |
| INHERITED::detach(); |
| return false; |
| @@ -87,7 +105,11 @@ bool VisualBench::setupBackend() { |
| this->setFullscreen(true); |
| this->setVsync(false); |
| + this->resetContext(); |
| + return true; |
| +} |
| +void VisualBench::resetContext() { |
| fInterface.reset(GrGLCreateNativeInterface()); |
| SkASSERT(fInterface); |
| @@ -97,26 +119,62 @@ bool VisualBench::setupBackend() { |
| // setup rendertargets |
| this->setupRenderTarget(); |
| - return true; |
| } |
| void VisualBench::setupRenderTarget() { |
| fRenderTarget.reset(this->renderTarget(fAttachmentInfo, fInterface, fContext)); |
| } |
| -void VisualBench::draw(SkCanvas* canvas) { |
| - fCurrentFrame++; |
| +void VisualBench::timeFrame(SkCanvas* canvas) { |
| WallTimer timer; |
|
bsalomon
2015/06/01 13:49:54
I think you should time outside the loop
joshualitt
2015/06/01 16:16:09
Acknowledged.
|
| timer.start(); |
| - for (int i = 0; i < fCurrentLoops; i++) { |
| - canvas->drawPicture(fPictures[fCurrentPicture]); |
| - } |
| + canvas->drawPicture(fPictures[fCurrentPicture]); |
| // in case we have queued drawing calls |
| fContext->flush(); |
| INHERITED::present(); |
| timer.end(); |
| + if (fCurrentFrame > FLAGS_gpuFrameLag) { |
| + fTimings[fCurrentPicture].fMeasurements.push_back(timer.fWall); |
| + } |
| +} |
| - SkDebugf("%s\n", HumanizeMs(timer.fWall).c_str()); |
| +void VisualBench::printStats() { |
| + const SkTArray<double>& measurements = fTimings[fCurrentPicture].fMeasurements; |
| + if (FLAGS_verbose) { |
| + for (int i = 0; i < measurements.count(); i++) { |
| + SkDebugf("%s ", HUMANIZE(measurements[i])); |
| + } |
| + SkDebugf("%s\n", fTimings[fCurrentPicture].fName.c_str()); |
| + } else { |
| + SkASSERT(measurements.count()); |
| + Stats stats(measurements.begin(), measurements.count()); |
|
robertphillips
2015/06/01 14:31:07
stdDevPercent ?
joshualitt
2015/06/01 16:16:09
Acknowledged.
|
| + const double stddev_percent = 100 * sqrt(stats.var) / stats.mean; |
| + SkDebugf("%4d/%-4dMB\t%s\t%s\t%s\t%s\t%.0f%%\t%s\n" |
|
robertphillips
2015/06/01 14:26:00
I think we only do the "lead-with-," thing for cto
joshualitt
2015/06/01 16:16:09
Acknowledged.
|
| + , sk_tools::getCurrResidentSetSizeMB() |
| + , sk_tools::getMaxResidentSetSizeMB() |
|
robertphillips
2015/06/01 14:31:07
This probably isn't yours but why isn't this fMin
joshualitt
2015/06/01 16:16:09
no idea, might be Mike Klein's code.
|
| + , HUMANIZE(stats.min) |
| + , HUMANIZE(stats.median) |
| + , HUMANIZE(stats.mean) |
| + , HUMANIZE(stats.max) |
| + , stddev_percent |
| + , fTimings[fCurrentPicture].fName.c_str() |
| + ); |
| + } |
| +} |
| + |
| +void VisualBench::draw(SkCanvas* canvas) { |
| + if (fCurrentPicture < fPictures.count()) { |
| + if (fCurrentFrame++ < FLAGS_maxFrames) { |
| + this->timeFrame(canvas); |
| + } else { |
| + this->printStats(); |
| + fCurrentPicture++; |
| + fCurrentFrame = 0; |
| + this->resetContext(); |
| + } |
| + } else { |
| + this->closeWindow(); |
| + } |
| // Invalidate the window to force a redraw. Poor man's animation mechanism. |
| this->inval(NULL); |