tools: separate TimeUtils from AnimTimer

gm, slides, and samples no longer need to know about the implementation
details of AnimTimer.

This
    virtual bool onAnimate(const AnimTimer&);
becomes this:
    virtual bool onAnimate(double /*nanoseconds*/);
which is much easier to reason about.

AnimTimer itself is now part of viewer.

Change-Id: Ib70bf7a0798b1991f25204ae84f70463cdbeb358
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/226838
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
diff --git a/samplecode/PerlinPatch.cpp b/samplecode/PerlinPatch.cpp
index 49a55ea..eb40048 100644
--- a/samplecode/PerlinPatch.cpp
+++ b/samplecode/PerlinPatch.cpp
@@ -11,7 +11,6 @@
 #include "samplecode/Sample.h"
 #include "src/utils/SkPatchUtils.h"
 #include "tools/ModifierKey.h"
-#include "tools/timer/AnimTimer.h"
 
 static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
     //draw control points
@@ -121,7 +120,7 @@
             return false;
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
+    bool onAnimate(double nanos) override {
         fSeed += 0.005f;
         return true;
     }
diff --git a/samplecode/Sample.h b/samplecode/Sample.h
index 7b511c5..a7c0a39 100644
--- a/samplecode/Sample.h
+++ b/samplecode/Sample.h
@@ -17,7 +17,6 @@
 #include "tools/ModifierKey.h"
 #include "tools/Registry.h"
 
-class AnimTimer;
 class SkCanvas;
 class Sample;
 
@@ -78,7 +77,7 @@
     static void DoClickUp(Click*, int x, int y, ModifierKey modi);
 
     void setBGColor(SkColor color) { fBGColor = color; }
-    bool animate(const AnimTimer& timer) { return this->onAnimate(timer); }
+    bool animate(double nanos) { return this->onAnimate(nanos); }
 
     virtual SkString name() = 0;
 
@@ -94,7 +93,7 @@
 
     virtual void onDrawBackground(SkCanvas*);
     virtual void onDrawContent(SkCanvas*) = 0;
-    virtual bool onAnimate(const AnimTimer&) { return false; }
+    virtual bool onAnimate(double /*nanos*/) { return false; }
     virtual void onOnceBeforeDraw() {}
 
 private:
diff --git a/samplecode/SampleAndroidShadows.cpp b/samplecode/SampleAndroidShadows.cpp
index b5a02a6..3c9c57c 100644
--- a/samplecode/SampleAndroidShadows.cpp
+++ b/samplecode/SampleAndroidShadows.cpp
@@ -17,7 +17,7 @@
 #include "src/core/SkBlurMask.h"
 #include "src/utils/SkUTF.h"
 #include "tools/ToolUtils.h"
-#include "tools/timer/AnimTimer.h"
+#include "tools/timer/TimeUtils.h"
 
 ////////////////////////////////////////////////////////////////////////////
 
@@ -335,11 +335,11 @@
                                lightPos, kLightWidth, .5f);
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        fAnimTranslate = timer.pingPong(30, 0, 125, -125);
-        fAnimAngle = timer.pingPong(15, 0, 0, 20);
+    bool onAnimate(double nanos) override {
+        fAnimTranslate = TimeUtils::PingPong(1e-9 * nanos, 30, 0, 125, -125);
+        fAnimAngle = TimeUtils::PingPong(1e-9 * nanos, 15, 0, 0, 20);
         if (fDoAlphaAnimation) {
-            fAnimAlpha = timer.pingPong(5, 0, 1, 0);
+            fAnimAlpha = TimeUtils::PingPong(1e-9 * nanos, 5, 0, 1, 0);
         }
         return true;
     }
diff --git a/samplecode/SampleAnimBlur.cpp b/samplecode/SampleAnimBlur.cpp
index b53d3a6..178854a 100644
--- a/samplecode/SampleAnimBlur.cpp
+++ b/samplecode/SampleAnimBlur.cpp
@@ -10,7 +10,6 @@
 #include "include/core/SkMaskFilter.h"
 #include "include/utils/SkRandom.h"
 #include "samplecode/Sample.h"
-#include "tools/timer/AnimTimer.h"
 
 SkScalar get_anim_sin(double secs, SkScalar amplitude, SkScalar periodInSec, SkScalar phaseInSec) {
     if (!periodInSec) {
@@ -49,9 +48,9 @@
         }
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        fBlurSigma = get_anim_sin(timer.secs(), 100, 4, 5);
-        fCircleRadius = 3 + get_anim_sin(timer.secs(), 150, 25, 3);
+    bool onAnimate(double nanos) override {
+        fBlurSigma = get_anim_sin(1e-9 * nanos, 100, 4, 5);
+        fCircleRadius = 3 + get_anim_sin(1e-9 * nanos, 150, 25, 3);
         return true;
     }
 
diff --git a/samplecode/SampleAnimatedImage.cpp b/samplecode/SampleAnimatedImage.cpp
index 0a8b5eb..eaa318c 100644
--- a/samplecode/SampleAnimatedImage.cpp
+++ b/samplecode/SampleAnimatedImage.cpp
@@ -14,7 +14,7 @@
 #include "include/core/SkRect.h"
 #include "include/core/SkScalar.h"
 #include "include/core/SkString.h"
-#include "tools/timer/AnimTimer.h"
+#include "tools/timer/TimeUtils.h"
 
 #include "samplecode/Sample.h"
 #include "tools/Resources.h"
@@ -56,13 +56,13 @@
         canvas->drawDrawable(fDrawable.get(), fImage->getBounds().width(), 0);
     }
 
-    bool onAnimate(const AnimTimer& animTimer) override {
+    bool onAnimate(double nanos) override {
         if (!fImage) {
             return false;
         }
 
         const double lastWallTime = fLastWallTime;
-        fLastWallTime = animTimer.msec();
+        fLastWallTime = TimeUtils::NanosToMSec(nanos);
 
         if (fRunning) {
             fCurrentTime += fLastWallTime - lastWallTime;
diff --git a/samplecode/SampleAnimatedText.cpp b/samplecode/SampleAnimatedText.cpp
index 13e81d6..e2e4d8d 100644
--- a/samplecode/SampleAnimatedText.cpp
+++ b/samplecode/SampleAnimatedText.cpp
@@ -123,7 +123,7 @@
         canvas->drawString(modeString, 768.f, 540.f, font, paint);
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
+    bool onAnimate(double nanos) override {
         // We add noise to the scale and rotation animations to
         // keep the font atlas from falling into a steady state
         fRotation += (1.0f + gRand.nextRangeF(-0.1f, 0.1f));
diff --git a/samplecode/SampleArc.cpp b/samplecode/SampleArc.cpp
index ec4e5ae..d6b6170 100644
--- a/samplecode/SampleArc.cpp
+++ b/samplecode/SampleArc.cpp
@@ -22,7 +22,6 @@
 #include "include/utils/SkTextUtils.h"
 #include "samplecode/Sample.h"
 #include "src/utils/SkUTF.h"
-#include "tools/timer/AnimTimer.h"
 
 #include "include/utils/SkParsePath.h"
 static void testparse() {
@@ -181,8 +180,8 @@
         canvas->drawDrawable(fRootDrawable.get());
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        SkScalar angle = SkDoubleToScalar(fmod(timer.secs() * 360 / 24, 360));
+    bool onAnimate(double nanos) override {
+        SkScalar angle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 24, 360));
         if (fAnimatingDrawable) {
             fAnimatingDrawable->setSweep(angle);
         }
diff --git a/samplecode/SampleAtlas.cpp b/samplecode/SampleAtlas.cpp
index 043d3fd..85d267c 100644
--- a/samplecode/SampleAtlas.cpp
+++ b/samplecode/SampleAtlas.cpp
@@ -13,7 +13,6 @@
 #include "include/utils/SkRandom.h"
 #include "include/utils/SkTextUtils.h"
 #include "samplecode/Sample.h"
-#include "tools/timer/AnimTimer.h"
 
 typedef void (*DrawAtlasProc)(SkCanvas*, SkImage*, const SkRSXform[], const SkRect[],
                               const SkColor[], int, const SkRect*, const SkPaint*);
@@ -229,11 +228,11 @@
         canvas->drawDrawable(fDrawable.get());
     }
 
-    bool onAnimate(const AnimTimer&) override { return true; }
+    bool onAnimate(double /*nanos*/) override { return true; }
 #if 0
     // TODO: switch over to use this for our animation
-    bool onAnimate(const AnimTimer& timer) override {
-        SkScalar angle = SkDoubleToScalar(fmod(timer.secs() * 360 / 24, 360));
+    bool onAnimate(double nanos) override {
+        SkScalar angle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 24, 360));
         fAnimatingDrawable->setSweep(angle);
         return true;
     }
diff --git a/samplecode/SampleBitmapRect.cpp b/samplecode/SampleBitmapRect.cpp
index 6bd1a89..8644cb4 100644
--- a/samplecode/SampleBitmapRect.cpp
+++ b/samplecode/SampleBitmapRect.cpp
@@ -19,13 +19,12 @@
 #include "include/effects/SkGradientShader.h"
 #include "samplecode/Sample.h"
 #include "src/utils/SkUTF.h"
-#include "tools/timer/AnimTimer.h"
 
 #include "include/core/SkStream.h"
 #include "src/core/SkOSFile.h"
 
-#define INT_SIZE        64
-#define SCALAR_SIZE     SkIntToScalar(INT_SIZE)
+static constexpr int INT_SIZE = 64;
+static constexpr float SCALAR_SIZE = (float)INT_SIZE;
 
 static void make_bitmap(SkBitmap* bitmap) {
     bitmap->allocN32Pixels(INT_SIZE, INT_SIZE);
@@ -40,11 +39,6 @@
     canvas.drawCircle(SCALAR_SIZE/2, SCALAR_SIZE/2, SCALAR_SIZE/2, paint);
 }
 
-static SkPoint unit_vec(int degrees) {
-    SkScalar rad = SkDegreesToRadians(SkIntToScalar(degrees));
-    return SkPoint::Make(SkScalarCos(rad), SkScalarSin(rad));
-}
-
 static void bounce(SkScalar* value, SkScalar* delta, SkScalar min, SkScalar max) {
     *value += *delta;
     if (*value < min) {
@@ -62,77 +56,43 @@
 }
 
 class BitmapRectView : public Sample {
-    SkPoint fSrcPts[2];
-    SkPoint fSrcVec[2];
-    SkRect  fSrcLimit;
-    SkRect  fDstR[2];
+    SkPoint fSrcPt = {0, 0};
+    SkPoint fSrcVec = {0.866025f, 0.5f};
 
-    void bounce() {
-        bounce_pt(&fSrcPts[0], &fSrcVec[0], fSrcLimit);
-        bounce_pt(&fSrcPts[1], &fSrcVec[1], fSrcLimit);
-    }
+    SkRect  fSrcLimit = {-SCALAR_SIZE/4,  -SCALAR_SIZE/4,
+                          SCALAR_SIZE*5/4, SCALAR_SIZE*5/4};
+    SkRect  fDstR[2] = {{10, 100, 260, 400}, {322.5, 100, 572.5, 400}};
+    SkBitmap fBitmap;
 
-    void resetBounce() {
-        fSrcPts[0].set(0, 0);
-        fSrcPts[1].set(SCALAR_SIZE, SCALAR_SIZE);
-
-        fSrcVec[0] = unit_vec(30);
-        fSrcVec[1] = unit_vec(107);
-    }
-
-public:
-    BitmapRectView() {
-        this->setBGColor(SK_ColorGRAY);
-
-        this->resetBounce();
-
-        fSrcLimit.set(-SCALAR_SIZE/4, -SCALAR_SIZE/4,
-                      SCALAR_SIZE*5/4, SCALAR_SIZE*5/4);
-
-        fDstR[0] = SkRect::MakeXYWH(SkIntToScalar(10), SkIntToScalar(100),
-                                       SkIntToScalar(250), SkIntToScalar(300));
-        fDstR[1] = fDstR[0];
-        fDstR[1].offset(fDstR[0].width() * 5/4, 0);
-
-        fSrcPts[0].set(32, 32);
-        fSrcPts[1].set(90, 90);
-    }
-
-protected:
     SkString name() override { return SkString("BitmapRect"); }
 
+    void onOnceBeforeDraw() override {
+        this->setBGColor(SK_ColorGRAY);
+        make_bitmap(&fBitmap);
+    }
+
     void onDrawContent(SkCanvas* canvas) override {
-        SkRect srcR;
-        srcR.set(fSrcPts[0], fSrcPts[1]);
-        srcR = SkRect::MakeXYWH(fSrcPts[0].fX, fSrcPts[0].fY, 32, 32);
-        srcR.offset(-srcR.width()/2, -srcR.height()/2);
+        SkRect srcR = {fSrcPt.fX - 16, fSrcPt.fY - 16,
+                       fSrcPt.fX + 16, fSrcPt.fY + 16};
 
-        SkPaint paint;
+        SkPaint paint(SkColors::kYellow);
         paint.setStyle(SkPaint::kStroke_Style);
-        paint.setColor(SK_ColorYELLOW);
-
-        SkBitmap bitmap;
-        make_bitmap(&bitmap);
 
         canvas->translate(20, 20);
 
-        canvas->drawBitmap(bitmap, 0, 0, &paint);
+        canvas->drawBitmap(fBitmap, 0, 0, &paint);
         canvas->drawRect(srcR, paint);
 
         for (int i = 0; i < 2; ++i) {
             paint.setFilterQuality(1 == i ? kLow_SkFilterQuality : kNone_SkFilterQuality);
-            canvas->drawBitmapRect(bitmap, srcR, fDstR[i], &paint,
+            canvas->drawBitmapRect(fBitmap, srcR, fDstR[i], &paint,
                                    SkCanvas::kStrict_SrcRectConstraint);
             canvas->drawRect(fDstR[i], paint);
         }
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        if (timer.isStopped()) {
-            this->resetBounce();
-        } else if (timer.isRunning()) {
-            this->bounce();
-        }
+    bool onAnimate(double nanos) override {
+        bounce_pt(&fSrcPt, &fSrcVec, fSrcLimit);
         return true;
     }
 
@@ -142,6 +102,8 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
+static constexpr int BIG_H = 120;
+
 static void make_big_bitmap(SkBitmap* bm) {
     static const char gText[] =
         "We the people, in order to form a more perfect union, establish justice,"
@@ -150,8 +112,6 @@
         " posterity, do ordain and establish this constitution for the United"
         " States of America.";
 
-    const int BIG_H = 120;
-
     SkFont font;
     font.setSize(SkIntToScalar(BIG_H));
 
@@ -167,41 +127,17 @@
 
 class BitmapRectView2 : public Sample {
     SkBitmap fBitmap;
+    SkRect   fSrcR = {0, 0, 3 * BIG_H, BIG_H};
+    SkRect   fLimitR;
+    SkScalar fDX = 1;
+    SkRect   fDstR[2] = {{20, 20, 620, 220}, {20, 270, 620, 470}};
 
-    SkRect  fSrcR;
-    SkRect  fLimitR;
-    SkScalar fDX;
-    SkRect  fDstR[2];
-
-    void bounceMe() {
-        SkScalar width = fSrcR.width();
-        bounce(&fSrcR.fLeft, &fDX, fLimitR.fLeft, fLimitR.fRight - width);
-        fSrcR.fRight = fSrcR.fLeft + width;
-    }
-
-    void resetBounce() {
-        fSrcR.iset(0, 0, fBitmap.height() * 3, fBitmap.height());
-        fDX = SK_Scalar1;
-    }
-
-public:
-    BitmapRectView2() { }
-
-protected:
     SkString name() override { return SkString("BigBitmapRect"); }
 
     void onOnceBeforeDraw() override {
-        make_big_bitmap(&fBitmap);
-
         this->setBGColor(SK_ColorGRAY);
-
-        this->resetBounce();
-
-        fLimitR.iset(0, 0, fBitmap.width(), fBitmap.height());
-
-        fDstR[0] = SkRect::MakeXYWH(20, 20, 600, 200);
-        fDstR[1] = fDstR[0];
-        fDstR[1].offset(0, fDstR[0].height() * 5/4);
+        make_big_bitmap(&fBitmap);
+        fLimitR = SkRect::Make(fBitmap.dimensions());
     }
 
     void onDrawContent(SkCanvas* canvas) override {
@@ -217,17 +153,12 @@
         }
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        if (timer.isStopped()) {
-            this->resetBounce();
-        } else if (timer.isRunning()) {
-            this->bounceMe();
-        }
+    bool onAnimate(double nanos) override {
+        SkScalar width = fSrcR.width();
+        bounce(&fSrcR.fLeft, &fDX, fLimitR.fLeft, fLimitR.fRight - width);
+        fSrcR.fRight = fSrcR.fLeft + width;
         return true;
     }
-
-private:
-    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/samplecode/SampleCamera.cpp b/samplecode/SampleCamera.cpp
index 3ad7455..38201eb 100644
--- a/samplecode/SampleCamera.cpp
+++ b/samplecode/SampleCamera.cpp
@@ -13,7 +13,7 @@
 #include "samplecode/Sample.h"
 #include "src/effects/SkEmbossMaskFilter.h"
 #include "tools/Resources.h"
-#include "tools/timer/AnimTimer.h"
+#include "tools/timer/TimeUtils.h"
 
 namespace {
 class CameraView : public Sample {
@@ -67,12 +67,8 @@
         }
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        if (timer.isStopped()) {
-            fRY = 0;
-        } else {
-            fRY = timer.scaled(90, 360);
-        }
+    bool onAnimate(double nanos) override {
+        fRY = nanos ? TimeUtils::Scaled(1e-9 * nanos, 90, 360) : 0;
         return true;
     }
 };
diff --git a/samplecode/SampleClock.cpp b/samplecode/SampleClock.cpp
index 040efa1..347b2ea 100644
--- a/samplecode/SampleClock.cpp
+++ b/samplecode/SampleClock.cpp
@@ -210,7 +210,7 @@
         canvas->restore();
     }
 
-    bool onAnimate(const AnimTimer&) override { return true; }
+    bool onAnimate(double /*nanos*/) override { return true; }
 
 private:
 
diff --git a/samplecode/SampleCowboy.cpp b/samplecode/SampleCowboy.cpp
index 22b8db4..db60229 100644
--- a/samplecode/SampleCowboy.cpp
+++ b/samplecode/SampleCowboy.cpp
@@ -98,7 +98,7 @@
 
     SkString name() override { return fLabel; }
 
-    bool onAnimate(const AnimTimer& timer) override {
+    bool onAnimate(double nanos) override {
         if (!fDom) {
             return false;
         }
diff --git a/samplecode/SampleCusp.cpp b/samplecode/SampleCusp.cpp
index f8ff078..28b1233 100644
--- a/samplecode/SampleCusp.cpp
+++ b/samplecode/SampleCusp.cpp
@@ -11,7 +11,7 @@
 #include "include/core/SkPath.h"
 #include "samplecode/Sample.h"
 #include "src/core/SkGeometry.h"
-#include "tools/timer/AnimTimer.h"
+#include "tools/timer/TimeUtils.h"
 
 // This draws an animation where every cubic has a cusp, to test drawing a circle
 // at the cusp point. Create a unit square. A cubic with its control points
@@ -165,8 +165,8 @@
         SkDebugf("");
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        curTime = timer.msec();
+    bool onAnimate(double nanos) override {
+        curTime = TimeUtils::NanosToMSec(nanos);
         if (!start) {
             start = curTime;
         }
diff --git a/samplecode/SampleDegenerateTwoPtRadials.cpp b/samplecode/SampleDegenerateTwoPtRadials.cpp
index 2237d49..f26403e 100644
--- a/samplecode/SampleDegenerateTwoPtRadials.cpp
+++ b/samplecode/SampleDegenerateTwoPtRadials.cpp
@@ -10,7 +10,6 @@
 #include "include/core/SkString.h"
 #include "include/effects/SkGradientShader.h"
 #include "samplecode/Sample.h"
-#include "tools/timer/AnimTimer.h"
 
 static void draw_gradient2(SkCanvas* canvas, const SkRect& rect, SkScalar delta) {
     SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorMAGENTA };
@@ -67,8 +66,8 @@
                            SkFont(), SkPaint());
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        fTime = SkDoubleToScalar(timer.secs() / 15);
+    bool onAnimate(double nanos) override {
+        fTime = SkDoubleToScalar(1e-9 * nanos / 15);
         return true;
     }
 
diff --git a/samplecode/SampleFilterQuality.cpp b/samplecode/SampleFilterQuality.cpp
index ac97d52..54fe4af 100644
--- a/samplecode/SampleFilterQuality.cpp
+++ b/samplecode/SampleFilterQuality.cpp
@@ -16,7 +16,7 @@
 #include "include/utils/SkRandom.h"
 #include "samplecode/Sample.h"
 #include "tools/Resources.h"
-#include "tools/timer/AnimTimer.h"
+#include "tools/timer/TimeUtils.h"
 
 static sk_sp<SkSurface> make_surface(SkCanvas* canvas, const SkImageInfo& info) {
     auto surface = canvas->makeSurface(info);
@@ -278,8 +278,8 @@
         canvas->drawString(SkStringPrintf("%.8g", trans[1]     ), textX, 250, font, paint);
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        fCurrTime = timer.msec();
+    bool onAnimate(double nanos) override {
+        fCurrTime = TimeUtils::NanosToMSec(nanos);
         return true;
     }
 
diff --git a/samplecode/SampleFlutterAnimate.cpp b/samplecode/SampleFlutterAnimate.cpp
index 026e521..e3e53e0 100644
--- a/samplecode/SampleFlutterAnimate.cpp
+++ b/samplecode/SampleFlutterAnimate.cpp
@@ -14,7 +14,6 @@
 #include "include/core/SkTypeface.h"
 #include "include/utils/SkRandom.h"
 #include "samplecode/Sample.h"
-#include "tools/timer/AnimTimer.h"
 #include "tools/timer/Timer.h"
 
 #if SK_SUPPORT_GPU
@@ -57,11 +56,11 @@
         }
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        fCurrTime = timer.secs() - fResetTime;
+    bool onAnimate(double nanos) override {
+        fCurrTime = 1e-9 * nanos - fResetTime;
         if (fCurrTime > kDuration) {
             this->initChars();
-            fResetTime = timer.secs();
+            fResetTime = 1e-9 * nanos;
             fCurrTime = 0;
         }
 
diff --git a/samplecode/SampleGlyphTransform.cpp b/samplecode/SampleGlyphTransform.cpp
index 4259ec5..2260a1a 100644
--- a/samplecode/SampleGlyphTransform.cpp
+++ b/samplecode/SampleGlyphTransform.cpp
@@ -12,7 +12,7 @@
 #include "include/core/SkRRect.h"
 #include "include/core/SkTypeface.h"
 #include "include/utils/SkRandom.h"
-#include "tools/timer/AnimTimer.h"
+#include "tools/timer/TimeUtils.h"
 
 #include <cmath>
 
@@ -54,9 +54,9 @@
                                font, paint);
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
+    bool onAnimate(double nanos) override {
         constexpr SkScalar maxt = 100000;
-        double t = timer.pingPong(20, 0, 0, maxt); // d3 t is in milliseconds
+        double t = TimeUtils::PingPong(1e-9 * nanos, 20, 0, 0, maxt); // d3 t is in milliseconds
 
         fTranslate.set(sin(t / 3000) - t * this->width() * 0.7 / maxt, sin(t / 999) / t);
         fScale = 4.5 - std::sqrt(t) / 99;
diff --git a/samplecode/SampleHT.cpp b/samplecode/SampleHT.cpp
index 7483b80..76bb048 100644
--- a/samplecode/SampleHT.cpp
+++ b/samplecode/SampleHT.cpp
@@ -12,7 +12,7 @@
 #include "include/utils/SkRandom.h"
 #include "samplecode/Sample.h"
 #include "src/core/SkPointPriv.h"
-#include "tools/timer/AnimTimer.h"
+#include "tools/timer/TimeUtils.h"
 
 const SkRect gUnitSquare = { -1, -1, 1, 1 };
 
@@ -148,8 +148,8 @@
         canvas->drawDrawable(fRoot.get());
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        fTime = timer.msec();
+    bool onAnimate(double nanos) override {
+        fTime = TimeUtils::NanosToMSec(nanos);
         for (int i = 0; i < N; ++i) {
             fArray[i].fDrawable->setTime(fTime);
         }
diff --git a/samplecode/SampleHairline.cpp b/samplecode/SampleHairline.cpp
index aafa564..df3b376 100644
--- a/samplecode/SampleHairline.cpp
+++ b/samplecode/SampleHairline.cpp
@@ -22,7 +22,6 @@
 #include "include/utils/SkRandom.h"
 #include "samplecode/Sample.h"
 #include "src/utils/SkUTF.h"
-#include "tools/timer/AnimTimer.h"
 
 static SkRandom gRand;
 
@@ -208,7 +207,7 @@
         canvas->drawBitmap(bm2, SkIntToScalar(10), SkIntToScalar(10), nullptr);
     }
 
-    bool onAnimate(const AnimTimer&) override {
+    bool onAnimate(double /*nanos*/) override {
         if (fDoAA) {
             fProcIndex = cycle_hairproc_index(fProcIndex);
             // todo: signal that we want to rebuild our TITLE
diff --git a/samplecode/SampleLayers.cpp b/samplecode/SampleLayers.cpp
index cb981f5..037530c 100644
--- a/samplecode/SampleLayers.cpp
+++ b/samplecode/SampleLayers.cpp
@@ -179,7 +179,6 @@
 #include "include/effects/SkMorphologyImageFilter.h"
 
 #include "tools/Resources.h"
-#include "tools/timer/AnimTimer.h"
 
 class BackdropView : public Sample {
     SkPoint fCenter;
@@ -219,8 +218,8 @@
         canvas->restore();
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        fAngle = SkDoubleToScalar(fmod(timer.secs() * 360 / 5, 360));
+    bool onAnimate(double nanos) override {
+        fAngle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 5, 360));
         return true;
     }
 
diff --git a/samplecode/SampleLighting.cpp b/samplecode/SampleLighting.cpp
index 022e44d..a8bd72e 100644
--- a/samplecode/SampleLighting.cpp
+++ b/samplecode/SampleLighting.cpp
@@ -69,7 +69,7 @@
         return this->INHERITED::onFindClickHandler(x, y, modi);
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
+    bool onAnimate(double nanos) override {
         fLightAngle += 0.015f;
         fColorFactor += 0.01f;
         if (fColorFactor > 1.0f) {
diff --git a/samplecode/SampleLitAtlas.cpp b/samplecode/SampleLitAtlas.cpp
index 94eb070..d43e6d7 100644
--- a/samplecode/SampleLitAtlas.cpp
+++ b/samplecode/SampleLitAtlas.cpp
@@ -14,7 +14,6 @@
 #include "src/shaders/SkBitmapProcShader.h"
 #include "src/shaders/SkLightingShader.h"
 #include "src/shaders/SkLights.h"
-#include "tools/timer/AnimTimer.h"
 
 #include "tools/ToolUtils.h"
 
@@ -476,7 +475,7 @@
         canvas->drawDrawable(fDrawable.get());
     }
 
-    bool onAnimate(const AnimTimer& timer) override { return true; }
+    bool onAnimate(double nanos) override { return true; }
 
 private:
     sk_sp<DrawLitAtlasDrawable> fDrawable;
diff --git a/samplecode/SampleMegaStroke.cpp b/samplecode/SampleMegaStroke.cpp
index 26e9588..0d13b49 100644
--- a/samplecode/SampleMegaStroke.cpp
+++ b/samplecode/SampleMegaStroke.cpp
@@ -69,7 +69,7 @@
         fClip.set(0, 0, 950, 600);
     }
 
-    bool onAnimate(const AnimTimer&) override { return true; }
+    bool onAnimate(double /*nanos*/) override { return true; }
 
 private:
     SkPath      fMegaPath;
diff --git a/samplecode/SamplePatch.cpp b/samplecode/SamplePatch.cpp
index a970400..1ec5a5c 100644
--- a/samplecode/SamplePatch.cpp
+++ b/samplecode/SamplePatch.cpp
@@ -27,7 +27,7 @@
 #include "src/core/SkOSFile.h"
 #include "src/utils/SkUTF.h"
 #include "tools/Resources.h"
-#include "tools/timer/AnimTimer.h"
+#include "tools/timer/TimeUtils.h"
 
 namespace {
 static sk_sp<SkShader> make_shader0(SkIPoint* size) {
@@ -282,8 +282,8 @@
         drawpatches(canvas, paint, nu, nv, &patch);
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        fAngle = timer.scaled(60, 360);
+    bool onAnimate(double nanos) override {
+        fAngle = TimeUtils::Scaled(1e-9 * nanos, 60, 360);
         return true;
     }
 
@@ -379,7 +379,7 @@
 protected:
     SkString name() override { return SkString("PseudoInk"); }
 
-    bool onAnimate(const AnimTimer& timer) override { return true; }
+    bool onAnimate(double nanos) override { return true; }
 
     void onDrawContent(SkCanvas* canvas) override {
         if (fDirty) {
@@ -445,7 +445,7 @@
 protected:
     SkString name() override { return SkString("ManyStrokes"); }
 
-    bool onAnimate(const AnimTimer& timer) override { return true; }
+    bool onAnimate(double nanos) override { return true; }
 
     void dodraw(SkCanvas* canvas, sk_sp<SkPathEffect> pe, SkScalar x, SkScalar y,
                 const SkPaint* ptr = nullptr) {
diff --git a/samplecode/SamplePath.cpp b/samplecode/SamplePath.cpp
index de52fa8..f698613 100644
--- a/samplecode/SamplePath.cpp
+++ b/samplecode/SamplePath.cpp
@@ -20,7 +20,7 @@
 #include "include/utils/SkParsePath.h"
 #include "samplecode/Sample.h"
 #include "src/utils/SkUTF.h"
-#include "tools/timer/AnimTimer.h"
+#include "tools/timer/TimeUtils.h"
 
 #include "src/core/SkGeometry.h"
 
@@ -177,8 +177,8 @@
         }
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        SkScalar currSecs = timer.scaled(100);
+    bool onAnimate(double nanos) override {
+        SkScalar currSecs = TimeUtils::Scaled(1e-9 * nanos, 100);
         SkScalar delta = currSecs - fPrevSecs;
         fPrevSecs = currSecs;
 
diff --git a/samplecode/SamplePathEffects.cpp b/samplecode/SamplePathEffects.cpp
index d501414..4522d93 100644
--- a/samplecode/SamplePathEffects.cpp
+++ b/samplecode/SamplePathEffects.cpp
@@ -17,7 +17,7 @@
 #include "include/utils/SkRandom.h"
 #include "samplecode/Sample.h"
 #include "src/utils/SkUTF.h"
-#include "tools/timer/AnimTimer.h"
+#include "tools/timer/TimeUtils.h"
 
 #define CORNER_RADIUS   12
 
@@ -132,8 +132,8 @@
         canvas->drawPath(fPath, paint);
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        fPhase = timer.scaled(40);
+    bool onAnimate(double nanos) override {
+        fPhase = TimeUtils::Scaled(1e-9 * nanos, 40);
         return true;
     }
 
diff --git a/samplecode/SamplePathText.cpp b/samplecode/SamplePathText.cpp
index c547802..273573a 100644
--- a/samplecode/SamplePathText.cpp
+++ b/samplecode/SamplePathText.cpp
@@ -15,7 +15,6 @@
 #include "src/core/SkStrikeSpec.h"
 #include "src/core/SkTaskGroup.h"
 #include "tools/ToolUtils.h"
-#include "tools/timer/AnimTimer.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Static text from paths.
@@ -164,15 +163,15 @@
         fLastTick = 0;
     }
 
-    bool onAnimate(const AnimTimer& timer) final {
+    bool onAnimate(double nanos) final {
         fBackgroundAnimationTask.wait();
         this->swapAnimationBuffers();
 
-        const double tsec = timer.secs();
-        const double dt = fLastTick ? (timer.secs() - fLastTick) : 0;
+        const double tsec = 1e-9 * nanos;
+        const double dt = fLastTick ? (1e-9 * nanos - fLastTick) : 0;
         fBackgroundAnimationTask.add(std::bind(&MovingPathText::runAnimationTask, this, tsec,
                                                dt, this->width(), this->height()));
-        fLastTick = timer.secs();
+        fLastTick = 1e-9 * nanos;
         return true;
     }
 
diff --git a/samplecode/SampleShadowUtils.cpp b/samplecode/SampleShadowUtils.cpp
index 52d151d..86151c1 100644
--- a/samplecode/SampleShadowUtils.cpp
+++ b/samplecode/SampleShadowUtils.cpp
@@ -17,7 +17,6 @@
 #include "src/core/SkBlurMask.h"
 #include "src/utils/SkUTF.h"
 #include "tools/ToolUtils.h"
-#include "tools/timer/AnimTimer.h"
 
 ////////////////////////////////////////////////////////////////////////////
 
diff --git a/samplecode/SampleShip.cpp b/samplecode/SampleShip.cpp
index 947b1a3..14708e2 100644
--- a/samplecode/SampleShip.cpp
+++ b/samplecode/SampleShip.cpp
@@ -11,7 +11,6 @@
 #include "include/core/SkSurface.h"
 #include "samplecode/Sample.h"
 #include "tools/Resources.h"
-#include "tools/timer/AnimTimer.h"
 #include "tools/timer/Timer.h"
 
 #include <stdio.h>
@@ -150,8 +149,8 @@
 
 #if 0
     // TODO: switch over to use this for our animation
-    bool onAnimate(const AnimTimer& timer) override {
-        SkScalar angle = SkDoubleToScalar(fmod(timer.secs() * 360 / 24, 360));
+    bool onAnimate(double nanos) override {
+        SkScalar angle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 24, 360));
         fAnimatingDrawable->setSweep(angle);
         return true;
     }
diff --git a/samplecode/SampleThinAA.cpp b/samplecode/SampleThinAA.cpp
index ae301e9..92aa202 100644
--- a/samplecode/SampleThinAA.cpp
+++ b/samplecode/SampleThinAA.cpp
@@ -13,7 +13,6 @@
 #include "include/core/SkImage.h"
 #include "include/core/SkPath.h"
 #include "include/core/SkSurface.h"
-#include "tools/timer/AnimTimer.h"
 
 namespace skiagm {
 
@@ -316,8 +315,8 @@
         this->drawShapes(canvas, "SSx64", 4, fSS16);
     }
 
-    bool onAnimate(const AnimTimer& timer) override {
-        SkScalar t = timer.secs();
+    bool onAnimate(double nanos) override {
+        SkScalar t = 1e-9 * nanos;
         SkScalar dt = fLastFrameTime < 0.f ? 0.f : t - fLastFrameTime;
         fLastFrameTime = t;
 
diff --git a/samplecode/SampleXfer.cpp b/samplecode/SampleXfer.cpp
index 6e607f6..1a3854b 100644
--- a/samplecode/SampleXfer.cpp
+++ b/samplecode/SampleXfer.cpp
@@ -15,7 +15,6 @@
 #include "include/utils/SkRandom.h"
 #include "include/utils/SkTextUtils.h"
 #include "samplecode/Sample.h"
-#include "tools/timer/AnimTimer.h"
 
 const SkBlendMode gModes[] = {
     SkBlendMode::kSrcOver,