Change to add zoom animations to nanobench

BUG=skia:

Review URL: https://codereview.chromium.org/1061323003
diff --git a/bench/SKPAnimationBench.cpp b/bench/SKPAnimationBench.cpp
new file mode 100644
index 0000000..24506d8
--- /dev/null
+++ b/bench/SKPAnimationBench.cpp
@@ -0,0 +1,60 @@
+/*
+ * 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 "SKPAnimationBench.h"
+#include "SkCommandLineFlags.h"
+#include "SkMultiPictureDraw.h"
+#include "SkSurface.h"
+
+SKPAnimationBench::SKPAnimationBench(const char* name, const SkPicture* pic,
+                                     const SkIRect& clip, SkMatrix animationMatrix, int steps)
+    : INHERITED(name, pic, clip, 1.0, false)
+    , fSteps(steps)
+    , fAnimationMatrix(animationMatrix)
+    , fName(name) {
+    fUniqueName.printf("%s_animation", name);
+}
+
+const char* SKPAnimationBench::onGetName() {
+    return fName.c_str();
+}
+
+const char* SKPAnimationBench::onGetUniqueName() {
+    return fUniqueName.c_str();
+}
+
+void SKPAnimationBench::onPerCanvasPreDraw(SkCanvas* canvas) {
+    INHERITED::onPerCanvasPreDraw(canvas);
+    SkIRect bounds;
+    SkAssertResult(canvas->getClipDeviceBounds(&bounds));
+
+    fCenter.set((bounds.fRight - bounds.fLeft) / 2.0f,
+                (bounds.fBottom - bounds.fTop) / 2.0f);
+}
+
+void SKPAnimationBench::drawPicture() {
+    SkMatrix frameMatrix = SkMatrix::MakeTrans(-fCenter.fX, -fCenter.fY);
+    frameMatrix.postConcat(fAnimationMatrix);
+    SkMatrix reverseTranslate = SkMatrix::MakeTrans(fCenter.fX, fCenter.fY);
+    frameMatrix.postConcat(reverseTranslate);
+
+    SkMatrix currentMatrix = frameMatrix;
+    for (int i = 0; i < fSteps; i++) {
+        for (int j = 0; j < this->tileRects().count(); ++j) {
+            SkMatrix trans = SkMatrix::MakeTrans(-1.f * this->tileRects()[j].fLeft,
+                                                 -1.f * this->tileRects()[j].fTop);
+            SkMatrix tileMatrix = currentMatrix;
+            tileMatrix.postConcat(trans);
+            this->surfaces()[j]->getCanvas()->drawPicture(this->picture(), &tileMatrix, NULL);
+        }
+
+        for (int j = 0; j < this->tileRects().count(); ++j) {
+           this->surfaces()[j]->getCanvas()->flush();
+        }
+        currentMatrix.postConcat(frameMatrix);
+    }
+}
diff --git a/bench/SKPAnimationBench.h b/bench/SKPAnimationBench.h
new file mode 100644
index 0000000..f6e9fa4
--- /dev/null
+++ b/bench/SKPAnimationBench.h
@@ -0,0 +1,42 @@
+/*
+ * 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 SKPAnimationBench_DEFINED
+#define SKPAnimationBench_DEFINED
+
+#include "SKPBench.h"
+
+/**
+ * Runs an SkPicture as a benchmark by repeatedly drawing it, first centering the picture and
+ * for each step it concats the passed in matrix
+ */
+class SKPAnimationBench : public SKPBench {
+public:
+    SKPAnimationBench(const char* name, const SkPicture*, const SkIRect& devClip,
+                      SkMatrix viewMatrix, int steps);
+
+protected:
+    const char* onGetName() override;
+    const char* onGetUniqueName() override;
+    void onPerCanvasPreDraw(SkCanvas* canvas) override;
+
+    void drawMPDPicture() override {
+        SkFAIL("MPD not supported\n");
+    }
+    void drawPicture() override;
+
+private:
+    int fSteps;
+    SkMatrix fAnimationMatrix;
+    SkString fName;
+    SkString fUniqueName;
+    SkPoint fCenter;
+
+    typedef SKPBench INHERITED;
+};
+
+#endif
diff --git a/bench/SKPBench.cpp b/bench/SKPBench.cpp
index 6f74ff9..592d042 100644
--- a/bench/SKPBench.cpp
+++ b/bench/SKPBench.cpp
@@ -98,32 +98,40 @@
 void SKPBench::onDraw(const int loops, SkCanvas* canvas) {
     if (fUseMultiPictureDraw) {
         for (int i = 0; i < loops; i++) {
-            SkMultiPictureDraw mpd;
-
-            for (int j = 0; j < fTileRects.count(); ++j) {
-                SkMatrix trans;
-                trans.setTranslate(-fTileRects[j].fLeft/fScale,
-                                   -fTileRects[j].fTop/fScale);
-                mpd.add(fSurfaces[j]->getCanvas(), fPic, &trans);
-            }
-
-            mpd.draw();
-
-            for (int j = 0; j < fTileRects.count(); ++j) {
-                fSurfaces[j]->getCanvas()->flush();
-            }
+            this->drawMPDPicture();
         }
     } else {
         for (int i = 0; i < loops; i++) {
-            for (int j = 0; j < fTileRects.count(); ++j) {
-                const SkMatrix trans = SkMatrix::MakeTrans(-fTileRects[j].fLeft / fScale,
-                                                           -fTileRects[j].fTop / fScale);
-                fSurfaces[j]->getCanvas()->drawPicture(fPic, &trans, NULL);
-            }
-
-            for (int j = 0; j < fTileRects.count(); ++j) {
-                fSurfaces[j]->getCanvas()->flush();
-            }
+            this->drawPicture();
         }
     }
 }
+
+void SKPBench::drawMPDPicture() {
+    SkMultiPictureDraw mpd;
+
+    for (int j = 0; j < fTileRects.count(); ++j) {
+        SkMatrix trans;
+        trans.setTranslate(-fTileRects[j].fLeft/fScale,
+                           -fTileRects[j].fTop/fScale);
+        mpd.add(fSurfaces[j]->getCanvas(), fPic, &trans);
+    }
+
+    mpd.draw();
+
+    for (int j = 0; j < fTileRects.count(); ++j) {
+        fSurfaces[j]->getCanvas()->flush();
+    }
+}
+
+void SKPBench::drawPicture() {
+    for (int j = 0; j < fTileRects.count(); ++j) {
+        const SkMatrix trans = SkMatrix::MakeTrans(-fTileRects[j].fLeft / fScale,
+                                                   -fTileRects[j].fTop / fScale);
+        fSurfaces[j]->getCanvas()->drawPicture(fPic, &trans, NULL);
+    }
+
+    for (int j = 0; j < fTileRects.count(); ++j) {
+        fSurfaces[j]->getCanvas()->flush();
+    }
+}
diff --git a/bench/SKPBench.h b/bench/SKPBench.h
index f17281c..3b645e9 100644
--- a/bench/SKPBench.h
+++ b/bench/SKPBench.h
@@ -30,6 +30,13 @@
     void onDraw(const int loops, SkCanvas* canvas) override;
     SkIPoint onGetSize() override;
 
+    virtual void drawMPDPicture();
+    virtual void drawPicture();
+
+    const SkPicture* picture() const { return fPic; }
+    const SkTDArray<SkSurface*>& surfaces() const { return fSurfaces; }
+    const SkTDArray<SkIRect>& tileRects() const { return fTileRects; }
+
 private:
     SkAutoTUnref<const SkPicture> fPic;
     const SkIRect fClip;
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index 0045d53..c33f2c7 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -18,6 +18,7 @@
 #include "ProcStats.h"
 #include "ResultsWriter.h"
 #include "RecordingBench.h"
+#include "SKPAnimationBench.h"
 #include "SKPBench.h"
 #include "Stats.h"
 #include "Timer.h"
@@ -82,6 +83,7 @@
 DEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this.");
 DEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs.");
 DEFINE_string(scales, "1.0", "Space-separated scales for SKPs.");
+DEFINE_string(zoom, "1.0,1", "Comma-separated scale,step zoom factors for SKPs.");
 DEFINE_bool(bbh, true, "Build a BBH for SKPs?");
 DEFINE_bool(mpd, true, "Use MultiPictureDraw for the SKPs?");
 DEFINE_int32(flushEvery, 10, "Flush --outResultsFile every Nth run.");
@@ -491,6 +493,7 @@
                       , fCurrentImage(0)
                       , fCurrentSubsetImage(0)
                       , fCurrentColorType(0)
+                      , fCurrentAnimSKP(0)
                       , fDivisor(2) {
         for (int i = 0; i < FLAGS_skps.count(); i++) {
             if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
@@ -517,6 +520,11 @@
             }
         }
 
+        if (2 != sscanf(FLAGS_zoom[0], "%f,%d", &fZoomScale, &fZoomSteps)) {
+            SkDebugf("Can't parse %s from --zoom as a scale,step.\n", FLAGS_zoom[0]);
+            exit(1);
+        }
+
         fUseMPDs.push_back() = false;
         if (FLAGS_mpd) {
             fUseMPDs.push_back() = true;
@@ -625,8 +633,9 @@
                     fSourceType = "skp";
                     fBenchType = "playback";
                     return SkNEW_ARGS(SKPBench,
-                            (name.c_str(), pic.get(), fClip,
-                             fScales[fCurrentScale], fUseMPDs[fCurrentUseMPD++]));
+                                      (name.c_str(), pic.get(), fClip,
+                                       fScales[fCurrentScale], fUseMPDs[fCurrentUseMPD++]));
+
                 }
                 fCurrentUseMPD = 0;
                 fCurrentSKP++;
@@ -635,6 +644,26 @@
             fCurrentScale++;
         }
 
+        // Now loop over each skp again if we have an animation
+        if (fZoomScale != 1.0f && fZoomSteps != 1) {
+            while (fCurrentAnimSKP < fSKPs.count()) {
+                const SkString& path = fSKPs[fCurrentAnimSKP];
+                SkAutoTUnref<SkPicture> pic;
+                if (!ReadPicture(path.c_str(), &pic)) {
+                    fCurrentAnimSKP++;
+                    continue;
+                }
+
+                fCurrentAnimSKP++;
+                SkString name = SkOSPath::Basename(path.c_str());
+                SkMatrix anim = SkMatrix::I();
+                anim.setScale(fZoomScale, fZoomScale);
+                return SkNEW_ARGS(SKPAnimationBench, (name.c_str(), pic.get(), fClip, anim,
+                                  fZoomSteps));
+            }
+        }
+
+
         for (; fCurrentCodec < fImages.count(); fCurrentCodec++) {
             const SkString& path = fImages[fCurrentCodec];
             SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str()));
@@ -789,6 +818,8 @@
     SkTArray<bool>     fUseMPDs;
     SkTArray<SkString> fImages;
     SkTArray<SkColorType> fColorTypes;
+    SkScalar           fZoomScale;
+    int                fZoomSteps;
 
     double fSKPBytes, fSKPOps;
 
@@ -802,6 +833,7 @@
     int fCurrentImage;
     int fCurrentSubsetImage;
     int fCurrentColorType;
+    int fCurrentAnimSKP;
     const int fDivisor;
 };