Add NVPR to VisualBench

BUG=skia:

Review URL: https://codereview.chromium.org/1409603004
diff --git a/tools/VisualBench/CpuWrappedBenchmark.h b/tools/VisualBench/CpuWrappedBenchmark.h
deleted file mode 100644
index 214ed00..0000000
--- a/tools/VisualBench/CpuWrappedBenchmark.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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 CpuWrappedBenchmark_DEFINED
-#define CpuWrappedBenchmark_DEFINED
-
-#include "Benchmark.h"
-#include "SkSurface.h"
-
-class CpuWrappedBenchmark : public Benchmark {
-public:
-    // Takes ownership of caller's ref on `bench`.
-    explicit CpuWrappedBenchmark(Benchmark* bench) : fBench(bench) {}
-
-    const char* onGetName()       override { return fBench->getName(); }
-    const char* onGetUniqueName() override { return fBench->getUniqueName(); }
-
-    void onDelayedSetup() override { fBench->delayedSetup(); }
-    void onPerCanvasPreDraw(SkCanvas* canvas) override { fBench->perCanvasPreDraw(canvas); }
-    void onPreDraw(SkCanvas* canvas) override { fBench->preDraw(canvas); }
-    void onPostDraw(SkCanvas* canvas) override { fBench->postDraw(canvas); }
-    void onPerCanvasPostDraw(SkCanvas* canvas) override { fBench->perCanvasPostDraw(canvas); }
-
-    void onDraw(int loops, SkCanvas* canvas) override {
-        // TODO: use onPreDraw() to move offscreen allocation/deallocation out of timing.
-        SkAutoTUnref<SkSurface> offscreen(SkSurface::NewRaster(canvas->imageInfo()));
-
-        fBench->draw(loops, offscreen->getCanvas());
-        SkAutoTUnref<SkImage> image(offscreen->newImageSnapshot());
-        canvas->drawImage(image, 0,0);
-    }
-
-    virtual SkIPoint onGetSize() override { return fBench->getSize(); }
-
-private:
-    SkAutoTUnref<Benchmark> fBench;
-};
-
-#endif//CpuWrappedBenchmark_DEFINED
diff --git a/tools/VisualBench/VisualBench.cpp b/tools/VisualBench/VisualBench.cpp
index 39d2491..9cc2ec1 100644
--- a/tools/VisualBench/VisualBench.cpp
+++ b/tools/VisualBench/VisualBench.cpp
@@ -84,8 +84,10 @@
 
     fInterface.reset(GrGLCreateNativeInterface());
 
-    // TODO use the GLContext creation factories
-    fInterface.reset(GrGLInterfaceRemoveNVPR(fInterface));
+    // TODO use the GLContext creation factories and also set this all up in configs
+    if (!FLAGS_nvpr) {
+        fInterface.reset(GrGLInterfaceRemoveNVPR(fInterface));
+    }
     SkASSERT(fInterface);
 
     // setup contexts
diff --git a/tools/VisualBench/VisualBenchmarkStream.cpp b/tools/VisualBench/VisualBenchmarkStream.cpp
index 235200a..906aab2 100644
--- a/tools/VisualBench/VisualBenchmarkStream.cpp
+++ b/tools/VisualBench/VisualBenchmarkStream.cpp
@@ -7,13 +7,14 @@
  */
 
 #include <VisualBench/VisualBenchmarkStream.h>
-#include "CpuWrappedBenchmark.h"
+#include <VisualBench/WrappedBenchmark.h>
 #include "GMBench.h"
 #include "SkOSFile.h"
 #include "SkPath.h"
 #include "SkPictureRecorder.h"
 #include "SkStream.h"
 #include "sk_tool_utils.h"
+#include "VisualFlags.h"
 #include "VisualSKPBench.h"
 
 DEFINE_bool(cpu, false, "Run in CPU mode?");
@@ -115,8 +116,12 @@
             bench->unref();
         }
     }
+
+    // TODO move this all to --config
     if (bench && FLAGS_cpu) {
         bench = new CpuWrappedBenchmark(bench);
+    } else if (bench && FLAGS_nvpr) {
+        bench = new NvprWrappedBenchmark(bench, 4);
     }
 
     fBenchmark.reset(bench);
diff --git a/tools/VisualBench/VisualFlags.cpp b/tools/VisualBench/VisualFlags.cpp
index 80435ca..2b0e549 100644
--- a/tools/VisualBench/VisualFlags.cpp
+++ b/tools/VisualBench/VisualFlags.cpp
@@ -8,3 +8,4 @@
 #include "VisualFlags.h"
 
 DEFINE_int32(msaa, 0, "Number of msaa samples.");
+DEFINE_bool(nvpr, false, "Run in NVPR mode?");
diff --git a/tools/VisualBench/VisualFlags.h b/tools/VisualBench/VisualFlags.h
index cd13e8e..ad3bdea 100644
--- a/tools/VisualBench/VisualFlags.h
+++ b/tools/VisualBench/VisualFlags.h
@@ -10,6 +10,8 @@
 
 #include "SkCommandLineFlags.h"
 
+DECLARE_string(config);
 DECLARE_int32(msaa);
+DECLARE_bool(nvpr);
 
 #endif
diff --git a/tools/VisualBench/WrappedBenchmark.h b/tools/VisualBench/WrappedBenchmark.h
new file mode 100644
index 0000000..6fac145
--- /dev/null
+++ b/tools/VisualBench/WrappedBenchmark.h
@@ -0,0 +1,91 @@
+/*
+ * 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 WrappedBenchmark_DEFINED
+#define WrappedBenchmark_DEFINED
+
+#include "Benchmark.h"
+#include "SkSurface.h"
+
+// Wrap some other benchmark to allow specialization to either
+// cpu or gpu backends. The derived class will override 'setupOffScreen'
+// to create an offscreen surface in which the actual rendering will occur.
+class WrappedBenchmark : public Benchmark {
+public:
+    // Takes ownership of caller's ref on `bench`.
+    explicit WrappedBenchmark(Benchmark* bench) : fBench(bench) {}
+
+    const char* onGetName()       override { return fBench->getName(); }
+    const char* onGetUniqueName() override { return fBench->getUniqueName(); }
+
+    void onDelayedSetup() override { fBench->delayedSetup(); }
+    void onPerCanvasPreDraw(SkCanvas* canvas) override {
+        fOffScreen.reset(this->setupOffScreen(canvas));
+        fBench->perCanvasPreDraw(fOffScreen->getCanvas());
+    }
+    void onPreDraw(SkCanvas* canvas) override {
+        SkASSERT(fOffScreen.get());
+        fBench->preDraw(fOffScreen->getCanvas());
+    }
+    void onPostDraw(SkCanvas* canvas) override {
+        SkASSERT(fOffScreen.get());
+        fBench->postDraw(fOffScreen->getCanvas());
+    }
+    void onPerCanvasPostDraw(SkCanvas* canvas) override {
+        SkASSERT(fOffScreen.get());
+        fBench->perCanvasPostDraw(fOffScreen->getCanvas());
+    }
+
+    void onDraw(int loops, SkCanvas* canvas) override {
+        SkASSERT(fOffScreen.get());
+        fBench->draw(loops, fOffScreen->getCanvas());
+        SkAutoTUnref<SkImage> image(fOffScreen->newImageSnapshot());
+        canvas->drawImage(image, 0,0);
+    }
+
+    virtual SkIPoint onGetSize() override { return fBench->getSize(); }
+
+private:
+    virtual SkSurface* setupOffScreen(SkCanvas*)=0;
+
+    SkAutoTUnref<SkSurface> fOffScreen;
+    SkAutoTUnref<Benchmark> fBench;
+};
+
+// Create a raster surface for off screen rendering
+class CpuWrappedBenchmark : public WrappedBenchmark {
+public:
+    explicit CpuWrappedBenchmark(Benchmark* bench) : INHERITED(bench) {}
+
+private:
+    SkSurface* setupOffScreen(SkCanvas* canvas) override {
+        return SkSurface::NewRaster(canvas->imageInfo());
+    }
+
+    typedef WrappedBenchmark INHERITED;
+};
+
+// Create an MSAA & NVPR-enabled GPU backend
+class NvprWrappedBenchmark : public WrappedBenchmark {
+public:
+    explicit NvprWrappedBenchmark(Benchmark* bench, int numSamples)
+        : INHERITED(bench)
+        , fNumSamples(numSamples) {}
+
+private:
+    SkSurface* setupOffScreen(SkCanvas* canvas) override {
+        return SkSurface::NewRenderTarget(canvas->getGrContext(),
+                                          SkSurface::kNo_Budgeted,
+                                          canvas->imageInfo(),
+                                          fNumSamples);
+    }
+
+    int fNumSamples;
+    typedef WrappedBenchmark INHERITED;
+};
+
+#endif //WrappedBenchmark_DEFINED