move visual bench interactive module to timing state machine

BUG=skia:

Review URL: https://codereview.chromium.org/1382883003
diff --git a/tools/VisualBench/VisualInteractiveModule.cpp b/tools/VisualBench/VisualInteractiveModule.cpp
index af922a9..f41bcae 100755
--- a/tools/VisualBench/VisualInteractiveModule.cpp
+++ b/tools/VisualBench/VisualInteractiveModule.cpp
@@ -23,16 +23,10 @@
 
 __SK_FORCE_IMAGE_DECODER_LINKING;
 
-static const int kGpuFrameLag = 5;
-static const int kFrames = 5;
-static const double kLoopMs = 5;
-
 VisualInteractiveModule::VisualInteractiveModule(VisualBench* owner)
     : fCurrentMeasurement(0)
-    , fCurrentFrame(0)
-    , fLoops(1)
-    , fState(kPreWarmLoops_State)
     , fBenchmark(nullptr)
+    , fAdvance(false)
     , fOwner(SkRef(owner)) {
     fBenchmarkStream.reset(new VisualBenchmarkStream);
 
@@ -40,7 +34,7 @@
 }
 
 inline void VisualInteractiveModule::renderFrame(SkCanvas* canvas) {
-    fBenchmark->draw(fLoops, canvas);
+    fBenchmark->draw(fTSM.loops(), canvas);
     this->drawStats(canvas);
     canvas->flush();
     fOwner->present();
@@ -102,7 +96,8 @@
 
     return true;
 }
-
+#include "GrGpu.h"
+#include "GrResourceCache.h"
 void VisualInteractiveModule::draw(SkCanvas* canvas) {
     if (!this->advanceRecordIfNecessary(canvas)) {
         SkDebugf("Exiting VisualBench successfully\n");
@@ -110,123 +105,34 @@
         return;
     }
     this->renderFrame(canvas);
-    switch (fState) {
-        case kPreWarmLoopsPerCanvasPreDraw_State: {
-            this->perCanvasPreDraw(canvas, kPreWarmLoops_State);
+    TimingStateMachine::ParentEvents event = fTSM.nextFrame(canvas, fBenchmark);
+    switch (event) {
+        case TimingStateMachine::kReset_ParentEvents:
+            fOwner->reset();
             break;
-        }
-        case kPreWarmLoops_State: {
-            this->preWarm(kTuneLoops_State);
+        case TimingStateMachine::kTiming_ParentEvents:
             break;
-        }
-        case kTuneLoops_State: {
-            this->tuneLoops(canvas);
+        case TimingStateMachine::kTimingFinished_ParentEvents:
+            // Record measurements
+            fMeasurements[fCurrentMeasurement++] = fTSM.lastMeasurement();
+            fCurrentMeasurement &= (kMeasurementCount-1);  // fast mod
+            SkASSERT(fCurrentMeasurement < kMeasurementCount);
+            this->drawStats(canvas);
+            if (fAdvance) {
+                fAdvance = false;
+                fTSM.nextBenchmark(canvas, fBenchmark);
+                fBenchmark.reset(nullptr);
+                fOwner->reset();
+            } else {
+                fTSM.nextSample();
+            }
             break;
-        }
-        case kPreTiming_State: {
-            fBenchmark->perCanvasPreDraw(canvas);
-            fBenchmark->preDraw(canvas);
-            fCurrentFrame = 0;
-            fTimer.start();
-            fState = kTiming_State;
-            // fall to next state
-        }
-        case kTiming_State: {
-            this->timing(canvas);
-            break;
-        }
-        case kAdvance_State: {
-            this->postDraw(canvas);
-            this->nextState(kPreWarmLoopsPerCanvasPreDraw_State);
-            break;
-        }
-    }
-}
-
-inline void VisualInteractiveModule::nextState(State nextState) {
-    fState = nextState;
-}
-
-void VisualInteractiveModule::perCanvasPreDraw(SkCanvas* canvas, State nextState) {
-    fBenchmark->perCanvasPreDraw(canvas);
-    fBenchmark->preDraw(canvas);
-    fCurrentFrame = 0;
-    this->nextState(nextState);
-}
-
-void VisualInteractiveModule::preWarm(State nextState) {
-    if (fCurrentFrame >= kGpuFrameLag) {
-        // we currently time across all frames to make sure we capture all GPU work
-        this->nextState(nextState);
-        fCurrentFrame = 0;
-        fTimer.start();
-    } else {
-        fCurrentFrame++;
-    }
-}
-
-inline double VisualInteractiveModule::elapsed() {
-    fTimer.end();
-    return fTimer.fWall;
-}
-
-void VisualInteractiveModule::resetTimingState() {
-    fCurrentFrame = 0;
-    fTimer = WallTimer();
-    fOwner->reset();
-}
-
-void VisualInteractiveModule::scaleLoops(double elapsedMs) {
-    // Scale back the number of loops
-    fLoops = (int)ceil(fLoops * kLoopMs / elapsedMs);
-}
-
-inline void VisualInteractiveModule::tuneLoops(SkCanvas* canvas) {
-    if (1 << 30 == fLoops) {
-        // We're about to wrap.  Something's wrong with the bench.
-        SkDebugf("InnerLoops wrapped\n");
-        fLoops = 0;
-    } else {
-        double elapsedMs = this->elapsed();
-        if (elapsedMs > kLoopMs) {
-            this->scaleLoops(elapsedMs);
-            fBenchmark->perCanvasPostDraw(canvas);
-            this->nextState(kPreTiming_State);
-        } else {
-            fLoops *= 2;
-            this->nextState(kPreWarmLoops_State);
-        }
-        this->resetTimingState();
-    }
-}
-
-void VisualInteractiveModule::recordMeasurement() {
-    double measurement = this->elapsed() / (kFrames * fLoops);
-    fMeasurements[fCurrentMeasurement++] = measurement;
-    fCurrentMeasurement &= (kMeasurementCount-1);  // fast mod
-    SkASSERT(fCurrentMeasurement < kMeasurementCount);
-}
-
-void VisualInteractiveModule::postDraw(SkCanvas* canvas) {
-    fBenchmark->postDraw(canvas);
-    fBenchmark->perCanvasPostDraw(canvas);
-    fBenchmark.reset(nullptr);
-    fLoops = 1;
-}
-
-inline void VisualInteractiveModule::timing(SkCanvas* canvas) {
-    if (fCurrentFrame >= kFrames) {
-        this->recordMeasurement();
-        fTimer.start();
-        fCurrentFrame = 0;
-    } else {
-        fCurrentFrame++;
     }
 }
 
 bool VisualInteractiveModule::onHandleChar(SkUnichar c) {
     if (' ' == c) {
-        this->nextState(kAdvance_State);
+        fAdvance = true;
     }
 
     return true;