allow GMs to animate

BUG=skia:

Review URL: https://codereview.chromium.org/888283002
diff --git a/gm/addarc.cpp b/gm/addarc.cpp
index 209fb59..1386cdd 100644
--- a/gm/addarc.cpp
+++ b/gm/addarc.cpp
@@ -10,6 +10,9 @@
 #include "SkRandom.h"
 
 class AddArcGM : public skiagm::GM {
+public:
+    AddArcGM() : fRotate(0) {}
+
 protected:
     SkString onShortName() SK_OVERRIDE { return SkString("addarc"); }
 
@@ -29,20 +32,30 @@
         const SkScalar sweepAngle = 345;
         SkRandom rand;
 
+        SkScalar sign = 1;
         while (r.width() > paint.getStrokeWidth() * 3) {
             paint.setColor(rand.nextU() | (0xFF << 24));
             SkScalar startAngle = rand.nextUScalar1() * 360;
 
+            SkScalar speed = SkScalarSqrt(16 / r.width()) * 0.5f;
+            startAngle += fRotate * 360 * speed * sign;
+
             SkPath path;
             path.addArc(r, startAngle, sweepAngle);
             canvas->drawPath(path, paint);
 
             r.inset(inset, inset);
-
+            sign = -sign;
         }
     }
 
+    bool onAnimatePulse(SkMSec curr, SkMSec prev) SK_OVERRIDE {
+        fRotate = SkDoubleToScalar(fmod(curr * 0.001, 360));
+        return true;
+    }
+
 private:
+    SkScalar fRotate;
     typedef skiagm::GM INHERITED;
 };
 DEF_GM( return new AddArcGM; )
diff --git a/gm/gm.cpp b/gm/gm.cpp
index 1922284..c8109a7 100644
--- a/gm/gm.cpp
+++ b/gm/gm.cpp
@@ -51,6 +51,12 @@
     fBGColor = color;
 }
 
+bool GM::animatePulse(SkMSec curr, SkMSec prev) {
+    return this->onAnimatePulse(curr, prev);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+
 void GM::onDrawBackground(SkCanvas* canvas) {
     canvas->drawColor(fBGColor, SkXfermode::kSrc_Mode);
 }
@@ -101,3 +107,4 @@
 SkString skiagm::SimpleGM::onShortName() {
     return fName;
 }
+
diff --git a/gm/gm.h b/gm/gm.h
index e6c71a3..c7dca6d 100644
--- a/gm/gm.h
+++ b/gm/gm.h
@@ -92,6 +92,8 @@
             fStarterMatrix = matrix;
         }
 
+        bool animatePulse(SkMSec curr, SkMSec prev);
+
     protected:
         /** draws a standard message that the GM is only intended to be used with the GPU.*/
         void drawGpuOnlyMessage(SkCanvas*);
@@ -101,6 +103,7 @@
         virtual SkISize onISize() = 0;
         virtual SkString onShortName() = 0;
 
+        virtual bool onAnimatePulse(SkMSec curr, SkMSec prev) { return false; }
         virtual SkMatrix onGetInitialTransform() const { return SkMatrix::I(); }
 
     private: