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

Unified Diff: tools/VisualBench/TimingStateMachine.cpp

Issue 1375363003: Factor out VisualBench timing code into a helper class (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: feedback inc Created 5 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/VisualBench/TimingStateMachine.h ('k') | tools/VisualBench/VisualBenchmarkStream.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/VisualBench/TimingStateMachine.cpp
diff --git a/tools/VisualBench/TimingStateMachine.cpp b/tools/VisualBench/TimingStateMachine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c7f2f134709ea9fda4a4c171b28951989e073c0d
--- /dev/null
+++ b/tools/VisualBench/TimingStateMachine.cpp
@@ -0,0 +1,122 @@
+/*
+ * 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 "TimingStateMachine.h"
+
+#include "SkCanvas.h"
+#include "SkCommandLineFlags.h"
+
+DEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU is allowed to lag.");
+DEFINE_int32(frames, 5, "Number of frames of each skp to render per sample.");
+DEFINE_double(loopMs, 5, "Each benchmark will be tuned until it takes loopsMs millseconds.");
+
+TimingStateMachine::TimingStateMachine()
+ : fCurrentFrame(0)
+ , fLoops(1)
+ , fLastMeasurement(0.)
+ , fState(kPreWarmLoopsPerCanvasPreDraw_State) {
+}
+
+TimingStateMachine::ParentEvents TimingStateMachine::nextFrame(SkCanvas* canvas,
+ Benchmark* benchmark) {
+ switch (fState) {
+ case kPreWarmLoopsPerCanvasPreDraw_State:
+ return this->perCanvasPreDraw(canvas, benchmark, kPreWarmLoops_State);
+ case kPreWarmLoops_State:
+ return this->preWarm(kTuneLoops_State);
+ case kTuneLoops_State:
+ return this->tuneLoops();
+ case kPreWarmTimingPerCanvasPreDraw_State:
+ return this->perCanvasPreDraw(canvas, benchmark, kPreWarmTiming_State);
+ case kPreWarmTiming_State:
+ return this->preWarm(kTiming_State);
+ case kTiming_State:
+ return this->timing(canvas, benchmark);
+ }
+ SkFAIL("Incomplete switch\n");
+ return kTiming_ParentEvents;
+}
+
+inline void TimingStateMachine::nextState(State nextState) {
+ fState = nextState;
+}
+
+TimingStateMachine::ParentEvents TimingStateMachine::perCanvasPreDraw(SkCanvas* canvas,
+ Benchmark* benchmark,
+ State nextState) {
+ benchmark->perCanvasPreDraw(canvas);
+ benchmark->preDraw(canvas);
+ fCurrentFrame = 0;
+ this->nextState(nextState);
+ return kTiming_ParentEvents;
+}
+
+TimingStateMachine::ParentEvents TimingStateMachine::preWarm(State nextState) {
+ if (fCurrentFrame >= FLAGS_gpuFrameLag) {
+ // we currently time across all frames to make sure we capture all GPU work
+ this->nextState(nextState);
+ fCurrentFrame = 0;
+ fTimer.start();
+ } else {
+ fCurrentFrame++;
+ }
+ return kTiming_ParentEvents;
+}
+
+inline double TimingStateMachine::elapsed() {
+ fTimer.end();
+ return fTimer.fWall;
+}
+
+void TimingStateMachine::resetTimingState() {
+ fCurrentFrame = 0;
+ fTimer = WallTimer();
+}
+
+inline TimingStateMachine::ParentEvents TimingStateMachine::tuneLoops() {
+ if (1 << 30 == fLoops) {
+ // We're about to wrap. Something's wrong with the bench.
+ SkDebugf("InnerLoops wrapped\n");
+ fLoops = 1;
+ return kTiming_ParentEvents;
+ } else {
+ double elapsedMs = this->elapsed();
+ if (elapsedMs > FLAGS_loopMs) {
+ this->nextState(kPreWarmTimingPerCanvasPreDraw_State);
+ } else {
+ fLoops *= 2;
+ this->nextState(kPreWarmLoops_State);
+ }
+ this->resetTimingState();
+ return kReset_ParentEvents;
+ }
+}
+
+void TimingStateMachine::recordMeasurement() {
+ fLastMeasurement = this->elapsed() / (FLAGS_frames * fLoops);
+}
+
+void TimingStateMachine::nextBenchmark(SkCanvas* canvas, Benchmark* benchmark) {
+ benchmark->postDraw(canvas);
+ benchmark->perCanvasPostDraw(canvas);
+ fLoops = 1;
+ this->nextState(kPreWarmLoopsPerCanvasPreDraw_State);
+}
+
+inline TimingStateMachine::ParentEvents TimingStateMachine::timing(SkCanvas* canvas,
+ Benchmark* benchmark) {
+ if (fCurrentFrame >= FLAGS_frames) {
+ this->recordMeasurement();
+ this->resetTimingState();
+ this->nextState(kPreWarmTimingPerCanvasPreDraw_State);
+ return kTimingFinished_ParentEvents;
+ } else {
+ fCurrentFrame++;
+ return kTiming_ParentEvents;
+ }
+}
+
« no previous file with comments | « tools/VisualBench/TimingStateMachine.h ('k') | tools/VisualBench/VisualBenchmarkStream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698