diff --git a/third_party/skia/samplecode/PerlinPatch.cpp b/third_party/skia/samplecode/PerlinPatch.cpp
deleted file mode 100644
index 43dce62..0000000
--- a/third_party/skia/samplecode/PerlinPatch.cpp
+++ /dev/null
@@ -1,209 +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.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/effects/SkGradientShader.h"
-#include "include/effects/SkPerlinNoiseShader.h"
-#include "samplecode/Sample.h"
-#include "src/utils/SkPatchUtils.h"
-#include "tools/skui/ModifierKey.h"
-
-static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
-    //draw control points
-    SkPaint paint;
-    SkPoint bottom[SkPatchUtils::kNumPtsCubic];
-    SkPatchUtils::GetBottomCubic(cubics, bottom);
-    SkPoint top[SkPatchUtils::kNumPtsCubic];
-    SkPatchUtils::GetTopCubic(cubics, top);
-    SkPoint left[SkPatchUtils::kNumPtsCubic];
-    SkPatchUtils::GetLeftCubic(cubics, left);
-    SkPoint right[SkPatchUtils::kNumPtsCubic];
-    SkPatchUtils::GetRightCubic(cubics, right);
-
-    paint.setColor(SK_ColorBLACK);
-    paint.setStrokeWidth(0.5f);
-    SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] };
-    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint);
-    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom + 1, paint);
-    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint);
-    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint);
-    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint);
-
-    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top + 1, paint);
-    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left + 1, paint);
-    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right + 1, paint);
-
-    paint.setStrokeWidth(2);
-
-    paint.setColor(SK_ColorRED);
-    canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint);
-
-    paint.setColor(SK_ColorBLUE);
-    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom + 1, paint);
-
-    paint.setColor(SK_ColorCYAN);
-    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top + 1, paint);
-
-    paint.setColor(SK_ColorYELLOW);
-    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left + 1, paint);
-
-    paint.setColor(SK_ColorGREEN);
-    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right + 1, paint);
-}
-
-// These are actually half the total width and hieghts
-const SkScalar TexWidth = 100.0f;
-const SkScalar TexHeight = 100.0f;
-
-class PerlinPatchView : public Sample {
-    sk_sp<SkShader> fShader0;
-    sk_sp<SkShader> fShader1;
-    sk_sp<SkShader> fShaderCompose;
-    SkScalar fXFreq;
-    SkScalar fYFreq;
-    SkScalar fSeed;
-    SkPoint  fPts[SkPatchUtils::kNumCtrlPts];
-    SkScalar fTexX;
-    SkScalar fTexY;
-    SkScalar fTexScale;
-    SkMatrix fInvMatrix;
-    bool     fShowGrid = false;
-
-public:
-    PerlinPatchView() : fXFreq(0.025f), fYFreq(0.025f), fSeed(0.0f),
-                        fTexX(100.0), fTexY(50.0), fTexScale(1.0f) {
-        const SkScalar s = 2;
-        // The order of the colors and points is clockwise starting at upper-left corner.
-        //top points
-        fPts[0].set(100 * s, 100 * s);
-        fPts[1].set(150 * s, 50 * s);
-        fPts[2].set(250 * s, 150 * s);
-        fPts[3].set(300 * s, 100 * s);
-        //right points
-        fPts[4].set(275 * s, 150 * s);
-        fPts[5].set(350 * s, 250 * s);
-        //bottom points
-        fPts[6].set(300 * s, 300 * s);
-        fPts[7].set(250 * s, 250 * s);
-        //left points
-        fPts[8].set(150 * s, 350 * s);
-        fPts[9].set(100 * s, 300 * s);
-        fPts[10].set(50 * s, 250 * s);
-        fPts[11].set(150 * s, 150 * s);
-
-        const SkColor colors[SkPatchUtils::kNumCorners] = {
-            0xFF5555FF, 0xFF8888FF, 0xFFCCCCFF
-        };
-        const SkPoint points[2] = { SkPoint::Make(0.0f, 0.0f),
-                                    SkPoint::Make(100.0f, 100.0f) };
-        fShader0 = SkGradientShader::MakeLinear(points,
-                                                  colors,
-                                                  nullptr,
-                                                  3,
-                                                  SkTileMode::kMirror,
-                                                  0,
-                                                  nullptr);
-    }
-
-protected:
-    SkString name() override { return SkString("PerlinPatch"); }
-
-    bool onChar(SkUnichar uni) override {
-            switch (uni) {
-                case 'g': fShowGrid = !fShowGrid; return true;
-                default: break;
-            }
-            return false;
-    }
-
-    bool onAnimate(double nanos) override {
-        fSeed += 0.005f;
-        return true;
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        if (!canvas->getTotalMatrix().invert(&fInvMatrix)) {
-            return;
-        }
-
-        SkPaint paint;
-
-        SkScalar texWidth = fTexScale * TexWidth;
-        SkScalar texHeight = fTexScale * TexHeight;
-        const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
-            { fTexX - texWidth, fTexY - texHeight},
-            { fTexX + texWidth, fTexY - texHeight},
-            { fTexX + texWidth, fTexY + texHeight},
-            { fTexX - texWidth, fTexY + texHeight}}
-        ;
-
-        SkScalar scaleFreq = 2.0;
-        fShader1 = SkPerlinNoiseShader::MakeImprovedNoise(fXFreq/scaleFreq, fYFreq/scaleFreq, 4,
-                                                             fSeed);
-        fShaderCompose = SkShaders::Blend(SkBlendMode::kSrcOver, fShader0, fShader1);
-
-        paint.setShader(fShaderCompose);
-
-        const SkPoint* tex = texCoords;
-        if (fShowGrid) {
-            tex = nullptr;
-        }
-        canvas->drawPatch(fPts, nullptr, tex, SkBlendMode::kSrc, paint);
-
-        draw_control_points(canvas, fPts);
-    }
-
-    class PtClick : public Click {
-    public:
-        int fIndex;
-        PtClick(int index) : fIndex(index) {}
-    };
-
-    static bool hittest(const SkPoint& pt, SkScalar x, SkScalar y) {
-        return SkPoint::Length(pt.fX - x, pt.fY - y) < SkIntToScalar(5);
-    }
-
-    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
-        modi &= ~skui::ModifierKey::kFirstPress;  // ignore this
-        if (skui::ModifierKey::kShift == modi) {
-            return new PtClick(-1);
-        }
-        if (skui::ModifierKey::kControl == modi) {
-            return new PtClick(-2);
-        }
-        SkPoint clickPoint = {x, y};
-        fInvMatrix.mapPoints(&clickPoint, 1);
-        for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
-            if (hittest(fPts[i], clickPoint.fX, clickPoint.fY)) {
-                return new PtClick((int)i);
-            }
-        }
-        return nullptr;
-    }
-
-    bool onClick(Click* click) override {
-        PtClick* ptClick = (PtClick*)click;
-        if (ptClick->fIndex >= 0) {
-            fPts[ptClick->fIndex].set(click->fCurr.fX , click->fCurr.fY );
-        } else if (-1 == ptClick->fIndex) {
-            SkScalar xDiff = click->fPrev.fX - click->fCurr.fX;
-            SkScalar yDiff = click->fPrev.fY - click->fCurr.fY;
-            fTexX += xDiff * fTexScale;
-            fTexY += yDiff * fTexScale;
-        } else if (-2 == ptClick->fIndex) {
-            SkScalar yDiff = click->fCurr.fY - click->fPrev.fY;
-            fTexScale += yDiff / 10.0f;
-            fTexScale = SkTMax(0.1f, SkTMin(20.f, fTexScale));
-        }
-        return true;
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-DEF_SAMPLE( return new PerlinPatchView(); )
diff --git a/third_party/skia/samplecode/Sample.cpp b/third_party/skia/samplecode/Sample.cpp
index c2ba788..a69de8e 100644
--- a/third_party/skia/samplecode/Sample.cpp
+++ b/third_party/skia/samplecode/Sample.cpp
@@ -10,16 +10,16 @@
 #include "samplecode/Sample.h"
 
 #if SK_SUPPORT_GPU
-#   include "include/gpu/GrContext.h"
+#   include "include/gpu/GrDirectContext.h"
 #else
-class GrContext;
+class GrDirectContext;
 #endif
 
 //////////////////////////////////////////////////////////////////////////////
 
 void Sample::setSize(SkScalar width, SkScalar height) {
-    width = SkMaxScalar(0, width);
-    height = SkMaxScalar(0, height);
+    width = std::max(0.0f, width);
+    height = std::max(0.0f, height);
 
     if (fWidth != width || fHeight != height)
     {
@@ -49,9 +49,9 @@
         SkAutoCanvasRestore acr(canvas, true);
         this->onDrawContent(canvas);
 #if SK_SUPPORT_GPU
-        // Ensure the GrContext doesn't combine GrDrawOps across draw loops.
-        if (GrContext* context = canvas->getGrContext()) {
-            context->flush();
+        // Ensure the context doesn't combine GrDrawOps across draw loops.
+        if (auto direct = GrAsDirectContext(canvas->recordingContext())) {
+            direct->flushAndSubmit();
         }
 #endif
 
@@ -62,12 +62,13 @@
 ////////////////////////////////////////////////////////////////////////////
 
 bool Sample::mouse(SkPoint point, skui::InputState clickState, skui::ModifierKey modifierKeys) {
+    auto dispatch = [this](Click* c) {
+        return c->fHasFunc ? c->fFunc(c) : this->onClick(c);
+    };
+
     switch (clickState) {
         case skui::InputState::kDown:
             fClick = nullptr;
-            if (point.x() < 0 || point.y() < 0 || point.x() >= fWidth || point.y() >= fHeight) {
-                return false;
-            }
             fClick.reset(this->onFindClickHandler(point.x(), point.y(), modifierKeys));
             if (!fClick) {
                 return false;
@@ -75,7 +76,7 @@
             fClick->fPrev = fClick->fCurr = fClick->fOrig = point;
             fClick->fState = skui::InputState::kDown;
             fClick->fModifierKeys = modifierKeys;
-            this->onClick(fClick.get());
+            dispatch(fClick.get());
             return true;
         case skui::InputState::kMove:
             if (fClick) {
@@ -83,7 +84,7 @@
                 fClick->fCurr = point;
                 fClick->fState = skui::InputState::kMove;
                 fClick->fModifierKeys = modifierKeys;
-                return this->onClick(fClick.get());
+                return dispatch(fClick.get());
             }
             return false;
         case skui::InputState::kUp:
@@ -92,7 +93,7 @@
                 fClick->fCurr = point;
                 fClick->fState = skui::InputState::kUp;
                 fClick->fModifierKeys = modifierKeys;
-                bool result = this->onClick(fClick.get());
+                bool result = dispatch(fClick.get());
                 fClick = nullptr;
                 return result;
             }
diff --git a/third_party/skia/samplecode/Sample.h b/third_party/skia/samplecode/Sample.h
index d6ccf48..f1026bd 100644
--- a/third_party/skia/samplecode/Sample.h
+++ b/third_party/skia/samplecode/Sample.h
@@ -18,6 +18,8 @@
 #include "tools/skui/InputState.h"
 #include "tools/skui/ModifierKey.h"
 
+#include <functional>
+
 class SkCanvas;
 class Sample;
 
@@ -55,13 +57,19 @@
     // Click handling
     class Click {
     public:
+        Click() {}
+        Click(std::function<bool(Click*)> f) : fFunc(f), fHasFunc(true) {}
         virtual ~Click() = default;
+
         SkPoint     fOrig = {0, 0};
         SkPoint     fPrev = {0, 0};
         SkPoint     fCurr = {0, 0};
         skui::InputState  fState = skui::InputState::kDown;
         skui::ModifierKey fModifierKeys = skui::ModifierKey::kNone;
         SkMetaData  fMeta;
+
+        std::function<bool(Click*)> fFunc;
+        bool fHasFunc = false;
     };
     bool mouse(SkPoint point, skui::InputState clickState, skui::ModifierKey modifierKeys);
 
diff --git a/third_party/skia/samplecode/Sample2PtRadial.cpp b/third_party/skia/samplecode/Sample2PtRadial.cpp
index 64f9e66..f404d14 100644
--- a/third_party/skia/samplecode/Sample2PtRadial.cpp
+++ b/third_party/skia/samplecode/Sample2PtRadial.cpp
@@ -14,9 +14,9 @@
     TwoPtConicalView() {}
 
 protected:
-    virtual SkString name() { return SkString("2PtConical"); }
+    SkString name() override { return SkString("2PtConical"); }
 
-    virtual void onDrawContent(SkCanvas* canvas) {
+    void onDrawContent(SkCanvas* canvas) override {
         canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
 
         SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
@@ -32,7 +32,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/Sample3D.cpp b/third_party/skia/samplecode/Sample3D.cpp
new file mode 100644
index 0000000..7e958bc
--- /dev/null
+++ b/third_party/skia/samplecode/Sample3D.cpp
@@ -0,0 +1,487 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/core/SkCanvas.h"
+#include "include/core/SkM44.h"
+#include "include/core/SkPaint.h"
+#include "include/core/SkRRect.h"
+#include "include/core/SkVertices.h"
+#include "include/utils/SkRandom.h"
+#include "samplecode/Sample.h"
+#include "tools/Resources.h"
+
+struct VSphere {
+    SkV2     fCenter;
+    SkScalar fRadius;
+
+    VSphere(SkV2 center, SkScalar radius) : fCenter(center), fRadius(radius) {}
+
+    bool contains(SkV2 v) const {
+        return (v - fCenter).length() <= fRadius;
+    }
+
+    SkV2 pinLoc(SkV2 p) const {
+        auto v = p - fCenter;
+        if (v.length() > fRadius) {
+            v *= (fRadius / v.length());
+        }
+        return fCenter + v;
+    }
+
+    SkV3 computeUnitV3(SkV2 v) const {
+        v = (v - fCenter) * (1 / fRadius);
+        SkScalar len2 = v.lengthSquared();
+        if (len2 > 1) {
+            v = v.normalize();
+            len2 = 1;
+        }
+        SkScalar z = SkScalarSqrt(1 - len2);
+        return {v.x, v.y, z};
+    }
+
+    struct RotateInfo {
+        SkV3    fAxis;
+        SkScalar fAngle;
+    };
+
+    RotateInfo computeRotationInfo(SkV2 a, SkV2 b) const {
+        SkV3 u = this->computeUnitV3(a);
+        SkV3 v = this->computeUnitV3(b);
+        SkV3 axis = u.cross(v);
+        SkScalar length = axis.length();
+
+        if (!SkScalarNearlyZero(length)) {
+            return {axis * (1.0f / length), acos(u.dot(v))};
+        }
+        return {{0, 0, 0}, 0};
+    }
+
+    SkM44 computeRotation(SkV2 a, SkV2 b) const {
+        auto [axis, angle] = this->computeRotationInfo(a, b);
+        return SkM44::Rotate(axis, angle);
+    }
+};
+
+static SkM44 inv(const SkM44& m) {
+    SkM44 inverse;
+    SkAssertResult(m.invert(&inverse));
+    return inverse;
+}
+
+// Compute the inverse transpose (of the upper-left 3x3) of a matrix, used to transform vectors
+static SkM44 normals(SkM44 m) {
+    m.setRow(3, {0, 0, 0, 1});
+    m.setCol(3, {0, 0, 0, 1});
+    SkAssertResult(m.invert(&m));
+    return m.transpose();
+}
+
+class Sample3DView : public Sample {
+protected:
+    float   fNear = 0.05f;
+    float   fFar = 4;
+    float   fAngle = SK_ScalarPI / 12;
+
+    SkV3    fEye { 0, 0, 1.0f/tan(fAngle/2) - 1 };
+    SkV3    fCOA { 0, 0, 0 };
+    SkV3    fUp  { 0, 1, 0 };
+
+public:
+    void concatCamera(SkCanvas* canvas, const SkRect& area, SkScalar zscale) {
+        SkM44 camera = SkM44::LookAt(fEye, fCOA, fUp),
+              perspective = SkM44::Perspective(fNear, fFar, fAngle),
+              viewport = SkM44::Translate(area.centerX(), area.centerY(), 0) *
+                         SkM44::Scale(area.width()*0.5f, area.height()*0.5f, zscale);
+
+        canvas->concat(viewport * perspective * camera * inv(viewport));
+    }
+};
+
+struct Face {
+    SkScalar fRx, fRy;
+    SkColor  fColor;
+
+    static SkM44 T(SkScalar x, SkScalar y, SkScalar z) {
+        return SkM44::Translate(x, y, z);
+    }
+
+    static SkM44 R(SkV3 axis, SkScalar rad) {
+        return SkM44::Rotate(axis, rad);
+    }
+
+    SkM44 asM44(SkScalar scale) const {
+        return R({0,1,0}, fRy) * R({1,0,0}, fRx) * T(0, 0, scale);
+    }
+};
+
+static bool front(const SkM44& m) {
+    SkM44 m2(SkM44::kUninitialized_Constructor);
+    if (!m.invert(&m2)) {
+        m2.setIdentity();
+    }
+    /*
+     *  Classically we want to dot the transpose(inverse(ctm)) with our surface normal.
+     *  In this case, the normal is known to be {0, 0, 1}, so we only actually need to look
+     *  at the z-scale of the inverse (the transpose doesn't change the main diagonal, so
+     *  no need to actually transpose).
+     */
+    return m2.rc(2,2) > 0;
+}
+
+const Face faces[] = {
+    {             0,             0,  SK_ColorRED }, // front
+    {             0,   SK_ScalarPI,  SK_ColorGREEN }, // back
+
+    { SK_ScalarPI/2,             0,  SK_ColorBLUE }, // top
+    {-SK_ScalarPI/2,             0,  SK_ColorCYAN }, // bottom
+
+    {             0, SK_ScalarPI/2,  SK_ColorMAGENTA }, // left
+    {             0,-SK_ScalarPI/2,  SK_ColorYELLOW }, // right
+};
+
+#include "include/effects/SkRuntimeEffect.h"
+
+struct LightOnSphere {
+    SkV2     fLoc;
+    SkScalar fDistance;
+    SkScalar fRadius;
+
+    SkV3 computeWorldPos(const VSphere& s) const {
+        return s.computeUnitV3(fLoc) * fDistance;
+    }
+
+    void draw(SkCanvas* canvas) const {
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setColor(SK_ColorWHITE);
+        canvas->drawCircle(fLoc.x, fLoc.y, fRadius + 2, paint);
+        paint.setColor(SK_ColorBLACK);
+        canvas->drawCircle(fLoc.x, fLoc.y, fRadius, paint);
+    }
+};
+
+#include "include/core/SkTime.h"
+
+class RotateAnimator {
+    SkV3        fAxis = {0, 0, 0};
+    SkScalar    fAngle = 0,
+                fPrevAngle = 1234567;
+    double      fNow = 0,
+                fPrevNow = 0;
+
+    SkScalar    fAngleSpeed = 0,
+                fAngleSign = 1;
+
+    inline static constexpr double kSlowDown = 4;
+    inline static constexpr SkScalar kMaxSpeed = 16;
+
+public:
+    void update(SkV3 axis, SkScalar angle) {
+        if (angle != fPrevAngle) {
+            fPrevAngle = fAngle;
+            fAngle = angle;
+
+            fPrevNow = fNow;
+            fNow = SkTime::GetSecs();
+
+            fAxis = axis;
+        }
+    }
+
+    SkM44 rotation() {
+        if (fAngleSpeed > 0) {
+            double now = SkTime::GetSecs();
+            double dtime = now - fPrevNow;
+            fPrevNow = now;
+            double delta = fAngleSign * fAngleSpeed * dtime;
+            fAngle += delta;
+            fAngleSpeed -= kSlowDown * dtime;
+            if (fAngleSpeed < 0) {
+                fAngleSpeed = 0;
+            }
+        }
+        return SkM44::Rotate(fAxis, fAngle);
+
+    }
+
+    void start() {
+        if (fPrevNow != fNow) {
+            fAngleSpeed = (fAngle - fPrevAngle) / (fNow - fPrevNow);
+            fAngleSign = fAngleSpeed < 0 ? -1 : 1;
+            fAngleSpeed = std::min(kMaxSpeed, std::abs(fAngleSpeed));
+        } else {
+            fAngleSpeed = 0;
+        }
+        fPrevNow = SkTime::GetSecs();
+        fAngle = 0;
+    }
+
+    void reset() {
+        fAngleSpeed = 0;
+        fAngle = 0;
+        fPrevAngle = 1234567;
+    }
+
+    bool isAnimating() const { return fAngleSpeed != 0; }
+};
+
+class SampleCubeBase : public Sample3DView {
+    enum {
+        DX = 400,
+        DY = 300
+    };
+
+    SkM44 fRotation;        // part of model
+
+    RotateAnimator fRotateAnimator;
+
+protected:
+    enum Flags {
+        kCanRunOnCPU    = 1 << 0,
+        kShowLightDome  = 1 << 1,
+    };
+
+    LightOnSphere fLight = {{200 + DX, 200 + DY}, 800, 12};
+
+    VSphere fSphere;
+    Flags   fFlags;
+
+public:
+    SampleCubeBase(Flags flags)
+        : fSphere({200 + DX, 200 + DY}, 400)
+        , fFlags(flags)
+    {}
+
+    bool onChar(SkUnichar uni) override {
+        switch (uni) {
+            case 'Z': fLight.fDistance += 10; return true;
+            case 'z': fLight.fDistance -= 10; return true;
+        }
+        return this->Sample3DView::onChar(uni);
+    }
+
+    virtual void drawContent(
+            SkCanvas* canvas, SkColor, int index, bool drawFront, const SkM44& localToWorld) = 0;
+
+    void onDrawContent(SkCanvas* canvas) override {
+        if (!canvas->recordingContext() && !(fFlags & kCanRunOnCPU)) {
+            return;
+        }
+
+        canvas->save();
+        canvas->translate(DX, DY);
+
+        this->concatCamera(canvas, {0, 0, 400, 400}, 200);
+
+        for (bool drawFront : {false, true}) {
+            int index = 0;
+            for (auto f : faces) {
+                SkAutoCanvasRestore acr(canvas, true);
+
+                SkM44 trans = SkM44::Translate(200, 200, 0);   // center of the rotation
+                SkM44 m = fRotateAnimator.rotation() * fRotation * f.asM44(200);
+
+                canvas->concat(trans);
+
+                // "World" space - content is centered at the origin, in device scale (+-200)
+                SkM44 localToWorld = m * inv(trans);
+
+                canvas->concat(localToWorld);
+                this->drawContent(canvas, f.fColor, index++, drawFront, localToWorld);
+            }
+        }
+
+        canvas->restore();  // camera & center the content in the window
+
+        if (fFlags & kShowLightDome){
+            fLight.draw(canvas);
+
+            SkPaint paint;
+            paint.setAntiAlias(true);
+            paint.setStyle(SkPaint::kStroke_Style);
+            paint.setColor(0x40FF0000);
+            canvas->drawCircle(fSphere.fCenter.x, fSphere.fCenter.y, fSphere.fRadius, paint);
+            canvas->drawLine(fSphere.fCenter.x, fSphere.fCenter.y - fSphere.fRadius,
+                             fSphere.fCenter.x, fSphere.fCenter.y + fSphere.fRadius, paint);
+            canvas->drawLine(fSphere.fCenter.x - fSphere.fRadius, fSphere.fCenter.y,
+                             fSphere.fCenter.x + fSphere.fRadius, fSphere.fCenter.y, paint);
+        }
+    }
+
+    Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
+        SkV2 p = fLight.fLoc - SkV2{x, y};
+        if (p.length() <= fLight.fRadius) {
+            Click* c = new Click();
+            c->fMeta.setS32("type", 0);
+            return c;
+        }
+        if (fSphere.contains({x, y})) {
+            Click* c = new Click();
+            c->fMeta.setS32("type", 1);
+
+            fRotation = fRotateAnimator.rotation() * fRotation;
+            fRotateAnimator.reset();
+            return c;
+        }
+        return nullptr;
+    }
+    bool onClick(Click* click) override {
+        if (click->fMeta.hasS32("type", 0)) {
+            fLight.fLoc = fSphere.pinLoc({click->fCurr.fX, click->fCurr.fY});
+            return true;
+        }
+        if (click->fMeta.hasS32("type", 1)) {
+            if (click->fState == skui::InputState::kUp) {
+                fRotation = fRotateAnimator.rotation() * fRotation;
+                fRotateAnimator.start();
+            } else {
+                auto [axis, angle] = fSphere.computeRotationInfo(
+                                                {click->fOrig.fX, click->fOrig.fY},
+                                                {click->fCurr.fX, click->fCurr.fY});
+                fRotateAnimator.update(axis, angle);
+            }
+            return true;
+        }
+        return true;
+    }
+
+    bool onAnimate(double nanos) override {
+        return fRotateAnimator.isAnimating();
+    }
+
+private:
+    using INHERITED = Sample3DView;
+};
+
+class SampleBump3D : public SampleCubeBase {
+    sk_sp<SkShader>        fBmpShader, fImgShader;
+    sk_sp<SkRuntimeEffect> fEffect;
+    SkRRect                fRR;
+
+public:
+    SampleBump3D() : SampleCubeBase(Flags(kCanRunOnCPU | kShowLightDome)) {}
+
+    SkString name() override { return SkString("bump3d"); }
+
+    void onOnceBeforeDraw() override {
+        fRR = SkRRect::MakeRectXY({20, 20, 380, 380}, 50, 50);
+        auto img = GetResourceAsImage("images/brickwork-texture.jpg");
+        fImgShader = img->makeShader(SkSamplingOptions(), SkMatrix::Scale(2, 2));
+        img = GetResourceAsImage("images/brickwork_normal-map.jpg");
+        fBmpShader = img->makeShader(SkSamplingOptions(), SkMatrix::Scale(2, 2));
+
+        const char code[] = R"(
+            uniform shader color_map;
+            uniform shader normal_map;
+
+            uniform float4x4 localToWorld;
+            uniform float4x4 localToWorldAdjInv;
+            uniform float3   lightPos;
+
+            float3 convert_normal_sample(half4 c) {
+                float3 n = 2 * c.rgb - 1;
+                n.y = -n.y;
+                return n;
+            }
+
+            half4 main(float2 p) {
+                float3 norm = convert_normal_sample(normal_map.eval(p));
+                float3 plane_norm = normalize(localToWorldAdjInv * norm.xyz0).xyz;
+
+                float3 plane_pos = (localToWorld * p.xy01).xyz;
+                float3 light_dir = normalize(lightPos - plane_pos);
+
+                float ambient = 0.2;
+                float dp = dot(plane_norm, light_dir);
+                float scale = min(ambient + max(dp, 0), 1);
+
+                return color_map.eval(p) * scale.xxx1;
+            }
+        )";
+        auto [effect, error] = SkRuntimeEffect::MakeForShader(SkString(code));
+        if (!effect) {
+            SkDebugf("runtime error %s\n", error.c_str());
+        }
+        fEffect = effect;
+    }
+
+    void drawContent(SkCanvas* canvas,
+                     SkColor color,
+                     int index,
+                     bool drawFront,
+                     const SkM44& localToWorld) override {
+        if (!drawFront || !front(canvas->getLocalToDevice())) {
+            return;
+        }
+
+        SkRuntimeShaderBuilder builder(fEffect);
+        builder.uniform("lightPos") = fLight.computeWorldPos(fSphere);
+        builder.uniform("localToWorld") = localToWorld;
+        builder.uniform("localToWorldAdjInv") = normals(localToWorld);
+
+        builder.child("color_map")  = fImgShader;
+        builder.child("normal_map") = fBmpShader;
+
+        SkPaint paint;
+        paint.setColor(color);
+        paint.setShader(builder.makeShader());
+
+        canvas->drawRRect(fRR, paint);
+    }
+};
+DEF_SAMPLE( return new SampleBump3D; )
+
+#include "modules/skottie/include/Skottie.h"
+
+class SampleSkottieCube : public SampleCubeBase {
+    sk_sp<skottie::Animation> fAnim[6];
+
+public:
+    SampleSkottieCube() : SampleCubeBase(kCanRunOnCPU) {}
+
+    SkString name() override { return SkString("skottie3d"); }
+
+    void onOnceBeforeDraw() override {
+        const char* files[] = {
+            "skottie/skottie-chained-mattes.json",
+            "skottie/skottie-gradient-ramp.json",
+            "skottie/skottie_sample_2.json",
+            "skottie/skottie-3d-3planes.json",
+            "skottie/skottie-text-animator-4.json",
+            "skottie/skottie-motiontile-effect-phase.json",
+
+        };
+        for (unsigned i = 0; i < SK_ARRAY_COUNT(files); ++i) {
+            if (auto stream = GetResourceAsStream(files[i])) {
+                fAnim[i] = skottie::Animation::Make(stream.get());
+            }
+        }
+    }
+
+    void drawContent(
+            SkCanvas* canvas, SkColor color, int index, bool drawFront, const SkM44&) override {
+        if (!drawFront || !front(canvas->getLocalToDevice())) {
+            return;
+        }
+
+        SkPaint paint;
+        paint.setColor(color);
+        SkRect r = {0, 0, 400, 400};
+        canvas->drawRect(r, paint);
+        fAnim[index]->render(canvas, &r);
+    }
+
+    bool onAnimate(double nanos) override {
+        for (auto& anim : fAnim) {
+            SkScalar dur = anim->duration();
+            SkScalar t = fmod(1e-9 * nanos, dur) / dur;
+            anim->seek(t);
+        }
+        return true;
+    }
+};
+DEF_SAMPLE( return new SampleSkottieCube; )
diff --git a/third_party/skia/samplecode/SampleAAClip.cpp b/third_party/skia/samplecode/SampleAAClip.cpp
deleted file mode 100644
index 46e4fe2..0000000
--- a/third_party/skia/samplecode/SampleAAClip.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkPath.h"
-#include "samplecode/Sample.h"
-#include "src/core/SkAAClip.h"
-
-static void testop(const SkIRect& r0, const SkIRect& r1, SkRegion::Op op,
-                   const SkIRect& expectedR) {
-    SkAAClip c0, c1, c2;
-    c0.setRect(r0);
-    c1.setRect(r1);
-    c2.op(c0, c1, op);
-
-    SkDEBUGCODE(SkIRect r2 = c2.getBounds());
-    SkASSERT(r2 == expectedR);
-}
-
-static const struct {
-    SkIRect r0;
-    SkIRect r1;
-    SkRegion::Op op;
-    SkIRect expectedR;
-} gRec[] = {
-    {{ 1, 2, 9, 3 }, { -3, 2, 5, 11 }, SkRegion::kDifference_Op, { 5, 2, 9, 3 }},
-    {{ 1, 10, 5, 13 }, { 1, 2, 5, 11 }, SkRegion::kDifference_Op, { 1, 11, 5, 13 }},
-    {{ 1, 10, 5, 13 }, { 1, 2, 5, 11 }, SkRegion::kReverseDifference_Op, { 1, 2, 5, 10 }},
-};
-
-static void testop() {
-    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
-        testop(gRec[i].r0, gRec[i].r1, gRec[i].op, gRec[i].expectedR);
-    }
-}
-
-static void drawClip(SkCanvas* canvas, const SkAAClip& clip) {
-    SkMask mask;
-    SkBitmap bm;
-
-    clip.copyToMask(&mask);
-    SkAutoMaskFreeImage amfi(mask.fImage);
-
-    bm.installMaskPixels(mask);
-
-    SkPaint paint;
-    canvas->drawBitmap(bm,
-                       SK_Scalar1 * mask.fBounds.fLeft,
-                       SK_Scalar1 * mask.fBounds.fTop,
-                       &paint);
-}
-
-class AAClipView : public Sample {
-    SkString name() override { return SkString("AAClip"); }
-
-    void onOnceBeforeDraw() override { testop(); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-#if 1
-        SkAAClip aaclip;
-        SkPath path;
-        SkRect bounds;
-
-        bounds.setLTRB(0, 0, 20, 20);
-        bounds.inset(SK_ScalarHalf, SK_ScalarHalf);
-
-//        path.addRect(bounds);
-//        path.addOval(bounds);
-        path.addRoundRect(bounds, 4, 4);
-        aaclip.setPath(path);
-        canvas->translate(30, 30);
-        drawClip(canvas, aaclip);
-
-        SkAAClip aaclip2;
-        path.offset(10, 10);
-        aaclip2.setPath(path);
-        canvas->translate(30, 0);
-        drawClip(canvas, aaclip2);
-
-        SkAAClip aaclip3;
-        aaclip3.op(aaclip, aaclip2, SkRegion::kIntersect_Op);
-        canvas->translate(30, 0);
-        drawClip(canvas, aaclip3);
-
-#endif
-
-#if 0
-        SkRect r;
-        r.set(0, 0, this->width(), this->height());
-        r.inset(20, 20);
-        canvas->clipRect(r);
-
-        SkPath path;
-        path.addRect(r);
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setColor(SK_ColorRED);
-        canvas->drawPath(path, paint);
-#endif
-    }
-};
-DEF_SAMPLE( return new AAClipView(); )
diff --git a/third_party/skia/samplecode/SampleAAGeometry.cpp b/third_party/skia/samplecode/SampleAAGeometry.cpp
deleted file mode 100644
index b2aa97d..0000000
--- a/third_party/skia/samplecode/SampleAAGeometry.cpp
+++ /dev/null
@@ -1,1847 +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.
- */
-
-#include "include/core/SkBitmap.h"
-#include "include/core/SkCanvas.h"
-#include "include/core/SkString.h"
-#include "include/private/SkMacros.h"
-#include "include/utils/SkTextUtils.h"
-#include "samplecode/Sample.h"
-#include "src/core/SkGeometry.h"
-#include "src/core/SkPointPriv.h"
-#include "src/pathops/SkIntersections.h"
-#include "src/pathops/SkOpEdgeBuilder.h"
-
-#if 0
-void SkStrokeSegment::dump() const {
-    SkDebugf("{{{%1.9g,%1.9g}, {%1.9g,%1.9g}", fPts[0].fX, fPts[0].fY, fPts[1].fX, fPts[1].fY);
-    if (SkPath::kQuad_Verb == fVerb) {
-        SkDebugf(", {%1.9g,%1.9g}", fPts[2].fX, fPts[2].fY);
-    }
-    SkDebugf("}}");
-#ifdef SK_DEBUG
-    SkDebugf(" id=%d", fDebugID);
-#endif
-    SkDebugf("\n");
-}
-
-void SkStrokeSegment::dumpAll() const {
-    const SkStrokeSegment* segment = this;
-    while (segment) {
-        segment->dump();
-        segment = segment->fNext;
-    }
-}
-
-void SkStrokeTriple::dump() const {
-    SkDebugf("{{{%1.9g,%1.9g}, {%1.9g,%1.9g}", fPts[0].fX, fPts[0].fY, fPts[1].fX, fPts[1].fY);
-    if (SkPath::kQuad_Verb <= fVerb) {
-        SkDebugf(", {%1.9g,%1.9g}", fPts[2].fX, fPts[2].fY);
-    }
-    if (SkPath::kCubic_Verb == fVerb) {
-        SkDebugf(", {%1.9g,%1.9g}", fPts[3].fX, fPts[3].fY);
-    } else if (SkPath::kConic_Verb == fVerb) {
-        SkDebugf(", %1.9g", weight());
-    }
-    SkDebugf("}}");
-#ifdef SK_DEBUG
-    SkDebugf(" triple id=%d", fDebugID);
-#endif
-    SkDebugf("\ninner:\n");
-    fInner->dumpAll();
-    SkDebugf("outer:\n");
-    fOuter->dumpAll();
-    SkDebugf("join:\n");
-    fJoin->dumpAll();
-}
-
-void SkStrokeTriple::dumpAll() const {
-    const SkStrokeTriple* triple = this;
-    while (triple) {
-        triple->dump();
-        triple = triple->fNext;
-    }
-}
-
-void SkStrokeContour::dump() const {
-#ifdef SK_DEBUG
-    SkDebugf("id=%d ", fDebugID);
-#endif
-    SkDebugf("head:\n");
-    fHead->dumpAll();
-    SkDebugf("head cap:\n");
-    fHeadCap->dumpAll();
-    SkDebugf("tail cap:\n");
-    fTailCap->dumpAll();
-}
-
-void SkStrokeContour::dumpAll() const {
-    const SkStrokeContour* contour = this;
-    while (contour) {
-        contour->dump();
-        contour = contour->fNext;
-    }
-}
-#endif
-
-SkScalar gCurveDistance = 10;
-
-#if 0  // unused
-static SkPath::Verb get_path_verb(int index, const SkPath& path) {
-    if (index < 0) {
-        return SkPath::kMove_Verb;
-    }
-    SkPoint pts[4];
-    SkPath::Verb verb;
-    SkPath::Iter iter(path, true);
-    int counter = -1;
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-        if (++counter < index) {
-            continue;
-        }
-        return verb;
-    }
-    SkASSERT(0);
-    return SkPath::kMove_Verb;
-}
-#endif
-
-static SkScalar get_path_weight(int index, const SkPath& path) {
-    SkPoint pts[4];
-    SkPath::Verb verb;
-    SkPath::Iter iter(path, true);
-    int counter = -1;
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-        if (++counter < index) {
-            continue;
-        }
-        return verb == SkPath::kConic_Verb ? iter.conicWeight() : 1;
-    }
-    SkASSERT(0);
-    return 0;
-}
-
-static void set_path_pt(int index, const SkPoint& pt, SkPath* path) {
-    SkPath result;
-    SkPoint pts[4];
-    SkPath::Verb verb;
-    SkPath::RawIter iter(*path);
-    int startIndex = 0;
-    int endIndex = 0;
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-        switch (verb) {
-            case SkPath::kMove_Verb:
-                endIndex += 1;
-                break;
-            case SkPath::kLine_Verb:
-                endIndex += 1;
-                break;
-            case SkPath::kQuad_Verb:
-            case SkPath::kConic_Verb:
-                endIndex += 2;
-                break;
-            case SkPath::kCubic_Verb:
-                endIndex += 3;
-                break;
-            case SkPath::kClose_Verb:
-                break;
-            case SkPath::kDone_Verb:
-                break;
-            default:
-                SkASSERT(0);
-        }
-        if (startIndex <= index && index < endIndex) {
-            pts[index - startIndex] = pt;
-            index = -1;
-        }
-        switch (verb) {
-            case SkPath::kMove_Verb:
-                result.moveTo(pts[0]);
-                break;
-            case SkPath::kLine_Verb:
-                result.lineTo(pts[1]);
-                startIndex += 1;
-                break;
-            case SkPath::kQuad_Verb:
-                result.quadTo(pts[1], pts[2]);
-                startIndex += 2;
-                break;
-            case SkPath::kConic_Verb:
-                result.conicTo(pts[1], pts[2], iter.conicWeight());
-                startIndex += 2;
-                break;
-            case SkPath::kCubic_Verb:
-                result.cubicTo(pts[1], pts[2], pts[3]);
-                startIndex += 3;
-                break;
-            case SkPath::kClose_Verb:
-                result.close();
-                startIndex += 1;
-                break;
-            case SkPath::kDone_Verb:
-                break;
-            default:
-                SkASSERT(0);
-        }
-    }
-#if 0
-    SkDebugf("\n\noriginal\n");
-    path->dump();
-    SkDebugf("\nedited\n");
-    result.dump();
-#endif
-    *path = result;
-}
-
-static void add_path_segment(int index, SkPath* path) {
-    SkPath result;
-    SkPoint pts[4];
-    SkPoint firstPt = { 0, 0 };  // init to avoid warning
-    SkPoint lastPt = { 0, 0 };  // init to avoid warning
-    SkPath::Verb verb;
-    SkPath::RawIter iter(*path);
-    int counter = -1;
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-        SkScalar weight  SK_INIT_TO_AVOID_WARNING;
-        if (++counter == index) {
-            switch (verb) {
-                case SkPath::kLine_Verb:
-                    result.lineTo((pts[0].fX + pts[1].fX) / 2, (pts[0].fY + pts[1].fY) / 2);
-                    break;
-                case SkPath::kQuad_Verb: {
-                    SkPoint chop[5];
-                    SkChopQuadAtHalf(pts, chop);
-                    result.quadTo(chop[1], chop[2]);
-                    pts[1] = chop[3];
-                    } break;
-                case SkPath::kConic_Verb: {
-                    SkConic chop[2];
-                    SkConic conic;
-                    conic.set(pts, iter.conicWeight());
-                    if (!conic.chopAt(0.5f, chop)) {
-                        return;
-                    }
-                    result.conicTo(chop[0].fPts[1], chop[0].fPts[2], chop[0].fW);
-                    pts[1] = chop[1].fPts[1];
-                    weight = chop[1].fW;
-                    } break;
-                case SkPath::kCubic_Verb: {
-                    SkPoint chop[7];
-                    SkChopCubicAtHalf(pts, chop);
-                    result.cubicTo(chop[1], chop[2], chop[3]);
-                    pts[1] = chop[4];
-                    pts[2] = chop[5];
-                    } break;
-                case SkPath::kClose_Verb: {
-                    result.lineTo((lastPt.fX + firstPt.fX) / 2, (lastPt.fY + firstPt.fY) / 2);
-                    } break;
-                default:
-                    SkASSERT(0);
-            }
-        } else if (verb == SkPath::kConic_Verb) {
-            weight = iter.conicWeight();
-        }
-        switch (verb) {
-            case SkPath::kMove_Verb:
-                result.moveTo(firstPt = pts[0]);
-                break;
-            case SkPath::kLine_Verb:
-                result.lineTo(lastPt = pts[1]);
-                break;
-            case SkPath::kQuad_Verb:
-                result.quadTo(pts[1], lastPt = pts[2]);
-                break;
-            case SkPath::kConic_Verb:
-                result.conicTo(pts[1], lastPt = pts[2], weight);
-                break;
-            case SkPath::kCubic_Verb:
-                result.cubicTo(pts[1], pts[2], lastPt = pts[3]);
-                break;
-            case SkPath::kClose_Verb:
-                result.close();
-                break;
-            case SkPath::kDone_Verb:
-                break;
-            default:
-                SkASSERT(0);
-        }
-    }
-    *path = result;
-}
-
-static void delete_path_segment(int index, SkPath* path) {
-    SkPath result;
-    SkPoint pts[4];
-    SkPath::Verb verb;
-    SkPath::RawIter iter(*path);
-    int counter = -1;
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-        if (++counter == index) {
-            continue;
-        }
-        switch (verb) {
-            case SkPath::kMove_Verb:
-                result.moveTo(pts[0]);
-                break;
-            case SkPath::kLine_Verb:
-                result.lineTo(pts[1]);
-                break;
-            case SkPath::kQuad_Verb:
-                result.quadTo(pts[1], pts[2]);
-                break;
-            case SkPath::kConic_Verb:
-                result.conicTo(pts[1], pts[2], iter.conicWeight());
-                break;
-            case SkPath::kCubic_Verb:
-                result.cubicTo(pts[1], pts[2], pts[3]);
-                break;
-            case SkPath::kClose_Verb:
-                result.close();
-                break;
-            case SkPath::kDone_Verb:
-                break;
-            default:
-                SkASSERT(0);
-        }
-    }
-    *path = result;
-}
-
-static void set_path_weight(int index, SkScalar w, SkPath* path) {
-    SkPath result;
-    SkPoint pts[4];
-    SkPath::Verb verb;
-    SkPath::Iter iter(*path, true);
-    int counter = -1;
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-        ++counter;
-        switch (verb) {
-            case SkPath::kMove_Verb:
-                result.moveTo(pts[0]);
-                break;
-            case SkPath::kLine_Verb:
-                result.lineTo(pts[1]);
-                break;
-            case SkPath::kQuad_Verb:
-                result.quadTo(pts[1], pts[2]);
-                break;
-            case SkPath::kConic_Verb:
-                result.conicTo(pts[1], pts[2], counter == index ? w : iter.conicWeight());
-                break;
-            case SkPath::kCubic_Verb:
-                result.cubicTo(pts[1], pts[2], pts[3]);
-                break;
-            case SkPath::kClose_Verb:
-                result.close();
-                break;
-            case SkPath::kDone_Verb:
-                break;
-            default:
-                SkASSERT(0);
-        }
-    }
-    *path = result;
-}
-
-static void set_path_verb(int index, SkPath::Verb v, SkPath* path, SkScalar w) {
-    SkASSERT(SkPath::kLine_Verb <= v && v <= SkPath::kCubic_Verb);
-    SkPath result;
-    SkPoint pts[4];
-    SkPath::Verb verb;
-    SkPath::Iter iter(*path, true);
-    int counter = -1;
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-        SkScalar weight = verb == SkPath::kConic_Verb ? iter.conicWeight() : 1;
-        if (++counter == index && v != verb) {
-            SkASSERT(SkPath::kLine_Verb <= verb && verb <= SkPath::kCubic_Verb);
-            switch (verb) {
-                case SkPath::kLine_Verb:
-                    switch (v) {
-                        case SkPath::kConic_Verb:
-                            weight = w;
-                        case SkPath::kQuad_Verb:
-                            pts[2] = pts[1];
-                            pts[1].fX = (pts[0].fX + pts[2].fX) / 2;
-                            pts[1].fY = (pts[0].fY + pts[2].fY) / 2;
-                            break;
-                        case SkPath::kCubic_Verb:
-                            pts[3] = pts[1];
-                            pts[1].fX = (pts[0].fX * 2 + pts[3].fX) / 3;
-                            pts[1].fY = (pts[0].fY * 2 + pts[3].fY) / 3;
-                            pts[2].fX = (pts[0].fX + pts[3].fX * 2) / 3;
-                            pts[2].fY = (pts[0].fY + pts[3].fY * 2) / 3;
-                            break;
-                         default:
-                            SkASSERT(0);
-                            break;
-                    }
-                    break;
-                case SkPath::kQuad_Verb:
-                case SkPath::kConic_Verb:
-                    switch (v) {
-                        case SkPath::kLine_Verb:
-                            pts[1] = pts[2];
-                            break;
-                        case SkPath::kConic_Verb:
-                            weight = w;
-                        case SkPath::kQuad_Verb:
-                            break;
-                        case SkPath::kCubic_Verb: {
-                            SkDQuad dQuad;
-                            dQuad.set(pts);
-                            SkDCubic dCubic = dQuad.debugToCubic();
-                            pts[3] = pts[2];
-                            pts[1] = dCubic[1].asSkPoint();
-                            pts[2] = dCubic[2].asSkPoint();
-                            } break;
-                         default:
-                            SkASSERT(0);
-                            break;
-                    }
-                    break;
-                case SkPath::kCubic_Verb:
-                    switch (v) {
-                        case SkPath::kLine_Verb:
-                            pts[1] = pts[3];
-                            break;
-                        case SkPath::kConic_Verb:
-                            weight = w;
-                        case SkPath::kQuad_Verb: {
-                            SkDCubic dCubic;
-                            dCubic.set(pts);
-                            SkDQuad dQuad = dCubic.toQuad();
-                            pts[1] = dQuad[1].asSkPoint();
-                            pts[2] = pts[3];
-                            } break;
-                        default:
-                            SkASSERT(0);
-                            break;
-                    }
-                    break;
-                default:
-                    SkASSERT(0);
-                    break;
-            }
-            verb = v;
-        }
-        switch (verb) {
-            case SkPath::kMove_Verb:
-                result.moveTo(pts[0]);
-                break;
-            case SkPath::kLine_Verb:
-                result.lineTo(pts[1]);
-                break;
-            case SkPath::kQuad_Verb:
-                result.quadTo(pts[1], pts[2]);
-                break;
-            case SkPath::kConic_Verb:
-                result.conicTo(pts[1], pts[2], weight);
-                break;
-            case SkPath::kCubic_Verb:
-                result.cubicTo(pts[1], pts[2], pts[3]);
-                break;
-            case SkPath::kClose_Verb:
-                result.close();
-                break;
-            default:
-                SkASSERT(0);
-                break;
-        }
-    }
-    *path = result;
-}
-
-static void add_to_map(SkScalar coverage, int x, int y, uint8_t* distanceMap, int w, int h) {
-    int byteCoverage = (int) (coverage * 256);
-    if (byteCoverage < 0) {
-        byteCoverage = 0;
-    } else if (byteCoverage > 255) {
-        byteCoverage = 255;
-    }
-    SkASSERT(x < w);
-    SkASSERT(y < h);
-    distanceMap[y * w + x] = SkTMax(distanceMap[y * w + x], (uint8_t) byteCoverage);
-}
-
-static void filter_coverage(const uint8_t* map, int len, uint8_t min, uint8_t max,
-        uint8_t* filter) {
-    for (int index = 0; index < len; ++index) {
-        uint8_t in = map[index];
-        filter[index] = in < min ? 0 : max < in ? 0 : in;
-    }
-}
-
-static void construct_path(SkPath& path) {
-    path.reset();
-    path.moveTo(442, 101.5f);
-    path.quadTo(413.5f, 691, 772, 514);
-    path.lineTo(346, 721.5f);
-    path.lineTo(154, 209);
-    path.lineTo(442, 101.5f);
-    path.close();
-}
-
-struct ButtonPaints {
-    static const int kMaxStateCount = 3;
-    SkPaint fDisabled;
-    SkPaint fStates[kMaxStateCount];
-    SkFont  fLabelFont;
-
-    ButtonPaints() {
-        fStates[0].setAntiAlias(true);
-        fStates[0].setStyle(SkPaint::kStroke_Style);
-        fStates[0].setColor(0xFF3F0000);
-        fStates[1] = fStates[0];
-        fStates[1].setStrokeWidth(3);
-        fStates[2] = fStates[1];
-        fStates[2].setColor(0xFFcf0000);
-        fLabelFont.setSize(25.0f);
-    }
-};
-
-struct Button {
-    SkRect fBounds;
-    int fStateCount;
-    int fState;
-    char fLabel;
-    bool fVisible;
-
-    Button(char label) {
-        fStateCount = 2;
-        fState = 0;
-        fLabel = label;
-        fVisible = false;
-    }
-
-    Button(char label, int stateCount) {
-        SkASSERT(stateCount <= ButtonPaints::kMaxStateCount);
-        fStateCount = stateCount;
-        fState = 0;
-        fLabel = label;
-        fVisible = false;
-    }
-
-    bool contains(const SkRect& rect) {
-        return fVisible && fBounds.contains(rect);
-    }
-
-    bool enabled() {
-        return SkToBool(fState);
-    }
-
-    void draw(SkCanvas* canvas, const ButtonPaints& paints) {
-        if (!fVisible) {
-            return;
-        }
-        canvas->drawRect(fBounds, paints.fStates[fState]);
-        SkTextUtils::Draw(canvas, &fLabel, 1, SkTextEncoding::kUTF8, fBounds.centerX(), fBounds.fBottom - 5,
-                          paints.fLabelFont, SkPaint(), SkTextUtils::kCenter_Align);
-    }
-
-    void toggle() {
-        if (++fState == fStateCount) {
-            fState = 0;
-        }
-    }
-
-    void setEnabled(bool enabled) {
-        fState = (int) enabled;
-    }
-};
-
-struct ControlPaints {
-    SkPaint fOutline;
-    SkPaint fIndicator;
-    SkPaint fFill;
-    SkPaint fLabel;
-    SkPaint fValue;
-
-    SkFont fLabelFont;
-    SkFont fValueFont;
-
-    ControlPaints() {
-        fOutline.setAntiAlias(true);
-        fOutline.setStyle(SkPaint::kStroke_Style);
-        fIndicator = fOutline;
-        fIndicator.setColor(SK_ColorRED);
-        fFill.setAntiAlias(true);
-        fFill.setColor(0x7fff0000);
-        fLabel.setAntiAlias(true);
-        fLabelFont.setSize(13.0f);
-        fValue.setAntiAlias(true);
-        fValueFont.setSize(11.0f);
-    }
-};
-
-struct UniControl {
-    SkString fName;
-    SkRect fBounds;
-    SkScalar fMin;
-    SkScalar fMax;
-    SkScalar fValLo;
-    SkScalar fYLo;
-    bool fVisible;
-
-    UniControl(const char* name, SkScalar min, SkScalar max) {
-        fName = name;
-        fValLo =  fMin = min;
-        fMax = max;
-        fVisible = false;
-
-    }
-
-    virtual ~UniControl() {}
-
-    bool contains(const SkRect& rect) {
-        return fVisible && fBounds.contains(rect);
-    }
-
-    virtual void draw(SkCanvas* canvas, const ControlPaints& paints) {
-        if (!fVisible) {
-            return;
-        }
-        canvas->drawRect(fBounds, paints.fOutline);
-        fYLo = fBounds.fTop + (fValLo - fMin) * fBounds.height() / (fMax - fMin);
-        canvas->drawLine(fBounds.fLeft - 5, fYLo, fBounds.fRight + 5, fYLo, paints.fIndicator);
-        SkString label;
-        label.printf("%0.3g", fValLo);
-        canvas->drawString(label, fBounds.fLeft + 5, fYLo - 5, paints.fValueFont, paints.fValue);
-        canvas->drawString(fName, fBounds.fLeft, fBounds.bottom() + 11, paints.fLabelFont,
-                           paints.fLabel);
-    }
-};
-
-struct BiControl : public UniControl {
-    SkScalar fValHi;
-
-    BiControl(const char* name, SkScalar min, SkScalar max)
-        : UniControl(name, min, max)
-        ,  fValHi(fMax) {
-    }
-
-    virtual ~BiControl() {}
-
-    virtual void draw(SkCanvas* canvas, const ControlPaints& paints) {
-        UniControl::draw(canvas, paints);
-        if (!fVisible || fValHi == fValLo) {
-            return;
-        }
-        SkScalar yPos = fBounds.fTop + (fValHi - fMin) * fBounds.height() / (fMax - fMin);
-        canvas->drawLine(fBounds.fLeft - 5, yPos, fBounds.fRight + 5, yPos, paints.fIndicator);
-        SkString label;
-        label.printf("%0.3g", fValHi);
-        if (yPos < fYLo + 10) {
-            yPos = fYLo + 10;
-        }
-        canvas->drawString(label, fBounds.fLeft + 5, yPos - 5, paints.fValueFont, paints.fValue);
-        SkRect fill = { fBounds.fLeft, fYLo, fBounds.fRight, yPos };
-        canvas->drawRect(fill, paints.fFill);
-    }
-};
-
-
-class MyClick : public Sample::Click {
-public:
-    enum ClickType {
-        kInvalidType = -1,
-        kPtType,
-        kVerbType,
-        kControlType,
-        kPathType,
-    } fType;
-
-    enum ControlType {
-        kInvalidControl = -1,
-        kFirstControl,
-        kFilterControl = kFirstControl,
-        kResControl,
-        kWeightControl,
-        kWidthControl,
-        kLastControl = kWidthControl,
-        kFirstButton,
-        kCubicButton = kFirstButton,
-        kConicButton,
-        kQuadButton,
-        kLineButton,
-        kLastVerbButton = kLineButton,
-        kAddButton,
-        kDeleteButton,
-        kInOutButton,
-        kFillButton,
-        kSkeletonButton,
-        kFilterButton,
-        kBisectButton,
-        kJoinButton,
-        kLastButton = kJoinButton,
-        kPathMove,
-    } fControl;
-
-    SkPath::Verb fVerb;
-    SkScalar fWeight;
-
-    MyClick(ClickType type, ControlType control)
-        : fType(type)
-        , fControl(control)
-        , fVerb((SkPath::Verb) -1)
-        , fWeight(1) {
-    }
-
-    MyClick(ClickType type, int index)
-        : fType(type)
-        , fControl((ControlType) index)
-        , fVerb((SkPath::Verb) -1)
-        , fWeight(1) {
-    }
-
-    MyClick(ClickType type, int index, SkPath::Verb verb, SkScalar weight)
-        : fType(type)
-        , fControl((ControlType) index)
-        , fVerb(verb)
-        , fWeight(weight) {
-    }
-
-    bool isButton() {
-        return kFirstButton <= fControl && fControl <= kLastButton;
-    }
-
-    int ptHit() const {
-        SkASSERT(fType == kPtType);
-        return (int) fControl;
-    }
-
-    int verbHit() const {
-        SkASSERT(fType == kVerbType);
-        return (int) fControl;
-    }
-};
-
-enum {
-    kControlCount = MyClick::kLastControl - MyClick::kFirstControl + 1,
-};
-
-static struct ControlPair {
-    UniControl* fControl;
-    MyClick::ControlType fControlType;
-} kControlList[kControlCount];
-
-enum {
-    kButtonCount = MyClick::kLastButton - MyClick::kFirstButton + 1,
-    kVerbCount = MyClick::kLastVerbButton - MyClick::kFirstButton + 1,
-};
-
-static struct ButtonPair {
-    Button* fButton;
-    MyClick::ControlType fButtonType;
-} kButtonList[kButtonCount];
-
-static void enable_verb_button(MyClick::ControlType type) {
-    for (int index = 0; index < kButtonCount; ++index) {
-        MyClick::ControlType testType = kButtonList[index].fButtonType;
-        if (MyClick::kFirstButton <= testType && testType <= MyClick::kLastVerbButton) {
-            Button* button = kButtonList[index].fButton;
-            button->setEnabled(testType == type);
-        }
-    }
-}
-
-struct Stroke;
-
-struct Active {
-    Active* fNext;
-    Stroke* fParent;
-    SkScalar fStart;
-    SkScalar fEnd;
-
-    void reset() {
-        fNext = nullptr;
-        fStart = 0;
-        fEnd = 1;
-    }
-};
-
-struct Stroke {
-    SkPath fPath;
-    Active fActive;
-    bool fInner;
-
-    void reset() {
-        fPath.reset();
-        fActive.reset();
-    }
-};
-
-struct PathUndo {
-    SkPath fPath;
-    std::unique_ptr<PathUndo> fNext;
-};
-
-class AAGeometryView : public Sample {
-    SkPaint fActivePaint;
-    SkPaint fComplexPaint;
-    SkPaint fCoveragePaint;
-    SkFont fLegendLeftFont;
-    SkFont fLegendRightFont;
-    SkPaint fPointPaint;
-    SkPaint fSkeletonPaint;
-    SkPaint fLightSkeletonPaint;
-    SkPath fPath;
-    ControlPaints fControlPaints;
-    UniControl fResControl;
-    UniControl fWeightControl;
-    UniControl fWidthControl;
-    BiControl fFilterControl;
-    ButtonPaints fButtonPaints;
-    Button fCubicButton;
-    Button fConicButton;
-    Button fQuadButton;
-    Button fLineButton;
-    Button fAddButton;
-    Button fDeleteButton;
-    Button fFillButton;
-    Button fSkeletonButton;
-    Button fFilterButton;
-    Button fBisectButton;
-    Button fJoinButton;
-    Button fInOutButton;
-    SkTArray<Stroke> fStrokes;
-    std::unique_ptr<PathUndo> fUndo;
-    int fActivePt;
-    int fActiveVerb;
-    bool fHandlePathMove;
-    bool fShowLegend;
-    bool fHideAll;
-    const int kHitToleranace = 25;
-
-public:
-
-    AAGeometryView()
-        : fResControl("error", 0, 10)
-        , fWeightControl("weight", 0, 5)
-        , fWidthControl("width", FLT_EPSILON, 100)
-        , fFilterControl("filter", 0, 255)
-        , fCubicButton('C')
-        , fConicButton('K')
-        , fQuadButton('Q')
-        , fLineButton('L')
-        , fAddButton('+')
-        , fDeleteButton('x')
-        , fFillButton('p')
-        , fSkeletonButton('s')
-        , fFilterButton('f', 3)
-        , fBisectButton('b')
-        , fJoinButton('j')
-        , fInOutButton('|')
-        , fActivePt(-1)
-        , fActiveVerb(-1)
-        , fHandlePathMove(true)
-        , fShowLegend(false)
-        , fHideAll(false)
-    {
-        fCoveragePaint.setAntiAlias(true);
-        fCoveragePaint.setColor(SK_ColorBLUE);
-        SkPaint strokePaint;
-        strokePaint.setAntiAlias(true);
-        strokePaint.setStyle(SkPaint::kStroke_Style);
-        fPointPaint = strokePaint;
-        fPointPaint.setColor(0x99ee3300);
-        fSkeletonPaint = strokePaint;
-        fSkeletonPaint.setColor(SK_ColorRED);
-        fLightSkeletonPaint = fSkeletonPaint;
-        fLightSkeletonPaint.setColor(0xFFFF7f7f);
-        fActivePaint = strokePaint;
-        fActivePaint.setColor(0x99ee3300);
-        fActivePaint.setStrokeWidth(5);
-        fComplexPaint = fActivePaint;
-        fComplexPaint.setColor(SK_ColorBLUE);
-        fLegendLeftFont.setSize(13);
-        fLegendRightFont = fLegendLeftFont;
-        construct_path(fPath);
-        fFillButton.fVisible = fSkeletonButton.fVisible = fFilterButton.fVisible
-                = fBisectButton.fVisible = fJoinButton.fVisible = fInOutButton.fVisible = true;
-        fSkeletonButton.setEnabled(true);
-        fInOutButton.setEnabled(true);
-        fJoinButton.setEnabled(true);
-        fFilterControl.fValLo = 120;
-        fFilterControl.fValHi = 141;
-        fFilterControl.fVisible = fFilterButton.fState == 2;
-        fResControl.fValLo = 5;
-        fResControl.fVisible = true;
-        fWidthControl.fValLo = 50;
-        fWidthControl.fVisible = true;
-        init_controlList();
-        init_buttonList();
-    }
-
-    ~AAGeometryView() override {
-        // Free linked list without deep recursion.
-        std::unique_ptr<PathUndo> undo = std::move(fUndo);
-        while (undo) {
-            undo = std::move(undo->fNext);
-        }
-    }
-
-    bool constructPath() {
-        construct_path(fPath);
-        return true;
-    }
-
-    void savePath(skui::InputState state) {
-        if (state != skui::InputState::kDown) {
-            return;
-        }
-        if (fUndo && fUndo->fPath == fPath) {
-            return;
-        }
-        std::unique_ptr<PathUndo> undo(new PathUndo);
-        undo->fPath = fPath;
-        undo->fNext = std::move(fUndo);
-        fUndo = std::move(undo);
-    }
-
-    bool undo() {
-        if (!fUndo) {
-            return false;
-        }
-        fPath = std::move(fUndo->fPath);
-        fUndo = std::move(fUndo->fNext);
-        validatePath();
-        return true;
-    }
-
-    void validatePath() {}
-
-    void set_controlList(int index, UniControl* control, MyClick::ControlType type) {
-        kControlList[index].fControl = control;
-        kControlList[index].fControlType = type;
-    }
-
-    #define SET_CONTROL(Name) set_controlList(index++, &f##Name##Control, \
-        MyClick::k##Name##Control)
-
-    bool hideAll() {
-        fHideAll ^= true;
-        return true;
-    }
-
-    void init_controlList() {
-        int index = 0;
-        SET_CONTROL(Width);
-        SET_CONTROL(Res);
-        SET_CONTROL(Filter);
-        SET_CONTROL(Weight);
-    }
-
-    #undef SET_CONTROL
-
-    void set_buttonList(int index, Button* button, MyClick::ControlType type) {
-        kButtonList[index].fButton = button;
-        kButtonList[index].fButtonType = type;
-    }
-
-    #define SET_BUTTON(Name) set_buttonList(index++, &f##Name##Button, \
-            MyClick::k##Name##Button)
-
-    void init_buttonList() {
-        int index = 0;
-        SET_BUTTON(Fill);
-        SET_BUTTON(Skeleton);
-        SET_BUTTON(Filter);
-        SET_BUTTON(Bisect);
-        SET_BUTTON(Join);
-        SET_BUTTON(InOut);
-        SET_BUTTON(Cubic);
-        SET_BUTTON(Conic);
-        SET_BUTTON(Quad);
-        SET_BUTTON(Line);
-        SET_BUTTON(Add);
-        SET_BUTTON(Delete);
-    }
-
-    #undef SET_BUTTON
-
-    SkString name() override { return SkString("AAGeometry"); }
-
-    bool onChar(SkUnichar) override;
-
-    void onSizeChange() override {
-        setControlButtonsPos();
-        this->INHERITED::onSizeChange();
-    }
-
-    bool pathDump() {
-        fPath.dump();
-        return true;
-    }
-
-    bool scaleDown() {
-        SkMatrix matrix;
-        SkRect bounds = fPath.getBounds();
-        matrix.setScale(1.f / 1.5f, 1.f / 1.5f, bounds.centerX(), bounds.centerY());
-        fPath.transform(matrix);
-        validatePath();
-        return true;
-    }
-
-    bool scaleToFit() {
-        SkMatrix matrix;
-        SkRect bounds = fPath.getBounds();
-        SkScalar scale = SkTMin(this->width() / bounds.width(), this->height() / bounds.height())
-                * 0.8f;
-        matrix.setScale(scale, scale, bounds.centerX(), bounds.centerY());
-        fPath.transform(matrix);
-        bounds = fPath.getBounds();
-        SkScalar offsetX = (this->width() - bounds.width()) / 2 - bounds.fLeft;
-        SkScalar offsetY = (this->height() - bounds.height()) / 2 - bounds.fTop;
-        fPath.offset(offsetX, offsetY);
-        validatePath();
-        return true;
-    }
-
-    bool scaleUp() {
-        SkMatrix matrix;
-        SkRect bounds = fPath.getBounds();
-        matrix.setScale(1.5f, 1.5f, bounds.centerX(), bounds.centerY());
-        fPath.transform(matrix);
-        validatePath();
-        return true;
-    }
-
-    void setControlButtonsPos() {
-        SkScalar widthOffset = this->width() - 100;
-        for (int index = 0; index < kControlCount; ++index) {
-            if (kControlList[index].fControl->fVisible) {
-                kControlList[index].fControl->fBounds.setXYWH(widthOffset, 30, 30, 400);
-                widthOffset -= 50;
-            }
-        }
-        SkScalar buttonOffset = 0;
-        for (int index = 0; index < kButtonCount; ++index) {
-            kButtonList[index].fButton->fBounds.setXYWH(this->width() - 50,
-                    buttonOffset += 50, 30, 30);
-        }
-    }
-
-    bool showLegend() {
-        fShowLegend ^= true;
-        return true;
-    }
-
-    void draw_bisect(SkCanvas* canvas, const SkVector& lastVector, const SkVector& vector,
-                const SkPoint& pt) {
-        SkVector lastV = lastVector;
-        SkScalar lastLen = lastVector.length();
-        SkVector nextV = vector;
-        SkScalar nextLen = vector.length();
-        if (lastLen < nextLen) {
-            lastV.setLength(nextLen);
-        } else {
-            nextV.setLength(lastLen);
-        }
-
-        SkVector bisect = { (lastV.fX + nextV.fX) / 2, (lastV.fY + nextV.fY) / 2 };
-        bisect.setLength(fWidthControl.fValLo * 2);
-        if (fBisectButton.enabled()) {
-            canvas->drawLine(pt, pt + bisect, fSkeletonPaint);
-        }
-        lastV.setLength(fWidthControl.fValLo);
-        if (fBisectButton.enabled()) {
-            canvas->drawLine(pt, {pt.fX - lastV.fY, pt.fY + lastV.fX}, fSkeletonPaint);
-        }
-        nextV.setLength(fWidthControl.fValLo);
-        if (fBisectButton.enabled()) {
-            canvas->drawLine(pt, {pt.fX + nextV.fY, pt.fY - nextV.fX}, fSkeletonPaint);
-        }
-        if (fJoinButton.enabled()) {
-            SkScalar r = fWidthControl.fValLo;
-            SkRect oval = { pt.fX - r, pt.fY - r, pt.fX + r, pt.fY + r};
-            SkScalar startAngle = SkScalarATan2(lastV.fX, -lastV.fY) * 180.f / SK_ScalarPI;
-            SkScalar endAngle = SkScalarATan2(-nextV.fX, nextV.fY) * 180.f / SK_ScalarPI;
-            if (endAngle > startAngle) {
-                canvas->drawArc(oval, startAngle, endAngle - startAngle, false, fSkeletonPaint);
-            } else {
-                canvas->drawArc(oval, startAngle, 360 - (startAngle - endAngle), false,
-                        fSkeletonPaint);
-            }
-        }
-    }
-
-    void draw_bisects(SkCanvas* canvas, bool activeOnly) {
-        SkVector firstVector, lastVector, nextLast, vector;
-        SkPoint pts[4];
-        SkPoint firstPt = { 0, 0 };  // init to avoid warning;
-        SkPath::Verb verb;
-        SkPath::Iter iter(fPath, true);
-        bool foundFirst = false;
-        int counter = -1;
-        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-            ++counter;
-            if (activeOnly && counter != fActiveVerb && counter - 1 != fActiveVerb
-                    && counter + 1 != fActiveVerb
-                    && (fActiveVerb != 1 || counter != fPath.countVerbs())) {
-                continue;
-            }
-            switch (verb) {
-                case SkPath::kLine_Verb:
-                    nextLast = pts[0] - pts[1];
-                    vector = pts[1] - pts[0];
-                    break;
-                case SkPath::kQuad_Verb: {
-                    nextLast = pts[1] - pts[2];
-                    if (SkScalarNearlyZero(nextLast.length())) {
-                        nextLast = pts[0] - pts[2];
-                    }
-                    vector = pts[1] - pts[0];
-                    if (SkScalarNearlyZero(vector.length())) {
-                        vector = pts[2] - pts[0];
-                    }
-                    if (!fBisectButton.enabled()) {
-                        break;
-                    }
-                    SkScalar t = SkFindQuadMaxCurvature(pts);
-                    if (0 < t && t < 1) {
-                        SkPoint maxPt = SkEvalQuadAt(pts, t);
-                        SkVector tangent = SkEvalQuadTangentAt(pts, t);
-                        tangent.setLength(fWidthControl.fValLo * 2);
-                        canvas->drawLine(maxPt, {maxPt.fX + tangent.fY, maxPt.fY - tangent.fX},
-                                         fSkeletonPaint);
-                    }
-                    } break;
-                case SkPath::kConic_Verb:
-                    nextLast = pts[1] - pts[2];
-                    if (SkScalarNearlyZero(nextLast.length())) {
-                        nextLast = pts[0] - pts[2];
-                    }
-                    vector = pts[1] - pts[0];
-                    if (SkScalarNearlyZero(vector.length())) {
-                        vector = pts[2] - pts[0];
-                    }
-                    if (!fBisectButton.enabled()) {
-                        break;
-                    }
-                    // FIXME : need max curvature or equivalent here
-                    break;
-                case SkPath::kCubic_Verb: {
-                    nextLast = pts[2] - pts[3];
-                    if (SkScalarNearlyZero(nextLast.length())) {
-                        nextLast = pts[1] - pts[3];
-                        if (SkScalarNearlyZero(nextLast.length())) {
-                            nextLast = pts[0] - pts[3];
-                        }
-                    }
-                    vector = pts[0] - pts[1];
-                    if (SkScalarNearlyZero(vector.length())) {
-                        vector = pts[0] - pts[2];
-                        if (SkScalarNearlyZero(vector.length())) {
-                            vector = pts[0] - pts[3];
-                        }
-                    }
-                    if (!fBisectButton.enabled()) {
-                        break;
-                    }
-                    SkScalar tMax[2];
-                    int tMaxCount = SkFindCubicMaxCurvature(pts, tMax);
-                    for (int tIndex = 0; tIndex < tMaxCount; ++tIndex) {
-                        if (0 >= tMax[tIndex] || tMax[tIndex] >= 1) {
-                            continue;
-                        }
-                        SkPoint maxPt;
-                        SkVector tangent;
-                        SkEvalCubicAt(pts, tMax[tIndex], &maxPt, &tangent, nullptr);
-                        tangent.setLength(fWidthControl.fValLo * 2);
-                        canvas->drawLine(maxPt, {maxPt.fX + tangent.fY, maxPt.fY - tangent.fX},
-                                         fSkeletonPaint);
-                    }
-                    } break;
-                case SkPath::kClose_Verb:
-                    if (foundFirst) {
-                        draw_bisect(canvas, lastVector, firstVector, firstPt);
-                        foundFirst = false;
-                    }
-                    break;
-                default:
-                    break;
-            }
-            if (SkPath::kLine_Verb <= verb && verb <= SkPath::kCubic_Verb) {
-                if (!foundFirst) {
-                    firstPt = pts[0];
-                    firstVector = vector;
-                    foundFirst = true;
-                } else {
-                    draw_bisect(canvas, lastVector, vector, pts[0]);
-                }
-                lastVector = nextLast;
-            }
-        }
-    }
-
-    void draw_legend(SkCanvas* canvas);
-
-    void draw_segment(SkCanvas* canvas) {
-        SkPoint pts[4];
-        SkPath::Verb verb;
-        SkPath::Iter iter(fPath, true);
-        int counter = -1;
-        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-            if (++counter < fActiveVerb) {
-                continue;
-            }
-            switch (verb) {
-                case SkPath::kLine_Verb:
-                    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, fActivePaint);
-                    draw_points(canvas, pts, 2);
-                    break;
-                case SkPath::kQuad_Verb: {
-                    SkPath qPath;
-                    qPath.moveTo(pts[0]);
-                    qPath.quadTo(pts[1], pts[2]);
-                    canvas->drawPath(qPath, fActivePaint);
-                    draw_points(canvas, pts, 3);
-                    } break;
-                case SkPath::kConic_Verb: {
-                    SkPath conicPath;
-                    conicPath.moveTo(pts[0]);
-                    conicPath.conicTo(pts[1], pts[2], iter.conicWeight());
-                    canvas->drawPath(conicPath, fActivePaint);
-                    draw_points(canvas, pts, 3);
-                    } break;
-                case SkPath::kCubic_Verb: {
-                    SkScalar loopT[3];
-                    int complex = SkDCubic::ComplexBreak(pts, loopT);
-                    SkPath cPath;
-                    cPath.moveTo(pts[0]);
-                    cPath.cubicTo(pts[1], pts[2], pts[3]);
-                    canvas->drawPath(cPath, complex ? fComplexPaint : fActivePaint);
-                    draw_points(canvas, pts, 4);
-                    } break;
-                default:
-                    break;
-            }
-            return;
-        }
-    }
-
-    void draw_points(SkCanvas* canvas, SkPoint* points, int count) {
-        for (int index = 0; index < count; ++index) {
-            canvas->drawCircle(points[index].fX, points[index].fY, 10, fPointPaint);
-        }
-    }
-
-    int hittest_verb(SkPoint pt, SkPath::Verb* verbPtr, SkScalar* weight) {
-        SkIntersections i;
-        SkDLine hHit = {{{pt.fX - kHitToleranace, pt.fY }, {pt.fX + kHitToleranace, pt.fY}}};
-        SkDLine vHit = {{{pt.fX, pt.fY - kHitToleranace }, {pt.fX, pt.fY + kHitToleranace}}};
-        SkPoint pts[4];
-        SkPath::Verb verb;
-        SkPath::Iter iter(fPath, true);
-        int counter = -1;
-        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-            ++counter;
-            switch (verb) {
-                case SkPath::kLine_Verb: {
-                    SkDLine line;
-                    line.set(pts);
-                    if (i.intersect(line, hHit) || i.intersect(line, vHit)) {
-                        *verbPtr = verb;
-                        *weight = 1;
-                        return counter;
-                    }
-                    } break;
-                case SkPath::kQuad_Verb: {
-                    SkDQuad quad;
-                    quad.set(pts);
-                    if (i.intersect(quad, hHit) || i.intersect(quad, vHit)) {
-                        *verbPtr = verb;
-                        *weight = 1;
-                        return counter;
-                    }
-                    } break;
-                case SkPath::kConic_Verb: {
-                    SkDConic conic;
-                    SkScalar w = iter.conicWeight();
-                    conic.set(pts, w);
-                    if (i.intersect(conic, hHit) || i.intersect(conic, vHit)) {
-                        *verbPtr = verb;
-                        *weight = w;
-                        return counter;
-                    }
-                    } break;
-                case SkPath::kCubic_Verb: {
-                    SkDCubic cubic;
-                    cubic.set(pts);
-                    if (i.intersect(cubic, hHit) || i.intersect(cubic, vHit)) {
-                        *verbPtr = verb;
-                        *weight = 1;
-                        return counter;
-                    }
-                    } break;
-                default:
-                    break;
-            }
-        }
-        return -1;
-    }
-
-    SkScalar pt_to_line(SkPoint s, SkPoint e, int x, int y) {
-        SkScalar radius = fWidthControl.fValLo;
-        SkVector adjOpp = e - s;
-        SkScalar lenSq = SkPointPriv::LengthSqd(adjOpp);
-        SkPoint rotated = {
-                (y - s.fY) * adjOpp.fY + (x - s.fX) * adjOpp.fX,
-                (y - s.fY) * adjOpp.fX - (x - s.fX) * adjOpp.fY,
-        };
-        if (rotated.fX < 0 || rotated.fX > lenSq) {
-                return -radius;
-        }
-        rotated.fY /= SkScalarSqrt(lenSq);
-        return SkTMax(-radius, SkTMin(radius, rotated.fY));
-    }
-
-    // given a line, compute the interior and exterior gradient coverage
-    bool coverage(SkPoint s, SkPoint e, uint8_t* distanceMap, int w, int h) {
-        SkScalar radius = fWidthControl.fValLo;
-        int minX = SkTMax(0, (int) (SkTMin(s.fX, e.fX) - radius));
-        int minY = SkTMax(0, (int) (SkTMin(s.fY, e.fY) - radius));
-        int maxX = SkTMin(w, (int) (SkTMax(s.fX, e.fX) + radius) + 1);
-        int maxY = SkTMin(h, (int) (SkTMax(s.fY, e.fY) + radius) + 1);
-        for (int y = minY; y < maxY; ++y) {
-            for (int x = minX; x < maxX; ++x) {
-                SkScalar ptToLineDist = pt_to_line(s, e, x, y);
-                if (ptToLineDist > -radius && ptToLineDist < radius) {
-                    SkScalar coverage = ptToLineDist / radius;
-                    add_to_map(1 - SkScalarAbs(coverage), x, y, distanceMap, w, h);
-                }
-                SkVector ptToS = { x - s.fX, y - s.fY };
-                SkScalar dist = ptToS.length();
-                if (dist < radius) {
-                    SkScalar coverage = dist / radius;
-                    add_to_map(1 - SkScalarAbs(coverage), x, y, distanceMap, w, h);
-                }
-                SkVector ptToE = { x - e.fX, y - e.fY };
-                dist = ptToE.length();
-                if (dist < radius) {
-                    SkScalar coverage = dist / radius;
-                    add_to_map(1 - SkScalarAbs(coverage), x, y, distanceMap, w, h);
-                }
-            }
-        }
-        return true;
-    }
-
-    void quad_coverage(SkPoint pts[3], uint8_t* distanceMap, int w, int h) {
-        SkScalar dist = pts[0].Distance(pts[0], pts[2]);
-        if (dist < gCurveDistance) {
-            (void) coverage(pts[0], pts[2], distanceMap, w, h);
-            return;
-        }
-        SkPoint split[5];
-        SkChopQuadAt(pts, split, 0.5f);
-        quad_coverage(&split[0], distanceMap, w, h);
-        quad_coverage(&split[2], distanceMap, w, h);
-    }
-
-    void conic_coverage(SkPoint pts[3], SkScalar weight, uint8_t* distanceMap, int w, int h) {
-        SkScalar dist = pts[0].Distance(pts[0], pts[2]);
-        if (dist < gCurveDistance) {
-            (void) coverage(pts[0], pts[2], distanceMap, w, h);
-            return;
-        }
-        SkConic split[2];
-        SkConic conic;
-        conic.set(pts, weight);
-        if (conic.chopAt(0.5f, split)) {
-            conic_coverage(split[0].fPts, split[0].fW, distanceMap, w, h);
-            conic_coverage(split[1].fPts, split[1].fW, distanceMap, w, h);
-        }
-    }
-
-    void cubic_coverage(SkPoint pts[4], uint8_t* distanceMap, int w, int h) {
-        SkScalar dist = pts[0].Distance(pts[0], pts[3]);
-        if (dist < gCurveDistance) {
-            (void) coverage(pts[0], pts[3], distanceMap, w, h);
-            return;
-        }
-        SkPoint split[7];
-        SkChopCubicAt(pts, split, 0.5f);
-        cubic_coverage(&split[0], distanceMap, w, h);
-        cubic_coverage(&split[3], distanceMap, w, h);
-    }
-
-    void path_coverage(const SkPath& path, uint8_t* distanceMap, int w, int h) {
-        memset(distanceMap, 0, sizeof(distanceMap[0]) * w * h);
-        SkPoint pts[4];
-        SkPath::Verb verb;
-        SkPath::Iter iter(path, true);
-        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-            switch (verb) {
-                case SkPath::kLine_Verb:
-                    (void) coverage(pts[0], pts[1], distanceMap, w, h);
-                    break;
-                case SkPath::kQuad_Verb:
-                    quad_coverage(pts, distanceMap, w, h);
-                    break;
-                case SkPath::kConic_Verb:
-                    conic_coverage(pts, iter.conicWeight(), distanceMap, w, h);
-                    break;
-                case SkPath::kCubic_Verb:
-                    cubic_coverage(pts, distanceMap, w, h);
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-
-    static uint8_t* set_up_dist_map(const SkImageInfo& imageInfo, SkBitmap* distMap) {
-        distMap->setInfo(imageInfo);
-        distMap->setIsVolatile(true);
-        SkAssertResult(distMap->tryAllocPixels());
-        SkASSERT((int) distMap->rowBytes() == imageInfo.width());
-        return distMap->getAddr8(0, 0);
-    }
-
-    void path_stroke(int index, SkPath* inner, SkPath* outer) {
-        #if 0
-        SkPathStroker stroker(fPath, fWidthControl.fValLo, 0,
-                SkPaint::kRound_Cap, SkPaint::kRound_Join, fResControl.fValLo);
-        SkPoint pts[4], firstPt, lastPt;
-        SkPath::Verb verb;
-        SkPath::Iter iter(fPath, true);
-        int counter = -1;
-        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-            ++counter;
-            switch (verb) {
-                case SkPath::kMove_Verb:
-                    firstPt = pts[0];
-                    break;
-                case SkPath::kLine_Verb:
-                    if (counter == index) {
-                        stroker.moveTo(pts[0]);
-                        stroker.lineTo(pts[1]);
-                        goto done;
-                    }
-                    lastPt = pts[1];
-                    break;
-                case SkPath::kQuad_Verb:
-                    if (counter == index) {
-                        stroker.moveTo(pts[0]);
-                        stroker.quadTo(pts[1], pts[2]);
-                        goto done;
-                    }
-                    lastPt = pts[2];
-                    break;
-                case SkPath::kConic_Verb:
-                    if (counter == index) {
-                        stroker.moveTo(pts[0]);
-                        stroker.conicTo(pts[1], pts[2], iter.conicWeight());
-                        goto done;
-                    }
-                    lastPt = pts[2];
-                    break;
-                case SkPath::kCubic_Verb:
-                    if (counter == index) {
-                        stroker.moveTo(pts[0]);
-                        stroker.cubicTo(pts[1], pts[2], pts[3]);
-                        goto done;
-                    }
-                    lastPt = pts[3];
-                    break;
-                case SkPath::kClose_Verb:
-                    if (counter == index) {
-                        stroker.moveTo(lastPt);
-                        stroker.lineTo(firstPt);
-                        goto done;
-                    }
-                    break;
-                case SkPath::kDone_Verb:
-                    break;
-                default:
-                    SkASSERT(0);
-            }
-        }
-    done:
-        *inner = stroker.fInner;
-        *outer = stroker.fOuter;
-#endif
-    }
-
-    void draw_stroke(SkCanvas* canvas, int active) {
-        SkPath inner, outer;
-        path_stroke(active, &inner, &outer);
-        canvas->drawPath(inner, fSkeletonPaint);
-        canvas->drawPath(outer, fSkeletonPaint);
-    }
-
-    void gather_strokes() {
-        fStrokes.reset();
-        for (int index = 0; index < fPath.countVerbs(); ++index) {
-            Stroke& inner = fStrokes.push_back();
-            inner.reset();
-            inner.fInner = true;
-            Stroke& outer = fStrokes.push_back();
-            outer.reset();
-            outer.fInner = false;
-            path_stroke(index, &inner.fPath, &outer.fPath);
-        }
-    }
-
-    void trim_strokes() {
-        // eliminate self-itersecting loops
-        // trim outside edges
-        gather_strokes();
-        for (int index = 0; index < fStrokes.count(); ++index) {
-            SkPath& outPath = fStrokes[index].fPath;
-            for (int inner = 0; inner < fStrokes.count(); ++inner) {
-                if (index == inner) {
-                    continue;
-                }
-                SkPath& inPath = fStrokes[inner].fPath;
-                if (!outPath.getBounds().intersects(inPath.getBounds())) {
-                    continue;
-                }
-
-            }
-        }
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-#if 0
-        SkDEBUGCODE(SkDebugStrokeGlobals debugGlobals);
-        SkOpAA aaResult(fPath, fWidthControl.fValLo, fResControl.fValLo
-                SkDEBUGPARAMS(&debugGlobals));
-#endif
-        SkPath strokePath;
-//        aaResult.simplify(&strokePath);
-        canvas->drawPath(strokePath, fSkeletonPaint);
-        SkRect bounds = fPath.getBounds();
-        SkScalar radius = fWidthControl.fValLo;
-        int w = (int) (bounds.fRight + radius + 1);
-        int h = (int) (bounds.fBottom + radius + 1);
-        SkImageInfo imageInfo = SkImageInfo::MakeA8(w, h);
-        SkBitmap distMap;
-        uint8_t* distanceMap = set_up_dist_map(imageInfo, &distMap);
-        path_coverage(fPath, distanceMap, w, h);
-        if (fFillButton.enabled()) {
-            canvas->drawPath(fPath, fCoveragePaint);
-        }
-        if (fFilterButton.fState == 2
-                && (0 < fFilterControl.fValLo || fFilterControl.fValHi < 255)) {
-            SkBitmap filteredMap;
-            uint8_t* filtered = set_up_dist_map(imageInfo, &filteredMap);
-            filter_coverage(distanceMap, sizeof(uint8_t) * w * h, (uint8_t) fFilterControl.fValLo,
-                    (uint8_t) fFilterControl.fValHi, filtered);
-            canvas->drawBitmap(filteredMap, 0, 0, &fCoveragePaint);
-        } else if (fFilterButton.enabled()) {
-            canvas->drawBitmap(distMap, 0, 0, &fCoveragePaint);
-        }
-        if (fSkeletonButton.enabled()) {
-            canvas->drawPath(fPath, fActiveVerb >= 0 ? fLightSkeletonPaint : fSkeletonPaint);
-        }
-        if (fActiveVerb >= 0) {
-            draw_segment(canvas);
-        }
-        if (fBisectButton.enabled() || fJoinButton.enabled()) {
-            draw_bisects(canvas, fActiveVerb >= 0);
-        }
-        if (fInOutButton.enabled()) {
-            if (fActiveVerb >= 0) {
-                draw_stroke(canvas, fActiveVerb);
-            } else {
-                for (int index = 0; index < fPath.countVerbs(); ++index) {
-                    draw_stroke(canvas, index);
-                }
-            }
-        }
-        if (fHideAll) {
-            return;
-        }
-        for (int index = 0; index < kControlCount; ++index) {
-            kControlList[index].fControl->draw(canvas, fControlPaints);
-        }
-        for (int index = 0; index < kButtonCount; ++index) {
-            kButtonList[index].fButton->draw(canvas, fButtonPaints);
-        }
-        if (fShowLegend) {
-            draw_legend(canvas);
-        }
-
-#if 0
-        SkPaint paint;
-        paint.setARGB(255, 34, 31, 31);
-        paint.setAntiAlias(true);
-
-        SkPath path;
-        path.moveTo(18,439);
-        path.lineTo(414,439);
-        path.lineTo(414,702);
-        path.lineTo(18,702);
-        path.lineTo(18,439);
-
-        path.moveTo(19,701);
-        path.lineTo(413,701);
-        path.lineTo(413,440);
-        path.lineTo(19,440);
-        path.lineTo(19,701);
-        path.close();
-        canvas->drawPath(path, paint);
-
-        canvas->scale(1.0f, -1.0f);
-        canvas->translate(0.0f, -800.0f);
-        canvas->drawPath(path, paint);
-#endif
-
-    }
-
-    int hittest_pt(SkPoint pt) {
-        for (int index = 0; index < fPath.countPoints(); ++index) {
-            if (SkPoint::Distance(fPath.getPoint(index), pt) <= kHitToleranace * 2) {
-                return index;
-            }
-        }
-        return -1;
-    }
-
-    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
-        SkPoint pt = {x, y};
-        int ptHit = hittest_pt(pt);
-        if (ptHit >= 0) {
-            return new MyClick(MyClick::kPtType, ptHit);
-        }
-        SkPath::Verb verb;
-        SkScalar weight;
-        int verbHit = hittest_verb(pt, &verb, &weight);
-        if (verbHit >= 0) {
-            return new MyClick(MyClick::kVerbType, verbHit, verb, weight);
-        }
-        if (!fHideAll) {
-            const SkRect& rectPt = SkRect::MakeXYWH(x, y, 1, 1);
-            for (int index = 0; index < kControlCount; ++index) {
-                if (kControlList[index].fControl->contains(rectPt)) {
-                    return new MyClick(MyClick::kControlType,
-                            kControlList[index].fControlType);
-                }
-            }
-            for (int index = 0; index < kButtonCount; ++index) {
-                if (kButtonList[index].fButton->contains(rectPt)) {
-                    return new MyClick(MyClick::kControlType, kButtonList[index].fButtonType);
-                }
-            }
-        }
-        fLineButton.fVisible = fQuadButton.fVisible = fConicButton.fVisible
-                = fCubicButton.fVisible = fWeightControl.fVisible = fAddButton.fVisible
-                = fDeleteButton.fVisible = false;
-        fActiveVerb = -1;
-        fActivePt = -1;
-        if (fHandlePathMove) {
-            return new MyClick(MyClick::kPathType, MyClick::kPathMove);
-        }
-        return nullptr;
-    }
-
-    static SkScalar MapScreenYtoValue(int y, const UniControl& control) {
-        return SkTMin(1.f, SkTMax(0.f,
-                SkIntToScalar(y) - control.fBounds.fTop) / control.fBounds.height())
-                * (control.fMax - control.fMin) + control.fMin;
-    }
-
-    bool onClick(Click* click) override {
-        MyClick* myClick = (MyClick*) click;
-        switch (myClick->fType) {
-            case MyClick::kPtType: {
-                savePath(click->fState);
-                fActivePt = myClick->ptHit();
-                SkPoint pt = fPath.getPoint((int) myClick->fControl);
-                pt.offset(SkIntToScalar(click->fCurr.fX - click->fPrev.fX),
-                        SkIntToScalar(click->fCurr.fY - click->fPrev.fY));
-                set_path_pt(fActivePt, pt, &fPath);
-                validatePath();
-                return true;
-                }
-            case MyClick::kPathType:
-                savePath(click->fState);
-                fPath.offset(SkIntToScalar(click->fCurr.fX - click->fPrev.fX),
-                        SkIntToScalar(click->fCurr.fY - click->fPrev.fY));
-                validatePath();
-                return true;
-            case MyClick::kVerbType: {
-                fActiveVerb = myClick->verbHit();
-                fLineButton.fVisible = fQuadButton.fVisible = fConicButton.fVisible
-                        = fCubicButton.fVisible = fAddButton.fVisible = fDeleteButton.fVisible
-                        = true;
-                fLineButton.setEnabled(myClick->fVerb == SkPath::kLine_Verb);
-                fQuadButton.setEnabled(myClick->fVerb == SkPath::kQuad_Verb);
-                fConicButton.setEnabled(myClick->fVerb == SkPath::kConic_Verb);
-                fCubicButton.setEnabled(myClick->fVerb == SkPath::kCubic_Verb);
-                fWeightControl.fValLo = myClick->fWeight;
-                fWeightControl.fVisible = myClick->fVerb == SkPath::kConic_Verb;
-                } break;
-            case MyClick::kControlType: {
-                if (click->fState != skui::InputState::kDown && myClick->isButton()) {
-                    return true;
-                }
-                switch (myClick->fControl) {
-                    case MyClick::kFilterControl: {
-                        SkScalar val = MapScreenYtoValue(click->fCurr.fY, fFilterControl);
-                        if (val - fFilterControl.fValLo < fFilterControl.fValHi - val) {
-                            fFilterControl.fValLo = SkTMax(0.f, val);
-                        } else {
-                            fFilterControl.fValHi = SkTMin(255.f, val);
-                        }
-                        } break;
-                    case MyClick::kResControl:
-                        fResControl.fValLo = MapScreenYtoValue(click->fCurr.fY, fResControl);
-                        break;
-                    case MyClick::kWeightControl: {
-                        savePath(click->fState);
-                        SkScalar w = MapScreenYtoValue(click->fCurr.fY, fWeightControl);
-                        set_path_weight(fActiveVerb, w, &fPath);
-                        validatePath();
-                        fWeightControl.fValLo = w;
-                        } break;
-                    case MyClick::kWidthControl:
-                        fWidthControl.fValLo = MapScreenYtoValue(click->fCurr.fY, fWidthControl);
-                        break;
-                    case MyClick::kLineButton:
-                        savePath(click->fState);
-                        enable_verb_button(myClick->fControl);
-                        fWeightControl.fVisible = false;
-                        set_path_verb(fActiveVerb, SkPath::kLine_Verb, &fPath, 1);
-                        validatePath();
-                        break;
-                    case MyClick::kQuadButton:
-                        savePath(click->fState);
-                        enable_verb_button(myClick->fControl);
-                        fWeightControl.fVisible = false;
-                        set_path_verb(fActiveVerb, SkPath::kQuad_Verb, &fPath, 1);
-                        validatePath();
-                        break;
-                    case MyClick::kConicButton: {
-                        savePath(click->fState);
-                        enable_verb_button(myClick->fControl);
-                        fWeightControl.fVisible = true;
-                        const SkScalar defaultConicWeight = 1.f / SkScalarSqrt(2);
-                        set_path_verb(fActiveVerb, SkPath::kConic_Verb, &fPath, defaultConicWeight);
-                        validatePath();
-                        fWeightControl.fValLo = get_path_weight(fActiveVerb, fPath);
-                        } break;
-                    case MyClick::kCubicButton:
-                        savePath(click->fState);
-                        enable_verb_button(myClick->fControl);
-                        fWeightControl.fVisible = false;
-                        set_path_verb(fActiveVerb, SkPath::kCubic_Verb, &fPath, 1);
-                        validatePath();
-                        break;
-                    case MyClick::kAddButton:
-                        savePath(click->fState);
-                        add_path_segment(fActiveVerb, &fPath);
-                        validatePath();
-                        if (fWeightControl.fVisible) {
-                            fWeightControl.fValLo = get_path_weight(fActiveVerb, fPath);
-                        }
-                        break;
-                    case MyClick::kDeleteButton:
-                        savePath(click->fState);
-                        delete_path_segment(fActiveVerb, &fPath);
-                        validatePath();
-                        break;
-                    case MyClick::kFillButton:
-                        fFillButton.toggle();
-                        break;
-                    case MyClick::kSkeletonButton:
-                        fSkeletonButton.toggle();
-                        break;
-                    case MyClick::kFilterButton:
-                        fFilterButton.toggle();
-                        fFilterControl.fVisible = fFilterButton.fState == 2;
-                        break;
-                    case MyClick::kBisectButton:
-                        fBisectButton.toggle();
-                        break;
-                    case MyClick::kJoinButton:
-                        fJoinButton.toggle();
-                        break;
-                    case MyClick::kInOutButton:
-                        fInOutButton.toggle();
-                        break;
-                    default:
-                        SkASSERT(0);
-                        break;
-                }
-            } break;
-            default:
-                SkASSERT(0);
-                break;
-        }
-        setControlButtonsPos();
-        return true;
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-static struct KeyCommand {
-    char fKey;
-    char fAlternate;
-    const char* fDescriptionL;
-    const char* fDescriptionR;
-    bool (AAGeometryView::*fFunction)();
-} kKeyCommandList[] = {
-    { ' ',  0,  "space",   "center path", &AAGeometryView::scaleToFit },
-    { '-',  0,  "-",          "zoom out", &AAGeometryView::scaleDown },
-    { '+', '=', "+/=",         "zoom in", &AAGeometryView::scaleUp },
-    { 'D',  0,  "D",   "dump to console", &AAGeometryView::pathDump },
-    { 'H',  0,  "H",     "hide controls", &AAGeometryView::hideAll },
-    { 'R',  0,  "R",        "reset path", &AAGeometryView::constructPath },
-    { 'Z',  0,  "Z",              "undo", &AAGeometryView::undo },
-    { '?',  0,  "?",       "show legend", &AAGeometryView::showLegend },
-};
-
-const int kKeyCommandCount = (int) SK_ARRAY_COUNT(kKeyCommandList);
-
-void AAGeometryView::draw_legend(SkCanvas* canvas) {
-    SkScalar bottomOffset = this->height() - 10;
-    for (int index = kKeyCommandCount - 1; index >= 0; --index) {
-        bottomOffset -= 15;
-        SkTextUtils::DrawString(canvas, kKeyCommandList[index].fDescriptionL, this->width() - 160, bottomOffset,
-                                fLegendLeftFont, SkPaint());
-        SkTextUtils::DrawString(canvas, kKeyCommandList[index].fDescriptionR,
-                this->width() - 20, bottomOffset,
-                fLegendRightFont, SkPaint(), SkTextUtils::kRight_Align);
-    }
-}
-
-bool AAGeometryView::onChar(SkUnichar uni) {
-        for (int index = 0; index < kButtonCount; ++index) {
-            Button* button = kButtonList[index].fButton;
-            if (button->fVisible && uni == button->fLabel) {
-                MyClick click(MyClick::kControlType, kButtonList[index].fButtonType);
-                click.fState = skui::InputState::kDown;
-                (void) this->onClick(&click);
-                return true;
-            }
-        }
-        for (int index = 0; index < kKeyCommandCount; ++index) {
-            KeyCommand& keyCommand = kKeyCommandList[index];
-            if (uni == keyCommand.fKey || uni == keyCommand.fAlternate) {
-                return (this->*keyCommand.fFunction)();
-            }
-        }
-        if (('A' <= uni && uni <= 'Z') || ('a' <= uni && uni <= 'z')) {
-            for (int index = 0; index < kButtonCount; ++index) {
-                Button* button = kButtonList[index].fButton;
-                if (button->fVisible && (uni & ~0x20) == (button->fLabel & ~0x20)) {
-                    MyClick click(MyClick::kControlType, kButtonList[index].fButtonType);
-                    click.fState = skui::InputState::kDown;
-                    (void) this->onClick(&click);
-                    return true;
-                }
-            }
-        }
-        return false;
-}
-
-DEF_SAMPLE( return new AAGeometryView; )
diff --git a/third_party/skia/samplecode/SampleAARectModes.cpp b/third_party/skia/samplecode/SampleAARectModes.cpp
index a3c5ea3..99d8f77 100644
--- a/third_party/skia/samplecode/SampleAARectModes.cpp
+++ b/third_party/skia/samplecode/SampleAARectModes.cpp
@@ -62,10 +62,8 @@
     *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC,
                                                              0xCC, 0xCC);
 
-    SkMatrix m;
-    m.setScale(SkIntToScalar(6), SkIntToScalar(6));
-
-    return bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &m);
+    return bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, SkSamplingOptions(),
+                         SkMatrix::Scale(6, 6));
 }
 
 class AARectsModesView : public Sample {
diff --git a/third_party/skia/samplecode/SampleAARects.cpp b/third_party/skia/samplecode/SampleAARects.cpp
index 834a1e5..b7cc5e8 100644
--- a/third_party/skia/samplecode/SampleAARects.cpp
+++ b/third_party/skia/samplecode/SampleAARects.cpp
@@ -49,7 +49,8 @@
         SkPaint bluePaint;
         bluePaint.setARGB(0xff, 0x0, 0x0, 0xff);
         SkPaint bmpPaint;
-        bmpPaint.setShader(fBitmap.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
+        bmpPaint.setShader(fBitmap.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
+                                              SkSamplingOptions()));
         bluePaint.setStrokeWidth(3);
         bmpPaint.setStrokeWidth(3);
 
@@ -170,7 +171,7 @@
 
 private:
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleAndroidShadows.cpp b/third_party/skia/samplecode/SampleAndroidShadows.cpp
index a4518f2..50c626e 100644
--- a/third_party/skia/samplecode/SampleAndroidShadows.cpp
+++ b/third_party/skia/samplecode/SampleAndroidShadows.cpp
@@ -9,7 +9,6 @@
 #include "include/core/SkColorFilter.h"
 #include "include/core/SkPath.h"
 #include "include/core/SkPoint3.h"
-#include "include/effects/SkBlurMaskFilter.h"
 #include "include/pathops/SkPathOps.h"
 #include "include/utils/SkCamera.h"
 #include "include/utils/SkShadowUtils.h"
@@ -192,55 +191,55 @@
 
         paint.setColor(SK_ColorWHITE);
         canvas->translate(200, 90);
-        zPlaneParams.fZ = SkTMax(1.0f, 2 + fZDelta);
+        zPlaneParams.fZ = std::max(1.0f, 2 + fZDelta);
         this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
                                lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
 
         paint.setColor(SK_ColorRED);
         canvas->translate(250, 0);
-        zPlaneParams.fZ = SkTMax(1.0f, 8 + fZDelta);
+        zPlaneParams.fZ = std::max(1.0f, 8 + fZDelta);
         this->drawShadowedPath(canvas, fRectPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
                                lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
 
         paint.setColor(SK_ColorBLUE);
         canvas->translate(-250, 110);
-        zPlaneParams.fZ = SkTMax(1.0f, 12 + fZDelta);
+        zPlaneParams.fZ = std::max(1.0f, 12 + fZDelta);
         this->drawShadowedPath(canvas, fCirclePath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
                                lightPos, kLightWidth, fAnimAlpha*0.5f);
 
         paint.setColor(SK_ColorGREEN);
         canvas->translate(250, 0);
-        zPlaneParams.fZ = SkTMax(1.0f, 64 + fZDelta);
+        zPlaneParams.fZ = std::max(1.0f, 64 + fZDelta);
         this->drawShadowedPath(canvas, fRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
                                lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
 
         paint.setColor(SK_ColorYELLOW);
         canvas->translate(-250, 110);
-        zPlaneParams.fZ = SkTMax(1.0f, 8 + fZDelta);
+        zPlaneParams.fZ = std::max(1.0f, 8 + fZDelta);
         this->drawShadowedPath(canvas, fFunkyRRPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
                                lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
 
         paint.setColor(SK_ColorCYAN);
         canvas->translate(250, 0);
-        zPlaneParams.fZ = SkTMax(1.0f, 16 + fZDelta);
+        zPlaneParams.fZ = std::max(1.0f, 16 + fZDelta);
         this->drawShadowedPath(canvas, fCubicPath, zPlaneParams, paint, fAnimAlpha*kAmbientAlpha,
                                lightPos, kLightWidth, fAnimAlpha*kSpotAlpha);
 
         paint.setColor(SK_ColorWHITE);
         canvas->translate(250, -180);
-        zPlaneParams.fZ = SkTMax(1.0f, 8 + fZDelta);
+        zPlaneParams.fZ = std::max(1.0f, 8 + fZDelta);
         this->drawShadowedPath(canvas, fStarPath, zPlaneParams, paint,
                                kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
 
         paint.setColor(SK_ColorWHITE);
         canvas->translate(150, 0);
-        zPlaneParams.fZ = SkTMax(1.0f, 2 + fZDelta);
+        zPlaneParams.fZ = std::max(1.0f, 2 + fZDelta);
         this->drawShadowedPath(canvas, fNotchPath, zPlaneParams, paint,
                                kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
 
         paint.setColor(SK_ColorWHITE);
         canvas->translate(200, 0);
-        zPlaneParams.fZ = SkTMax(1.0f, 16 + fZDelta);
+        zPlaneParams.fZ = std::max(1.0f, 16 + fZDelta);
         this->drawShadowedPath(canvas, fTabPath, zPlaneParams, paint,
                                kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
 
@@ -252,7 +251,7 @@
 
         paint.setColor(SK_ColorMAGENTA);
         canvas->translate(-725, 240);
-        zPlaneParams.fZ = SkTMax(1.0f, 32 + fZDelta);
+        zPlaneParams.fZ = std::max(1.0f, 32 + fZDelta);
         this->drawShadowedPath(canvas, tmpPath, zPlaneParams, paint, .1f,
                                lightPos, kLightWidth, .5f);
 
@@ -262,7 +261,7 @@
         Op(fSquareRRectPath, tmpClipPathBug, kIntersect_SkPathOp, &tmpPath);
 
         canvas->translate(250, 0);
-        zPlaneParams.fZ = SkTMax(1.0f, 32 + fZDelta);
+        zPlaneParams.fZ = std::max(1.0f, 32 + fZDelta);
         this->drawShadowedPath(canvas, tmpPath, zPlaneParams, paint, .1f,
                                lightPos, kLightWidth, .5f);
 
@@ -282,7 +281,7 @@
         SkScalar radians = SkDegreesToRadians(fAnimAngle);
         zPlaneParams = SkPoint3::Make(0,
                                       SkScalarSin(radians),
-                                      SkTMax(1.0f, 16 + fZDelta) - SkScalarSin(radians)*pivot.fY);
+                                      std::max(1.0f, 16 + fZDelta) - SkScalarSin(radians)*pivot.fY);
         this->drawShadowedPath(canvas, fWideRectPath, zPlaneParams, paint, .1f,
                                lightPos, kLightWidth, .5f);
 
@@ -298,7 +297,7 @@
         canvas->setMatrix(persp);
         zPlaneParams = SkPoint3::Make(-SkScalarSin(radians),
                                       0,
-                                      SkTMax(1.0f, 32 + fZDelta) + SkScalarSin(radians)*pivot.fX);
+                                      std::max(1.0f, 32 + fZDelta) + SkScalarSin(radians)*pivot.fX);
         this->drawShadowedPath(canvas, fWideOvalPath, zPlaneParams, paint, .1f,
                                lightPos, kLightWidth, .5f);
 
@@ -313,7 +312,7 @@
         canvas->setMatrix(persp);
         zPlaneParams = SkPoint3::Make(-SkScalarSin(radians),
                                       0,
-                                      SkTMax(1.0f, 8 + fZDelta) + SkScalarSin(radians)*pivot.fX);
+                                      std::max(1.0f, 8 + fZDelta) + SkScalarSin(radians)*pivot.fX);
         this->drawShadowedPath(canvas, fStarPath, zPlaneParams, paint, .1f,
                                lightPos, kLightWidth, .5f);
     }
@@ -328,7 +327,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleAnimatedImage.cpp b/third_party/skia/samplecode/SampleAnimatedImage.cpp
index da6ac28..1ca7ac1 100644
--- a/third_party/skia/samplecode/SampleAnimatedImage.cpp
+++ b/third_party/skia/samplecode/SampleAnimatedImage.cpp
@@ -104,11 +104,10 @@
             switch (uni) {
                 case kPauseKey:
                     fRunning = !fRunning;
-                    if (fImage->isFinished()) {
-                        // fall through
-                    } else {
+                    if (!fImage->isFinished()) {
                         return true;
                     }
+                    [[fallthrough]];
                 case kResetKey:
                     fImage->reset();
                     fCurrentTime = fLastWallTime;
diff --git a/third_party/skia/samplecode/SampleAnimatedText.cpp b/third_party/skia/samplecode/SampleAnimatedText.cpp
index 8e7ed0e..80aafdc 100644
--- a/third_party/skia/samplecode/SampleAnimatedText.cpp
+++ b/third_party/skia/samplecode/SampleAnimatedText.cpp
@@ -8,6 +8,7 @@
 #include "include/core/SkCanvas.h"
 #include "include/core/SkColorFilter.h"
 #include "include/core/SkColorPriv.h"
+#include "include/core/SkFont.h"
 #include "include/core/SkImage.h"
 #include "include/core/SkTime.h"
 #include "include/core/SkTypeface.h"
@@ -16,8 +17,8 @@
 #include "src/utils/SkUTF.h"
 
 #if SK_SUPPORT_GPU
-#include "include/gpu/GrContext.h"
-#include "src/gpu/GrContextPriv.h"
+#include "include/gpu/GrDirectContext.h"
+#include "src/gpu/GrDirectContextPriv.h"
 #endif
 
 SkRandom gRand;
@@ -62,17 +63,18 @@
 
         SkPaint paint;
         paint.setAntiAlias(true);
-        paint.setFilterQuality(kMedium_SkFilterQuality);
 
         canvas->save();
 
 #if SK_SUPPORT_GPU
-        GrContext* grContext = canvas->getGrContext();
-        if (grContext) {
-            sk_sp<SkImage> image = grContext->priv().testingOnly_getFontAtlasImage(
+        auto direct = GrAsDirectContext(canvas->recordingContext());
+        if (direct) {
+            SkSamplingOptions sampling(SkFilterMode::kLinear, SkMipmapMode::kNearest);
+            sk_sp<SkImage> image = direct->priv().testingOnly_getFontAtlasImage(
                                                                 GrMaskFormat::kA8_GrMaskFormat);
-            canvas->drawImageRect(image,
-                                  SkRect::MakeXYWH(512.0f, 10.0f, 512.0f, 512.0f), &paint);
+            const SkRect rect = SkRect::MakeXYWH(512.0f, 10.0f, 512.0f, 512.0f);
+            canvas->drawImageRect(image.get(), rect, rect, sampling, &paint,
+                                  SkCanvas::kFast_SrcRectConstraint);
         }
 #endif
         canvas->translate(180, 180);
diff --git a/third_party/skia/samplecode/SampleAtlas.cpp b/third_party/skia/samplecode/SampleAtlas.cpp
index 85d267c..8f7f116 100644
--- a/third_party/skia/samplecode/SampleAtlas.cpp
+++ b/third_party/skia/samplecode/SampleAtlas.cpp
@@ -13,27 +13,30 @@
 #include "include/utils/SkRandom.h"
 #include "include/utils/SkTextUtils.h"
 #include "samplecode/Sample.h"
+#include "src/core/SkPaintPriv.h"
 
 typedef void (*DrawAtlasProc)(SkCanvas*, SkImage*, const SkRSXform[], const SkRect[],
-                              const SkColor[], int, const SkRect*, const SkPaint*);
+                              const SkColor[], int, const SkRect*, const SkSamplingOptions&,
+                              const SkPaint*);
 
 static void draw_atlas(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
                        const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
-                       const SkPaint* paint) {
-    canvas->drawAtlas(atlas, xform, tex, colors, count, SkBlendMode::kModulate, cull, paint);
+                       const SkSamplingOptions& sampling, const SkPaint* paint) {
+    canvas->drawAtlas(atlas, xform, tex, colors, count, SkBlendMode::kModulate,
+                      sampling, cull, paint);
 }
 
 static void draw_atlas_sim(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
                            const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
-                           const SkPaint* paint) {
+                           const SkSamplingOptions& sampling, const SkPaint* paint) {
     for (int i = 0; i < count; ++i) {
         SkMatrix matrix;
         matrix.setRSXform(xform[i]);
 
         canvas->save();
         canvas->concat(matrix);
-        canvas->drawImageRect(atlas, tex[i], tex[i].makeOffset(-tex[i].x(), -tex[i].y()), paint,
-                              SkCanvas::kFast_SrcRectConstraint);
+        canvas->drawImageRect(atlas, tex[i], tex[i].makeOffset(-tex[i].x(), -tex[i].y()),
+                              sampling, paint, SkCanvas::kFast_SrcRectConstraint);
         canvas->restore();
     }
 }
@@ -183,11 +186,11 @@
             }
         }
         SkPaint paint;
-        paint.setFilterQuality(kLow_SkFilterQuality);
+        SkSamplingOptions sampling(SkFilterMode::kLinear);
 
         const SkRect cull = this->getBounds();
         const SkColor* colorsPtr = fUseColors ? colors : nullptr;
-        fProc(canvas, fAtlas.get(), xform, fTex, colorsPtr, N, &cull, &paint);
+        fProc(canvas, fAtlas.get(), xform, fTex, colorsPtr, N, &cull, sampling, &paint);
     }
 
     SkRect onGetBounds() override {
@@ -198,7 +201,7 @@
     }
 
 private:
-    typedef SkDrawable INHERITED;
+    using INHERITED = SkDrawable;
 };
 
 class DrawAtlasView : public Sample {
@@ -239,7 +242,7 @@
 #endif
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleAudio.cpp b/third_party/skia/samplecode/SampleAudio.cpp
new file mode 100644
index 0000000..a3347d7
--- /dev/null
+++ b/third_party/skia/samplecode/SampleAudio.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/core/SkCanvas.h"
+#include "include/core/SkData.h"
+#include "modules/audioplayer/SkAudioPlayer.h"
+#include "samplecode/Sample.h"
+#include "src/core/SkUtils.h"
+#include "tools/Resources.h"
+
+class AudioView : public Sample {
+    std::unique_ptr<SkAudioPlayer> fPlayer;
+    SkRect                         fBar;
+
+public:
+    AudioView() {}
+
+protected:
+    SkString name() override { return SkString("Audio"); }
+
+    void onOnceBeforeDraw() override {
+        auto data = SkData::MakeFromFileName("/Users/reed/skia/mp3/scott-joplin-peacherine-rag.mp3");
+        if (data) {
+            fPlayer = SkAudioPlayer::Make(data);
+
+            SkDebugf("make: dur:%g time%g state:%d",
+                     fPlayer->duration(),
+                     fPlayer->time(),
+                     (int)fPlayer->state());
+        }
+
+        fBar = { 10, 10, 510, 30 };
+    }
+
+    void onDrawContent(SkCanvas* canvas) override {
+        if (!fPlayer) {
+            return;
+        }
+
+        SkPaint p;
+        p.setColor(0xFFCCCCCC);
+        canvas->drawRect(fBar, p);
+
+        p.setColor(fPlayer->isPlaying() ? SK_ColorBLUE : 0xFF8888FF);
+        SkRect r = fBar;
+        r.fRight = r.fLeft + (float)fPlayer->normalizedTime() * r.width();
+        canvas->drawRect(r, p);
+    }
+
+    bool onChar(SkUnichar c) override {
+        if (c == ' ') {
+            switch (fPlayer->state()) {
+                case SkAudioPlayer::State::kPlaying: fPlayer->pause(); break;
+                case SkAudioPlayer::State::kPaused:  fPlayer->play(); break;
+                case SkAudioPlayer::State::kStopped: fPlayer->play(); break;
+            }
+            return true;
+        }
+        return this->INHERITED::onChar(c);
+    }
+
+    Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override {
+        if (fPlayer && fBar.contains(x, y)) {
+            bool wasPlaying = fPlayer->isPlaying();
+            if (wasPlaying) {
+                fPlayer->pause();
+            }
+            return new Click([this, wasPlaying](Click* click) {
+                if (fBar.contains(click->fCurr.fX, click->fCurr.fY)) {
+                    fPlayer->setNormalizedTime((click->fCurr.fX - fBar.fLeft) / fBar.width());
+                }
+
+                if (click->fState == skui::InputState::kUp) {
+                    if (wasPlaying) {
+                        fPlayer->play();
+                    }
+                }
+                return true;
+            });
+        }
+        return nullptr;
+    }
+
+    bool onAnimate(double /*nanos*/) override {
+        return true;
+    }
+
+private:
+    using INHERITED = Sample;
+};
+DEF_SAMPLE( return new AudioView; )
diff --git a/third_party/skia/samplecode/SampleBackdropBounds.cpp b/third_party/skia/samplecode/SampleBackdropBounds.cpp
deleted file mode 100644
index d16d0b9..0000000
--- a/third_party/skia/samplecode/SampleBackdropBounds.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright 2019 Google LLC
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "samplecode/Sample.h"
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkColor.h"
-#include "include/core/SkFont.h"
-#include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
-#include "include/core/SkPoint.h"
-#include "include/core/SkRect.h"
-
-#include "tools/ToolUtils.h"
-
-static constexpr float kLineHeight = 16.f;
-static constexpr float kLineInset = 8.f;
-
-static float print_size(SkCanvas* canvas, const char* prefix, const SkIRect& rect,
-                        float x, float y, const SkFont& font, const SkPaint& paint) {
-    canvas->drawString(prefix, x, y, font, paint);
-    y += kLineHeight;
-    SkString sz;
-    sz.appendf("%d x %d", rect.width(), rect.height());
-    canvas->drawString(sz, x, y, font, paint);
-    return y + kLineHeight;
-}
-
-static float print_info(SkCanvas* canvas, const SkIRect& origLayerBounds,
-                        const SkIRect& localLayerBounds, const SkIRect& filterInputBounds,
-                        const SkIRect& devLayerBounds) {
-    SkFont font(nullptr, 12);
-    SkPaint text;
-    text.setAntiAlias(true);
-
-    float y = kLineHeight;
-
-    text.setColor(SK_ColorBLACK);
-    y = print_size(canvas, "Orig layer", origLayerBounds, kLineInset, y, font, text);
-    text.setColor(SK_ColorRED);
-    y = print_size(canvas, "Filter layer", localLayerBounds, kLineInset, y, font, text);
-    text.setColor(SK_ColorBLUE);
-    y = print_size(canvas, "Filter input", filterInputBounds, kLineInset, y, font, text);
-    text.setColor(SK_ColorMAGENTA);
-    y = print_size(canvas, "Backdrop size", devLayerBounds, kLineInset, y, font, text);
-
-    return y;
-}
-
-static SkPaint line_paint(SkScalar width, SkColor color) {
-    SkPaint paint;
-    paint.setColor(color);
-    paint.setStrokeWidth(width);
-    paint.setStyle(SkPaint::kStroke_Style);
-    paint.setAntiAlias(true);
-    return paint;
-}
-
-class BackdropBoundsSample : public Sample {
-public:
-    BackdropBoundsSample() {}
-
-    void onDrawContent(SkCanvas* canvas) override {
-        SkMatrix ctm = canvas->getTotalMatrix();
-
-        // This decomposition is for the backdrop filtering, and does not represent the CTM that
-        // the layer actually uses (unless it also has a filter during restore).
-        SkMatrix toGlobal, layerMatrix;
-        SkSize scale;
-        if (ctm.isScaleTranslate()) {
-            // No decomposition needed
-            toGlobal = SkMatrix::I();
-            layerMatrix = ctm;
-        } else if (ctm.decomposeScale(&scale, &toGlobal)) {
-            layerMatrix = SkMatrix::MakeScale(scale.fWidth, scale.fHeight);
-        } else {
-            toGlobal = ctm;
-            layerMatrix = SkMatrix::I();
-        }
-
-        SkMatrix fromGlobal;
-        if (!toGlobal.invert(&fromGlobal)) {
-            SkDebugf("Unable to invert CTM\n");
-            return;
-        }
-
-        // The local content, e.g. what would be submitted to drawRect
-        const SkRect localContentRect = SkRect::MakeLTRB(45.5f, 23.123f, 150.f, 140.45f);
-        canvas->drawRect(localContentRect, line_paint(0.f, SK_ColorBLACK));
-
-        canvas->save();
-        // The layer bounds of the content, this is the size of the actual layer and does not
-        // reflect the backdrop specific decomposition.
-        canvas->setMatrix(SkMatrix::I());
-        SkIRect origLayerBounds = ctm.mapRect(localContentRect).roundOut();
-        canvas->drawRect(SkRect::Make(origLayerBounds), line_paint(1.f, SK_ColorBLACK));
-
-        // Have to undo the full CTM transform on the layer bounds to get the layer bounds
-        // for the specific backdrop filter decomposition
-        canvas->setMatrix(toGlobal);
-        SkIRect layerBounds = fromGlobal.mapRect(SkRect::Make(origLayerBounds)).roundOut();
-        canvas->drawRect(SkRect::Make(layerBounds), line_paint(0.5f, SK_ColorRED));
-
-        // Input bounds for the backdrop filter to cover the actual layer bounds (emulate some
-        // blur that must outset by 5px for reading on the edge).
-        SkIRect filterInputBounds = layerBounds;
-        filterInputBounds.outset(5, 5);
-        canvas->drawRect(SkRect::Make(filterInputBounds), line_paint(1.f, SK_ColorBLUE));
-
-        // The destination bounds that must be snapped in order to transform and fill the
-        // filterInputBounds
-        canvas->setMatrix(SkMatrix::I());
-        SkIRect devLayerBounds = toGlobal.mapRect(SkRect::Make(filterInputBounds)).roundOut();
-        canvas->drawRect(SkRect::Make(devLayerBounds), line_paint(2.f, SK_ColorMAGENTA));
-
-        // The destination bounds mapped back into the layer space, which should cover 'layerBounds'
-        SkPath backdropCoveringBounds;
-
-        // Add axis lines, to show perspective distortion
-        SkIRect local = fromGlobal.mapRect(SkRect::Make(devLayerBounds)).roundOut();
-        static int kAxisSpace = 10;
-        for (int y = local.fTop + kAxisSpace; y <= local.fBottom - kAxisSpace; y += kAxisSpace) {
-            backdropCoveringBounds.moveTo(local.fLeft, y);
-            backdropCoveringBounds.lineTo(local.fRight, y);
-        }
-        for (int x = local.fLeft + kAxisSpace; x <= local.fRight - kAxisSpace; x += kAxisSpace) {
-            backdropCoveringBounds.moveTo(x, local.fTop);
-            backdropCoveringBounds.lineTo(x, local.fBottom);
-        }
-
-        canvas->setMatrix(toGlobal);
-        canvas->drawPath(backdropCoveringBounds, line_paint(0.f, SK_ColorGREEN));
-
-        canvas->resetMatrix();
-        print_info(canvas, origLayerBounds, layerBounds, filterInputBounds, devLayerBounds);
-
-        canvas->restore();
-    }
-
-    SkString name() override { return SkString("BackdropBounds"); }
-
-private:
-
-    typedef Sample INHERITED;
-};
-
-DEF_SAMPLE(return new BackdropBoundsSample();)
diff --git a/third_party/skia/samplecode/SampleBitmapRect.cpp b/third_party/skia/samplecode/SampleBitmapRect.cpp
deleted file mode 100644
index 1f757f5..0000000
--- a/third_party/skia/samplecode/SampleBitmapRect.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkBitmap.h"
-#include "include/core/SkCanvas.h"
-#include "include/core/SkColorFilter.h"
-#include "include/core/SkColorPriv.h"
-#include "include/core/SkFont.h"
-#include "include/core/SkGraphics.h"
-#include "include/core/SkPath.h"
-#include "include/core/SkRegion.h"
-#include "include/core/SkShader.h"
-#include "include/core/SkTime.h"
-#include "include/core/SkTypeface.h"
-#include "include/effects/SkGradientShader.h"
-#include "samplecode/Sample.h"
-#include "src/utils/SkUTF.h"
-
-#include "include/core/SkStream.h"
-#include "src/core/SkOSFile.h"
-
-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);
-    SkCanvas canvas(*bitmap);
-
-    canvas.drawColor(SK_ColorRED);
-    SkPaint paint;
-    paint.setAntiAlias(true);
-    const SkPoint pts[] = { { 0, 0 }, { SCALAR_SIZE, SCALAR_SIZE } };
-    const SkColor colors[] = { SK_ColorWHITE, SK_ColorBLUE };
-    paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp));
-    canvas.drawCircle(SCALAR_SIZE/2, SCALAR_SIZE/2, SCALAR_SIZE/2, paint);
-}
-
-static void bounce(SkScalar* value, SkScalar* delta, SkScalar min, SkScalar max) {
-    *value += *delta;
-    if (*value < min) {
-        *value = min;
-        *delta = - *delta;
-    } else if (*value > max) {
-        *value = max;
-        *delta = - *delta;
-    }
-}
-
-static void bounce_pt(SkPoint* pt, SkVector* vec, const SkRect& limit) {
-    bounce(&pt->fX, &vec->fX, limit.fLeft, limit.fRight);
-    bounce(&pt->fY, &vec->fY, limit.fTop, limit.fBottom);
-}
-
-class BitmapRectView : public Sample {
-    SkPoint fSrcPt = {0, 0};
-    SkPoint fSrcVec = {0.866025f, 0.5f};
-
-    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;
-
-    SkString name() override { return SkString("BitmapRect"); }
-
-    void onOnceBeforeDraw() override {
-        this->setBGColor(SK_ColorGRAY);
-        make_bitmap(&fBitmap);
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        SkRect srcR = {fSrcPt.fX - 16, fSrcPt.fY - 16,
-                       fSrcPt.fX + 16, fSrcPt.fY + 16};
-
-        SkPaint paint(SkColors::kYellow);
-        paint.setStyle(SkPaint::kStroke_Style);
-
-        canvas->translate(20, 20);
-
-        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(fBitmap, srcR, fDstR[i], &paint,
-                                   SkCanvas::kStrict_SrcRectConstraint);
-            canvas->drawRect(fDstR[i], paint);
-        }
-    }
-
-    bool onAnimate(double nanos) override {
-        bounce_pt(&fSrcPt, &fSrcVec, fSrcLimit);
-        return true;
-    }
-};
-
-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,"
-        " ensure domestic tranquility, provide for the common defense, promote the"
-        " general welfare and ensure the blessings of liberty to ourselves and our"
-        " posterity, do ordain and establish this constitution for the United"
-        " States of America.";
-
-    SkFont font;
-    font.setSize(SkIntToScalar(BIG_H));
-
-    const int BIG_W = SkScalarRoundToInt(font.measureText(gText, strlen(gText), SkTextEncoding::kUTF8));
-
-    bm->allocN32Pixels(BIG_W, BIG_H);
-    bm->eraseColor(SK_ColorWHITE);
-
-    SkCanvas canvas(*bm);
-
-    canvas.drawSimpleText(gText, strlen(gText), SkTextEncoding::kUTF8, 0, font.getSize()*4/5, font, SkPaint());
-}
-
-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}};
-
-    SkString name() override { return SkString("BigBitmapRect"); }
-
-    void onOnceBeforeDraw() override {
-        this->setBGColor(SK_ColorGRAY);
-        make_big_bitmap(&fBitmap);
-        fLimitR = SkRect::Make(fBitmap.dimensions());
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        SkPaint paint;
-        paint.setStyle(SkPaint::kStroke_Style);
-        paint.setColor(SK_ColorYELLOW);
-
-        for (int i = 0; i < 2; ++i) {
-            paint.setFilterQuality(1 == i ? kLow_SkFilterQuality : kNone_SkFilterQuality);
-            canvas->drawBitmapRect(fBitmap, fSrcR, fDstR[i], &paint,
-                                   SkCanvas::kStrict_SrcRectConstraint);
-            canvas->drawRect(fDstR[i], paint);
-        }
-    }
-
-    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;
-    }
-};
-
-DEF_SAMPLE( return new BitmapRectView(); )
-DEF_SAMPLE( return new BitmapRectView2(); )
diff --git a/third_party/skia/samplecode/SampleCCPRGeometry.cpp b/third_party/skia/samplecode/SampleCCPRGeometry.cpp
deleted file mode 100644
index dff8ed9..0000000
--- a/third_party/skia/samplecode/SampleCCPRGeometry.cpp
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkTypes.h"
-
-#if SK_SUPPORT_GPU
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
-#include "samplecode/Sample.h"
-#include "src/core/SkMakeUnique.h"
-#include "src/core/SkRectPriv.h"
-#include "src/gpu/GrClip.h"
-#include "src/gpu/GrContextPriv.h"
-#include "src/gpu/GrMemoryPool.h"
-#include "src/gpu/GrRenderTargetContext.h"
-#include "src/gpu/GrRenderTargetContextPriv.h"
-#include "src/gpu/GrResourceProvider.h"
-#include "src/gpu/ccpr/GrCCCoverageProcessor.h"
-#include "src/gpu/ccpr/GrCCFillGeometry.h"
-#include "src/gpu/ccpr/GrCCStroker.h"
-#include "src/gpu/ccpr/GrGSCoverageProcessor.h"
-#include "src/gpu/ccpr/GrVSCoverageProcessor.h"
-#include "src/gpu/geometry/GrPathUtils.h"
-#include "src/gpu/gl/GrGLGpu.h"
-#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/ops/GrDrawOp.h"
-
-using TriPointInstance = GrCCCoverageProcessor::TriPointInstance;
-using QuadPointInstance = GrCCCoverageProcessor::QuadPointInstance;
-using PrimitiveType = GrCCCoverageProcessor::PrimitiveType;
-
-static constexpr float kDebugBloat = 40;
-
-/**
- * This sample visualizes the AA bloat geometry generated by the ccpr geometry shaders. It
- * increases the AA bloat by 50x and outputs color instead of coverage (coverage=+1 -> green,
- * coverage=0 -> black, coverage=-1 -> red). Use the keys 1-7 to cycle through the different
- * geometry processors.
- */
-class CCPRGeometryView : public Sample {
-    void onOnceBeforeDraw() override { this->updateGpuData(); }
-    void onDrawContent(SkCanvas*) override;
-
-    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override;
-    bool onClick(Sample::Click*) override;
-    bool onChar(SkUnichar) override;
-    SkString name() override { return SkString("CCPRGeometry"); }
-
-    class Click;
-    class DrawCoverageCountOp;
-    class VisualizeCoverageCountFP;
-
-    void updateAndInval() { this->updateGpuData(); }
-
-    void updateGpuData();
-
-    PrimitiveType fPrimitiveType = PrimitiveType::kTriangles;
-    SkCubicType fCubicType;
-    SkMatrix fCubicKLM;
-
-    SkPoint fPoints[4] = {
-            {100.05f, 100.05f}, {400.75f, 100.05f}, {400.75f, 300.95f}, {100.05f, 300.95f}};
-
-    float fConicWeight = .5;
-    float fStrokeWidth = 40;
-    bool fDoStroke = false;
-
-    SkTArray<TriPointInstance> fTriPointInstances;
-    SkTArray<QuadPointInstance> fQuadPointInstances;
-    SkPath fPath;
-};
-
-class CCPRGeometryView::DrawCoverageCountOp : public GrDrawOp {
-    DEFINE_OP_CLASS_ID
-
-public:
-    DrawCoverageCountOp(CCPRGeometryView* view) : INHERITED(ClassID()), fView(view) {
-        this->setBounds(SkRect::MakeIWH(fView->width(), fView->height()), GrOp::HasAABloat::kNo,
-                        GrOp::IsHairline::kNo);
-    }
-
-    const char* name() const override {
-        return "[Testing/Sample code] CCPRGeometryView::DrawCoverageCountOp";
-    }
-
-private:
-    FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
-    GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
-                                      bool hasMixedSampledCoverage, GrClampType) override {
-        return GrProcessorSet::EmptySetAnalysis();
-    }
-    void onPrepare(GrOpFlushState*) override {}
-    void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
-
-    CCPRGeometryView* fView;
-
-    typedef GrDrawOp INHERITED;
-};
-
-class CCPRGeometryView::VisualizeCoverageCountFP : public GrFragmentProcessor {
-public:
-    VisualizeCoverageCountFP() : GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags) {}
-
-private:
-    const char* name() const override {
-        return "[Testing/Sample code] CCPRGeometryView::VisualizeCoverageCountFP";
-    }
-    std::unique_ptr<GrFragmentProcessor> clone() const override {
-        return skstd::make_unique<VisualizeCoverageCountFP>();
-    }
-    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
-    bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
-
-    class Impl : public GrGLSLFragmentProcessor {
-        void emitCode(EmitArgs& args) override {
-            GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
-            f->codeAppendf("half count = %s.a;", args.fInputColor);
-            f->codeAppendf("%s = half4(clamp(-count, 0, 1), clamp(+count, 0, 1), 0, abs(count));",
-                           args.fOutputColor);
-        }
-    };
-
-    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new Impl; }
-};
-
-static void draw_klm_line(int w, int h, SkCanvas* canvas, const SkScalar line[3], SkColor color) {
-    SkPoint p1, p2;
-    if (SkScalarAbs(line[1]) > SkScalarAbs(line[0])) {
-        // Draw from vertical edge to vertical edge.
-        p1 = {0, -line[2] / line[1]};
-        p2 = {(SkScalar)w, (-line[2] - w * line[0]) / line[1]};
-    } else {
-        // Draw from horizontal edge to horizontal edge.
-        p1 = {-line[2] / line[0], 0};
-        p2 = {(-line[2] - h * line[1]) / line[0], (SkScalar)h};
-    }
-
-    SkPaint linePaint;
-    linePaint.setColor(color);
-    linePaint.setAlpha(128);
-    linePaint.setStyle(SkPaint::kStroke_Style);
-    linePaint.setStrokeWidth(0);
-    linePaint.setAntiAlias(true);
-    canvas->drawLine(p1, p2, linePaint);
-}
-
-void CCPRGeometryView::onDrawContent(SkCanvas* canvas) {
-    canvas->clear(SK_ColorBLACK);
-
-    if (!fDoStroke) {
-        SkPaint outlinePaint;
-        outlinePaint.setColor(0x80ffffff);
-        outlinePaint.setStyle(SkPaint::kStroke_Style);
-        outlinePaint.setStrokeWidth(0);
-        outlinePaint.setAntiAlias(true);
-        canvas->drawPath(fPath, outlinePaint);
-    }
-
-#if 0
-    SkPaint gridPaint;
-    gridPaint.setColor(0x10000000);
-    gridPaint.setStyle(SkPaint::kStroke_Style);
-    gridPaint.setStrokeWidth(0);
-    gridPaint.setAntiAlias(true);
-    for (int y = 0; y < this->height(); y += kDebugBloat) {
-        canvas->drawLine(0, y, this->width(), y, gridPaint);
-    }
-    for (int x = 0; x < this->width(); x += kDebugBloat) {
-        canvas->drawLine(x, 0, x, this->height(), outlinePaint);
-    }
-#endif
-
-    SkString caption;
-    if (GrRenderTargetContext* rtc = canvas->internal_private_accessTopLayerRenderTargetContext()) {
-        // Render coverage count.
-        GrContext* ctx = canvas->getGrContext();
-        SkASSERT(ctx);
-
-        GrOpMemoryPool* pool = ctx->priv().opMemoryPool();
-
-        auto ccbuff = ctx->priv().makeDeferredRenderTargetContext(SkBackingFit::kApprox,
-                                                                  this->width(), this->height(),
-                                                                  GrColorType::kAlpha_F16, nullptr);
-        SkASSERT(ccbuff);
-        ccbuff->clear(nullptr, SK_PMColor4fTRANSPARENT,
-                      GrRenderTargetContext::CanClearFullscreen::kYes);
-        ccbuff->priv().testingOnly_addDrawOp(pool->allocate<DrawCoverageCountOp>(this));
-
-        // Visualize coverage count in main canvas.
-        GrPaint paint;
-        paint.addColorFragmentProcessor(
-                GrSimpleTextureEffect::Make(sk_ref_sp(ccbuff->asTextureProxy()),
-                                            ccbuff->colorInfo().alphaType(), SkMatrix::I()));
-        paint.addColorFragmentProcessor(
-                skstd::make_unique<VisualizeCoverageCountFP>());
-        paint.setPorterDuffXPFactory(SkBlendMode::kSrcOver);
-        rtc->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
-                      SkRect::MakeIWH(this->width(), this->height()));
-
-        // Add label.
-        caption.appendf("PrimitiveType_%s",
-                        GrCCCoverageProcessor::PrimitiveTypeName(fPrimitiveType));
-        if (PrimitiveType::kCubics == fPrimitiveType) {
-            caption.appendf(" (%s)", SkCubicTypeName(fCubicType));
-        } else if (PrimitiveType::kConics == fPrimitiveType) {
-            caption.appendf(" (w=%f)", fConicWeight);
-        }
-        if (fDoStroke) {
-            caption.appendf(" (stroke_width=%f)", fStrokeWidth);
-        }
-    } else {
-        caption = "Use GPU backend to visualize geometry.";
-    }
-
-    SkPaint pointsPaint;
-    pointsPaint.setColor(SK_ColorBLUE);
-    pointsPaint.setStrokeWidth(8);
-    pointsPaint.setAntiAlias(true);
-
-    if (PrimitiveType::kCubics == fPrimitiveType) {
-        canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, fPoints, pointsPaint);
-        if (!fDoStroke) {
-            int w = this->width(), h = this->height();
-            draw_klm_line(w, h, canvas, &fCubicKLM[0], SK_ColorYELLOW);
-            draw_klm_line(w, h, canvas, &fCubicKLM[3], SK_ColorBLUE);
-            draw_klm_line(w, h, canvas, &fCubicKLM[6], SK_ColorRED);
-        }
-    } else {
-        canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, fPoints, pointsPaint);
-        canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, fPoints + 3, pointsPaint);
-    }
-
-    SkFont font(nullptr, 20);
-    SkPaint captionPaint;
-    captionPaint.setColor(SK_ColorWHITE);
-    canvas->drawString(caption, 10, 30, font, captionPaint);
-}
-
-void CCPRGeometryView::updateGpuData() {
-    using Verb = GrCCFillGeometry::Verb;
-    fTriPointInstances.reset();
-    fQuadPointInstances.reset();
-
-    fPath.reset();
-    fPath.moveTo(fPoints[0]);
-
-    if (PrimitiveType::kCubics == fPrimitiveType) {
-        double t[2], s[2];
-        fCubicType = GrPathUtils::getCubicKLM(fPoints, &fCubicKLM, t, s);
-        GrCCFillGeometry geometry;
-        geometry.beginContour(fPoints[0]);
-        geometry.cubicTo(fPoints, kDebugBloat / 2, kDebugBloat / 2);
-        geometry.endContour();
-        int ptsIdx = 0;
-        for (Verb verb : geometry.verbs()) {
-            switch (verb) {
-                case Verb::kLineTo:
-                    ++ptsIdx;
-                    continue;
-                case Verb::kMonotonicQuadraticTo:
-                    ptsIdx += 2;
-                    continue;
-                case Verb::kMonotonicCubicTo:
-                    fQuadPointInstances.push_back().set(&geometry.points()[ptsIdx], 0, 0);
-                    ptsIdx += 3;
-                    continue;
-                default:
-                    continue;
-            }
-        }
-        fPath.cubicTo(fPoints[1], fPoints[2], fPoints[3]);
-    } else if (PrimitiveType::kTriangles != fPrimitiveType) {
-        SkPoint P3[3] = {fPoints[0], fPoints[1], fPoints[3]};
-        GrCCFillGeometry geometry;
-        geometry.beginContour(P3[0]);
-        if (PrimitiveType::kQuadratics == fPrimitiveType) {
-            geometry.quadraticTo(P3);
-            fPath.quadTo(fPoints[1], fPoints[3]);
-        } else {
-            SkASSERT(PrimitiveType::kConics == fPrimitiveType);
-            geometry.conicTo(P3, fConicWeight);
-            fPath.conicTo(fPoints[1], fPoints[3], fConicWeight);
-        }
-        geometry.endContour();
-        int ptsIdx = 0, conicWeightIdx = 0;
-        for (Verb verb : geometry.verbs()) {
-            if (Verb::kBeginContour == verb ||
-                Verb::kEndOpenContour == verb ||
-                Verb::kEndClosedContour == verb) {
-                continue;
-            }
-            if (Verb::kLineTo == verb) {
-                ++ptsIdx;
-                continue;
-            }
-            SkASSERT(Verb::kMonotonicQuadraticTo == verb || Verb::kMonotonicConicTo == verb);
-            if (PrimitiveType::kQuadratics == fPrimitiveType &&
-                Verb::kMonotonicQuadraticTo == verb) {
-                fTriPointInstances.push_back().set(
-                        &geometry.points()[ptsIdx], Sk2f(0, 0),
-                        TriPointInstance::Ordering::kXYTransposed);
-            } else if (PrimitiveType::kConics == fPrimitiveType &&
-                       Verb::kMonotonicConicTo == verb) {
-                fQuadPointInstances.push_back().setW(&geometry.points()[ptsIdx], Sk2f(0, 0),
-                                                     geometry.getConicWeight(conicWeightIdx++));
-            }
-            ptsIdx += 2;
-        }
-    } else {
-        fTriPointInstances.push_back().set(
-                fPoints[0], fPoints[1], fPoints[3], Sk2f(0, 0),
-                TriPointInstance::Ordering::kXYTransposed);
-        fPath.lineTo(fPoints[1]);
-        fPath.lineTo(fPoints[3]);
-        fPath.close();
-    }
-}
-
-void CCPRGeometryView::DrawCoverageCountOp::onExecute(GrOpFlushState* state,
-                                                      const SkRect& chainBounds) {
-    GrResourceProvider* rp = state->resourceProvider();
-    GrContext* context = state->gpu()->getContext();
-    GrGLGpu* glGpu = GrBackendApi::kOpenGL == context->backend()
-                             ? static_cast<GrGLGpu*>(state->gpu())
-                             : nullptr;
-    if (glGpu) {
-        glGpu->handleDirtyContext();
-        // GR_GL_CALL(glGpu->glInterface(), PolygonMode(GR_GL_FRONT_AND_BACK, GR_GL_LINE));
-        GR_GL_CALL(glGpu->glInterface(), Enable(GR_GL_LINE_SMOOTH));
-    }
-
-    GrPipeline pipeline(GrScissorTest::kDisabled, SkBlendMode::kPlus,
-                        state->drawOpArgs().outputSwizzle());
-
-    std::unique_ptr<GrCCCoverageProcessor> proc;
-    if (state->caps().shaderCaps()->geometryShaderSupport()) {
-        proc = skstd::make_unique<GrGSCoverageProcessor>();
-    } else {
-        proc = skstd::make_unique<GrVSCoverageProcessor>();
-    }
-
-    if (!fView->fDoStroke) {
-        proc->reset(fView->fPrimitiveType, rp);
-        SkDEBUGCODE(proc->enableDebugBloat(kDebugBloat));
-
-        SkSTArray<1, GrMesh> mesh;
-        if (PrimitiveType::kCubics == fView->fPrimitiveType ||
-            PrimitiveType::kConics == fView->fPrimitiveType) {
-            sk_sp<GrGpuBuffer> instBuff(
-                    rp->createBuffer(fView->fQuadPointInstances.count() * sizeof(QuadPointInstance),
-                                     GrGpuBufferType::kVertex, kDynamic_GrAccessPattern,
-                                     fView->fQuadPointInstances.begin()));
-            if (!fView->fQuadPointInstances.empty() && instBuff) {
-                proc->appendMesh(std::move(instBuff), fView->fQuadPointInstances.count(), 0, &mesh);
-            }
-        } else {
-            sk_sp<GrGpuBuffer> instBuff(
-                    rp->createBuffer(fView->fTriPointInstances.count() * sizeof(TriPointInstance),
-                                     GrGpuBufferType::kVertex, kDynamic_GrAccessPattern,
-                                     fView->fTriPointInstances.begin()));
-            if (!fView->fTriPointInstances.empty() && instBuff) {
-                proc->appendMesh(std::move(instBuff), fView->fTriPointInstances.count(), 0, &mesh);
-            }
-        }
-
-        if (!mesh.empty()) {
-            SkASSERT(1 == mesh.count());
-            proc->draw(state, pipeline, nullptr, mesh.begin(), 1, this->bounds());
-        }
-    } else if (PrimitiveType::kConics != fView->fPrimitiveType) {  // No conic stroke support yet.
-        GrCCStroker stroker(0,0,0);
-
-        SkPaint p;
-        p.setStyle(SkPaint::kStroke_Style);
-        p.setStrokeWidth(fView->fStrokeWidth);
-        p.setStrokeJoin(SkPaint::kMiter_Join);
-        p.setStrokeMiter(4);
-        // p.setStrokeCap(SkPaint::kRound_Cap);
-        stroker.parseDeviceSpaceStroke(fView->fPath, SkPathPriv::PointData(fView->fPath),
-                                       SkStrokeRec(p), p.getStrokeWidth(), GrScissorTest::kDisabled,
-                                       SkIRect::MakeWH(fView->width(), fView->height()), {0, 0});
-        GrCCStroker::BatchID batchID = stroker.closeCurrentBatch();
-
-        GrOnFlushResourceProvider onFlushRP(context->priv().drawingManager());
-        stroker.prepareToDraw(&onFlushRP);
-
-        SkIRect ibounds;
-        this->bounds().roundOut(&ibounds);
-        stroker.drawStrokes(state, proc.get(), batchID, ibounds);
-    }
-
-    if (glGpu) {
-        context->resetContext(kMisc_GrGLBackendState);
-    }
-}
-
-class CCPRGeometryView::Click : public Sample::Click {
-public:
-    Click(int ptIdx) : fPtIdx(ptIdx) {}
-
-    void doClick(SkPoint points[]) {
-        if (fPtIdx >= 0) {
-            points[fPtIdx] += fCurr - fPrev;
-        } else {
-            for (int i = 0; i < 4; ++i) {
-                points[i] += fCurr - fPrev;
-            }
-        }
-    }
-
-private:
-    int fPtIdx;
-};
-
-Sample::Click* CCPRGeometryView::onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) {
-    for (int i = 0; i < 4; ++i) {
-        if (PrimitiveType::kCubics != fPrimitiveType && 2 == i) {
-            continue;
-        }
-        if (fabs(x - fPoints[i].x()) < 20 && fabsf(y - fPoints[i].y()) < 20) {
-            return new Click(i);
-        }
-    }
-    return new Click(-1);
-}
-
-bool CCPRGeometryView::onClick(Sample::Click* click) {
-    Click* myClick = (Click*)click;
-    myClick->doClick(fPoints);
-    this->updateAndInval();
-    return true;
-}
-
-bool CCPRGeometryView::onChar(SkUnichar unichar) {
-        if (unichar >= '1' && unichar <= '4') {
-            fPrimitiveType = PrimitiveType(unichar - '1');
-            if (fPrimitiveType >= PrimitiveType::kWeightedTriangles) {
-                fPrimitiveType = (PrimitiveType) ((int)fPrimitiveType + 1);
-            }
-            this->updateAndInval();
-            return true;
-        }
-        float* valueToScale = nullptr;
-        if (fDoStroke) {
-            valueToScale = &fStrokeWidth;
-        } else if (PrimitiveType::kConics == fPrimitiveType) {
-            valueToScale = &fConicWeight;
-        }
-        if (valueToScale) {
-            if (unichar == '+') {
-                *valueToScale *= 2;
-                this->updateAndInval();
-                return true;
-            }
-            if (unichar == '+' || unichar == '=') {
-                *valueToScale *= 5/4.f;
-                this->updateAndInval();
-                return true;
-            }
-            if (unichar == '-') {
-                *valueToScale *= 4/5.f;
-                this->updateAndInval();
-                return true;
-            }
-            if (unichar == '_') {
-                *valueToScale *= .5f;
-                this->updateAndInval();
-                return true;
-            }
-        }
-        if (unichar == 'D') {
-            SkDebugf("    SkPoint fPoints[4] = {\n");
-            SkDebugf("        {%ff, %ff},\n", fPoints[0].x(), fPoints[0].y());
-            SkDebugf("        {%ff, %ff},\n", fPoints[1].x(), fPoints[1].y());
-            SkDebugf("        {%ff, %ff},\n", fPoints[2].x(), fPoints[2].y());
-            SkDebugf("        {%ff, %ff}\n", fPoints[3].x(), fPoints[3].y());
-            SkDebugf("    };\n");
-            return true;
-        }
-        if (unichar == 'S') {
-            fDoStroke = !fDoStroke;
-            this->updateAndInval();
-        }
-        return false;
-}
-
-DEF_SAMPLE(return new CCPRGeometryView;)
-
-#endif  // SK_SUPPORT_GPU
diff --git a/third_party/skia/samplecode/SampleCamera.cpp b/third_party/skia/samplecode/SampleCamera.cpp
index 38201eb..41da126 100644
--- a/third_party/skia/samplecode/SampleCamera.cpp
+++ b/third_party/skia/samplecode/SampleCamera.cpp
@@ -6,6 +6,7 @@
  */
 
 #include "include/core/SkCanvas.h"
+#include "include/core/SkImage.h"
 #include "include/core/SkShader.h"
 #include "include/core/SkString.h"
 #include "include/utils/SkCamera.h"
@@ -35,9 +36,8 @@
             if (GetResourceAsBitmap(resource, &bm)) {
                 SkRect src = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) };
                 SkRect dst = { -150, -150, 150, 150 };
-                SkMatrix matrix;
-                matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
-                fShaders.push_back(bm.makeShader(&matrix));
+                fShaders.push_back(bm.makeShader(SkSamplingOptions(SkFilterMode::kLinear),
+                                                 SkMatrix::RectToRect(src, dst)));
             }
         }
         this->setBGColor(0xFFDDDDDD);
@@ -61,7 +61,6 @@
             SkPaint paint;
             paint.setAntiAlias(true);
             paint.setShader(fShaders[fShaderIndex]);
-            paint.setFilterQuality(kLow_SkFilterQuality);
             SkRect r = { -150, -150, 150, 150 };
             canvas->drawRoundRect(r, 30, 30, paint);
         }
diff --git a/third_party/skia/samplecode/SampleChart.cpp b/third_party/skia/samplecode/SampleChart.cpp
index 448e1d7..37b9d06 100644
--- a/third_party/skia/samplecode/SampleChart.cpp
+++ b/third_party/skia/samplecode/SampleChart.cpp
@@ -7,7 +7,7 @@
 
 #include "include/core/SkCanvas.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/utils/SkRandom.h"
 #include "samplecode/Sample.h"
 
@@ -30,9 +30,7 @@
                       SkScalar yBase,
                       SkScalar xLeft, SkScalar xDelta,
                       int leftShift,
-                      SkPath* plot, SkPath* fill) {
-    plot->rewind();
-    fill->rewind();
+                      SkPathBuilder* plot, SkPathBuilder* fill) {
     plot->incReserve(topData.count());
     if (nullptr == bottomData) {
         fill->incReserve(topData.count() + 2);
@@ -81,9 +79,9 @@
 // A set of scrolling line plots with the area between each plot filled. Stresses out GPU path
 // filling
 class ChartView : public Sample {
-    static constexpr int kNumGraphs = 5;
-    static constexpr int kPixelsPerTick = 3;
-    static constexpr int kShiftPerFrame = 1;
+    inline static constexpr int kNumGraphs = 5;
+    inline static constexpr int kPixelsPerTick = 3;
+    inline static constexpr int kShiftPerFrame = 1;
     int                 fShift = 0;
     SkISize             fSize = {-1, -1};
     SkTDArray<SkScalar> fData[kNumGraphs];
@@ -102,7 +100,7 @@
         SkScalar height = SkIntToScalar(fSize.fHeight);
 
         if (sizeChanged) {
-            int dataPointCount = SkMax32(fSize.fWidth / kPixelsPerTick + 1, 2);
+            int dataPointCount = std::max(fSize.fWidth / kPixelsPerTick + 1, 2);
 
             for (int i = 0; i < kNumGraphs; ++i) {
                 SkScalar y = (kNumGraphs - i) * (height - ySpread) / (kNumGraphs + 1);
@@ -121,9 +119,6 @@
             }
         }
 
-        SkPath plotPath;
-        SkPath fillPath;
-
         static const SkScalar kStrokeWidth = SkIntToScalar(2);
         SkPaint plotPaint;
         SkPaint fillPaint;
@@ -135,7 +130,9 @@
         fillPaint.setAntiAlias(true);
         fillPaint.setStyle(SkPaint::kFill_Style);
 
+        SkPathBuilder plotPath, fillPath;
         SkTDArray<SkScalar>* prevData = nullptr;
+
         for (int i = 0; i < kNumGraphs; ++i) {
             gen_paths(fData[i],
                       prevData,
@@ -148,10 +145,10 @@
 
             // Make the fills partially transparent
             fillPaint.setColor((gColors[i] & 0x00ffffff) | 0x80000000);
-            canvas->drawPath(fillPath, fillPaint);
+            canvas->drawPath(fillPath.detach(), fillPaint);
 
             plotPaint.setColor(gColors[i]);
-            canvas->drawPath(plotPath, plotPaint);
+            canvas->drawPath(plotPath.detach(), plotPaint);
 
             prevData = fData + i;
         }
diff --git a/third_party/skia/samplecode/SampleChineseFling.cpp b/third_party/skia/samplecode/SampleChineseFling.cpp
index 1cdf784..0e62725 100644
--- a/third_party/skia/samplecode/SampleChineseFling.cpp
+++ b/third_party/skia/samplecode/SampleChineseFling.cpp
@@ -17,8 +17,8 @@
 #include "include/utils/SkRandom.h"
 
 #if SK_SUPPORT_GPU
-#include "include/gpu/GrContext.h"
-#include "src/gpu/GrContextPriv.h"
+#include "include/gpu/GrDirectContext.h"
+#include "src/gpu/GrDirectContextPriv.h"
 #endif
 
 static sk_sp<SkTypeface> chinese_typeface() {
@@ -38,8 +38,8 @@
 }
 
 class ChineseFlingView : public Sample {
-    static constexpr int kNumBlobs = 200;
-    static constexpr int kWordLength = 16;
+    inline static constexpr int kNumBlobs = 200;
+    inline static constexpr int kWordLength = 16;
 
     sk_sp<SkTypeface>    fTypeface;
     SkFontMetrics        fMetrics;
@@ -103,8 +103,8 @@
 };
 
 class ChineseZoomView : public Sample {
-    static constexpr int kNumBlobs = 8;
-    static constexpr int kParagraphLength = 175;
+    inline static constexpr int kNumBlobs = 8;
+    inline static constexpr int kParagraphLength = 175;
 
     bool                 fAfterFirstFrame = false;
     sk_sp<SkTypeface>    fTypeface;
@@ -137,24 +137,28 @@
 
         if (fAfterFirstFrame) {
 #if SK_SUPPORT_GPU
-            GrContext* grContext = canvas->getGrContext();
-            if (grContext) {
-                sk_sp<SkImage> image = grContext->priv().testingOnly_getFontAtlasImage(
+            auto direct = GrAsDirectContext(canvas->recordingContext());
+            if (direct) {
+                sk_sp<SkImage> image = direct->priv().testingOnly_getFontAtlasImage(
                             GrMaskFormat::kA8_GrMaskFormat, 0);
                 canvas->drawImageRect(image,
-                                      SkRect::MakeXYWH(10.0f, 10.0f, 512.0f, 512.0), &paint);
-                image = grContext->priv().testingOnly_getFontAtlasImage(
+                                      SkRect::MakeXYWH(10.0f, 10.0f, 512.0f, 512.0),
+                                      SkSamplingOptions(), &paint);
+                image = direct->priv().testingOnly_getFontAtlasImage(
                         GrMaskFormat::kA8_GrMaskFormat, 1);
                 canvas->drawImageRect(image,
-                                      SkRect::MakeXYWH(522.0f, 10.0f, 512.f, 512.0f), &paint);
-                image = grContext->priv().testingOnly_getFontAtlasImage(
+                                      SkRect::MakeXYWH(522.0f, 10.0f, 512.f, 512.0f),
+                                      SkSamplingOptions(), &paint);
+                image = direct->priv().testingOnly_getFontAtlasImage(
                         GrMaskFormat::kA8_GrMaskFormat, 2);
                 canvas->drawImageRect(image,
-                                      SkRect::MakeXYWH(10.0f, 522.0f, 512.0f, 512.0f), &paint);
-                image = grContext->priv().testingOnly_getFontAtlasImage(
+                                      SkRect::MakeXYWH(10.0f, 522.0f, 512.0f, 512.0f),
+                                      SkSamplingOptions(), &paint);
+                image = direct->priv().testingOnly_getFontAtlasImage(
                         GrMaskFormat::kA8_GrMaskFormat, 3);
                 canvas->drawImageRect(image,
-                                      SkRect::MakeXYWH(522.0f, 522.0f, 512.0f, 512.0f), &paint);
+                                      SkRect::MakeXYWH(522.0f, 522.0f, 512.0f, 512.0f),
+                                      SkSamplingOptions(), &paint);
             }
 #endif
         }
@@ -191,7 +195,7 @@
             auto paragraphLength = kParagraphLength;
             SkScalar y = 0;
             while (paragraphLength - 45 > 0) {
-                auto currentLineLength = SkTMin(45, paragraphLength - 45);
+                auto currentLineLength = std::min(45, paragraphLength - 45);
                 this->createRandomLine(glyphs, currentLineLength);
 
                 ToolUtils::add_to_text_blob_w_len(&builder,
diff --git a/third_party/skia/samplecode/SampleCircle.cpp b/third_party/skia/samplecode/SampleCircle.cpp
index c4126f9..3cd7c0b 100644
--- a/third_party/skia/samplecode/SampleCircle.cpp
+++ b/third_party/skia/samplecode/SampleCircle.cpp
@@ -35,7 +35,7 @@
             paint.setStrokeWidth(SkIntToScalar(width));
         }
         canvas->drawCircle(0, 0, 9.0f, paint);
-        if (false) { // avoid bit rot, suppress warning
+        if ((false)) { // avoid bit rot, suppress warning
             test_circlebounds(canvas);
         }
     }
diff --git a/third_party/skia/samplecode/SampleClip.cpp b/third_party/skia/samplecode/SampleClip.cpp
index bff7704..358e3f8 100644
--- a/third_party/skia/samplecode/SampleClip.cpp
+++ b/third_party/skia/samplecode/SampleClip.cpp
@@ -9,10 +9,11 @@
 #include "include/core/SkColorPriv.h"
 #include "include/core/SkFont.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/utils/SkRandom.h"
 #include "samplecode/Sample.h"
-#include "src/core/SkClipOpPriv.h"
+#include "src/core/SkPathPriv.h"
+#include "tools/Resources.h"
 
 constexpr int W = 150;
 constexpr int H = 200;
@@ -37,7 +38,6 @@
 
     for (int i = 0; i < 50; ++i) {
         SkRect r;
-        SkPath p;
 
         r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
                   rand.nextUScalar1() * W, rand.nextUScalar1() * H);
@@ -47,8 +47,7 @@
         r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
                   rand.nextUScalar1() * W, rand.nextUScalar1() * H);
         paint.setColor(rand.nextU());
-        p.addOval(r);
-        canvas->drawPath(p, paint);
+        canvas->drawOval(r, paint);
     }
 }
 
@@ -66,7 +65,6 @@
 
     for (int i = 0; i < n; ++i) {
         SkRect r;
-        SkPath p;
 
         r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
                   rand.nextUScalar1() * W, rand.nextUScalar1() * H);
@@ -76,8 +74,7 @@
         r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
                   rand.nextUScalar1() * W, rand.nextUScalar1() * H);
         paint.setColor(rand.nextU());
-        p.addOval(r);
-        canvas->drawPath(p, paint);
+        canvas->drawOval(r, paint);
 
         const SkScalar minx = -SkIntToScalar(W)/4;
         const SkScalar maxx = 5*SkIntToScalar(W)/4;
@@ -112,9 +109,8 @@
         };
 
         SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
-        SkPath clipPath;
         r.inset(SK_Scalar1 / 4, SK_Scalar1 / 4);
-        clipPath.addRoundRect(r, SkIntToScalar(20), SkIntToScalar(20));
+        SkPath clipPath = SkPathBuilder().addRRect(SkRRect::MakeRectXY(r, 20, 20)).detach();
 
 //        clipPath.toggleInverseFillType();
 
@@ -122,7 +118,7 @@
             canvas->save();
             for (size_t i = 0; i < SK_ARRAY_COUNT(gProc); ++i) {
                 canvas->save();
-                canvas->clipPath(clipPath, kIntersect_SkClipOp, SkToBool(aa));
+                canvas->clipPath(clipPath, SkClipOp::kIntersect, SkToBool(aa));
 //                canvas->drawColor(SK_ColorWHITE);
                 gProc[i](canvas, SkToBool(aa));
                 canvas->restore();
@@ -211,7 +207,7 @@
 
 #include "src/core/SkEdgeClipper.h"
 
-static void clip(const SkPath& path, SkPoint p0, SkPoint p1, SkPath* clippedPath) {
+static SkPath clip(const SkPath& path, SkPoint p0, SkPoint p1) {
     SkMatrix mx, inv;
     SkVector v = p1 - p0;
     mx.setAll(v.fX, -v.fY, p0.fX,
@@ -226,9 +222,9 @@
     SkRect clip = {-big, 0, big, big };
 
     struct Rec {
-        SkPath* fResult;
-        SkPoint fPrev;
-    } rec = { clippedPath, {0, 0} };
+        SkPathBuilder   fResult;
+        SkPoint         fPrev = {0, 0};
+    } rec;
 
     SkEdgeClipper::ClipPath(rotated, clip, false,
                             [](SkEdgeClipper* clipper, bool newCtr, void* ctx) {
@@ -239,26 +235,26 @@
         SkPath::Verb verb;
         while ((verb = clipper->next(pts)) != SkPath::kDone_Verb) {
             if (newCtr) {
-                rec->fResult->moveTo(pts[0]);
+                rec->fResult.moveTo(pts[0]);
                 rec->fPrev = pts[0];
                 newCtr = false;
             }
 
             if (addLineTo || pts[0] != rec->fPrev) {
-                rec->fResult->lineTo(pts[0]);
+                rec->fResult.lineTo(pts[0]);
             }
 
             switch (verb) {
                 case SkPath::kLine_Verb:
-                    rec->fResult->lineTo(pts[1]);
+                    rec->fResult.lineTo(pts[1]);
                     rec->fPrev = pts[1];
                     break;
                 case SkPath::kQuad_Verb:
-                    rec->fResult->quadTo(pts[1], pts[2]);
+                    rec->fResult.quadTo(pts[1], pts[2]);
                     rec->fPrev = pts[2];
                     break;
                 case SkPath::kCubic_Verb:
-                    rec->fResult->cubicTo(pts[1], pts[2], pts[3]);
+                    rec->fResult.cubicTo(pts[1], pts[2], pts[3]);
                     rec->fPrev = pts[3];
                     break;
                 default: break;
@@ -267,27 +263,7 @@
         }
     }, &rec);
 
-    rec.fResult->transform(mx);
-}
-
-// true means use clippedPath.
-// false means there was no clipping -- use the original path
-static bool clip(const SkPath& path, const SkHalfPlane& plane, SkPath* clippedPath) {
-    switch (plane.test(path.getBounds())) {
-        case SkHalfPlane::kAllPositive:
-            return false;
-        case SkHalfPlane::kMixed: {
-            SkPoint pts[2];
-            if (plane.twoPts(pts)) {
-                clip(path, pts[0], pts[1], clippedPath);
-                return true;
-            }
-        } break;
-        default: break; // handled outside of the switch
-    }
-    // clipped out (or failed)
-    clippedPath->reset();
-    return true;
+    return rec.fResult.detach().makeTransform(mx);
 }
 
 static void draw_halfplane(SkCanvas* canvas, SkPoint p0, SkPoint p1, SkColor c) {
@@ -302,14 +278,21 @@
 
 static SkPath make_path() {
     SkRandom rand;
-    auto rand_pt = [&rand]() { return SkPoint{rand.nextF() * 400, rand.nextF() * 400}; };
+    auto rand_pt = [&rand]() {
+        auto x = rand.nextF();
+        auto y = rand.nextF();
+        return SkPoint{x * 400, y * 400};
+    };
 
-    SkPath path;
+    SkPathBuilder path;
     for (int i = 0; i < 4; ++i) {
-        path.moveTo(rand_pt()).quadTo(rand_pt(), rand_pt())
-            .quadTo(rand_pt(), rand_pt()).lineTo(rand_pt());
+        SkPoint pts[6];
+        for (auto& p : pts) {
+            p = rand_pt();
+        }
+        path.moveTo(pts[0]).quadTo(pts[1], pts[2]).quadTo(pts[3], pts[4]).lineTo(pts[5]);
     }
-    return path;
+    return path.detach();
 }
 
 class HalfPlaneView : public Sample {
@@ -332,9 +315,7 @@
 
         paint.setColor({0, 0, 0, 1}, nullptr);
 
-        SkPath clippedPath;
-        clip(fPath, fPts[0], fPts[1], &clippedPath);
-        canvas->drawPath(clippedPath, paint);
+        canvas->drawPath(clip(fPath, fPts[0], fPts[1]), paint);
 
         draw_halfplane(canvas, fPts[0], fPts[1], SK_ColorRED);
     }
@@ -357,16 +338,16 @@
     draw_halfplane(canvas, pts[0], pts[1], c);
 }
 
-static void compute_half_planes(const SkMatrix& mx, SkScalar W, SkScalar H,
+static void compute_half_planes(const SkMatrix& mx, SkScalar width, SkScalar height,
                                 SkHalfPlane planes[4]) {
     SkScalar a = mx[0], b = mx[1], c = mx[2],
              d = mx[3], e = mx[4], f = mx[5],
              g = mx[6], h = mx[7], i = mx[8];
 
-    planes[0] = { 2*g - 2*a/W,  2*h - 2*b/W,  2*i - 2*c/W };
-    planes[1] = { 2*a/W,        2*b/W,        2*c/W };
-    planes[2] = { 2*g - 2*d/H,  2*h - 2*e/H,  2*i - 2*f/H };
-    planes[3] = { 2*d/H,        2*e/H,        2*f/H };
+    planes[0] = { 2*g - 2*a/width,  2*h - 2*b/width,  2*i - 2*c/width };
+    planes[1] = { 2*a/width,        2*b/width,        2*c/width };
+    planes[2] = { 2*g - 2*d/height, 2*h - 2*e/height, 2*i - 2*f/height };
+    planes[3] = { 2*d/height,       2*e/height,       2*f/height };
 }
 
 class HalfPlaneView2 : public Sample {
@@ -435,55 +416,78 @@
 };
 DEF_SAMPLE( return new HalfPlaneView2(); )
 
-#include "include/core/SkMatrix44.h"
-#include "include/utils/Sk3D.h"
-#include "tools/Resources.h"
-
-static SkMatrix44 inv(const SkMatrix44& m) {
-    SkMatrix44 inverse;
+static SkM44 inv(const SkM44& m) {
+    SkM44 inverse;
     SkAssertResult(m.invert(&inverse));
     return inverse;
 }
 
-#if 0   // Jim's general half-planes math
-static void half_planes(const SkMatrix44& m44, SkScalar W, SkScalar H, SkHalfPlane planes[6]) {
-    float mx[16];
-    m44.asColMajorf(mx);
-
-    SkScalar a = mx[0], b = mx[4], /* c = mx[ 8], */ d = mx[12],
-             e = mx[1], f = mx[5], /* g = mx[ 9], */ h = mx[13],
-             i = mx[2], j = mx[6], /* k = mx[10], */ l = mx[14],
-             m = mx[3], n = mx[7], /* o = mx[11], */ p = mx[15];
-
-    a = 2*a/W - m;  b = 2*b/W - n;  d = 2*d/W - p;
-    e = 2*e/H - m;  f = 2*f/H - n;  h = 2*h/H - p;
-//    i = 2*i   - m;  j = 2*j   - n;  l = 2*l   - p;
-
-    planes[0] = { m - a, n - b, p - d }; // w - x
-    planes[1] = { m + a, n + b, p + d }; // w + x
-    planes[2] = { m - e, n - f, p - h }; // w - y
-    planes[3] = { m + e, n + f, p + h }; // w + y
-    planes[4] = { m - i, n - j, p - l }; // w - z
-    planes[5] = { m + i, n + j, p + l }; // w + z
-}
-#endif
-
 static SkHalfPlane half_plane_w0(const SkMatrix& m) {
     return { m[SkMatrix::kMPersp0], m[SkMatrix::kMPersp1], m[SkMatrix::kMPersp2] - 0.05f };
 }
 
-class HalfPlaneView3 : public Sample {
+class SampleCameraView : public Sample {
     float   fNear = 0.05f;
     float   fFar = 4;
     float   fAngle = SK_ScalarPI / 4;
 
-    SkPoint3    fEye { 0, 0, 1.0f/tan(fAngle/2) - 1 };
-    SkPoint3    fCOA { 0, 0, 0 };
-    SkPoint3    fUp  { 0, 1, 0 };
+    SkV3    fEye { 0, 0, 1.0f/tan(fAngle/2) - 1 };
+    SkV3    fCOA { 0, 0, 0 };
+    SkV3    fUp  { 0, 1, 0 };
 
-    SkMatrix44  fRot;
-    SkPoint3    fTrans;
+    SkM44  fRot;
+    SkV3   fTrans;
 
+    void rotate(float x, float y, float z) {
+        SkM44 r;
+        if (x) {
+            r.setRotateUnit({1, 0, 0}, x);
+        } else if (y) {
+            r.setRotateUnit({0, 1, 0}, y);
+        } else {
+            r.setRotateUnit({0, 0, 1}, z);
+        }
+        fRot = r * fRot;
+    }
+
+public:
+    SkM44 get44(const SkRect& r) const {
+        SkScalar w = r.width();
+        SkScalar h = r.height();
+
+        SkM44 camera = SkM44::LookAt(fEye, fCOA, fUp),
+              perspective = SkM44::Perspective(fNear, fFar, fAngle),
+              translate = SkM44::Translate(fTrans.x, fTrans.y, fTrans.z),
+              viewport = SkM44::Translate(r.centerX(), r.centerY(), 0) *
+                         SkM44::Scale(w*0.5f, h*0.5f, 1);
+
+        return viewport * perspective * camera * translate * fRot * inv(viewport);
+    }
+
+    bool onChar(SkUnichar uni) override {
+        float delta = SK_ScalarPI / 30;
+        switch (uni) {
+            case '8': this->rotate( delta, 0, 0); return true;
+            case '2': this->rotate(-delta, 0, 0); return true;
+            case '4': this->rotate(0,  delta, 0); return true;
+            case '6': this->rotate(0, -delta, 0); return true;
+            case '-': this->rotate(0, 0,  delta); return true;
+            case '+': this->rotate(0, 0, -delta); return true;
+
+            case 'i': fTrans.z += 0.1f; SkDebugf("z %g\n", fTrans.z); return true;
+            case 'k': fTrans.z -= 0.1f; SkDebugf("z %g\n", fTrans.z); return true;
+
+            case 'n': fNear += 0.1f; SkDebugf("near %g\n", fNear); return true;
+            case 'N': fNear -= 0.1f; SkDebugf("near %g\n", fNear); return true;
+            case 'f': fFar  += 0.1f; SkDebugf("far  %g\n", fFar); return true;
+            case 'F': fFar  -= 0.1f; SkDebugf("far  %g\n", fFar); return true;
+            default: break;
+        }
+        return false;
+    }
+};
+
+class HalfPlaneView3 : public SampleCameraView {
     SkPath fPath;
     sk_sp<SkShader> fShader;
     bool fShowUnclipped = false;
@@ -493,37 +497,19 @@
     void onOnceBeforeDraw() override {
         fPath = make_path();
         fShader = GetResourceAsImage("images/mandrill_128.png")
-                        ->makeShader(SkMatrix::MakeScale(3, 3));
+                        ->makeShader(SkSamplingOptions(), SkMatrix::Scale(3, 3));
     }
 
-    void rotate(float x, float y, float z) {
-        SkMatrix44 r;
-        if (x) {
-            r.setRotateAboutUnit(1, 0, 0, x);
-        } else if (y) {
-            r.setRotateAboutUnit(0, 1, 0, y);
-        } else {
-            r.setRotateAboutUnit(0, 0, 1, z);
+    bool onChar(SkUnichar uni) override {
+        switch (uni) {
+            case 'u': fShowUnclipped = !fShowUnclipped; return true;
+            default: break;
         }
-        fRot.postConcat(r);
-    }
-
-    SkMatrix44 get44() const {
-        SkMatrix44  camera,
-                    perspective,
-                    translate,
-                    viewport;
-
-        Sk3Perspective(&perspective, fNear, fFar, fAngle);
-        Sk3LookAt(&camera, fEye, fCOA, fUp);
-        translate.setTranslate(fTrans.fX, fTrans.fY, fTrans.fZ);
-        viewport.setScale(200, 200, 1).postTranslate( 200,  200, 0);
-
-        return viewport * perspective * camera * translate * fRot * inv(viewport);
+        return this->SampleCameraView::onChar(uni);
     }
 
     void onDrawContent(SkCanvas* canvas) override {
-        SkMatrix mx = this->get44();
+        SkM44 mx = this->get44({0, 0, 400, 400});
 
         SkPaint paint;
         paint.setColor({0.75, 0.75, 0.75, 1});
@@ -540,11 +526,10 @@
             canvas->restore();
         }
 
-        SkHalfPlane hpw = half_plane_w0(mx);
 
         SkColor planeColor = SK_ColorBLUE;
         SkPath clippedPath, *path = &fPath;
-        if (clip(fPath, hpw, &clippedPath)) {
+        if (SkPathPriv::PerspectiveClip(fPath, mx.asM33(), &clippedPath)) {
             path = &clippedPath;
             planeColor = SK_ColorRED;
         }
@@ -553,38 +538,97 @@
         canvas->drawPath(*path, paint);
         canvas->restore();
 
+        SkHalfPlane hpw = half_plane_w0(mx.asM33());
         draw_halfplane(canvas, hpw, planeColor);
     }
-
-    bool onChar(SkUnichar uni) override {
-        float delta = SK_ScalarPI / 30;
-        switch (uni) {
-            case '8': this->rotate( delta, 0, 0); return true;
-            case '2': this->rotate(-delta, 0, 0); return true;
-            case '4': this->rotate(0,  delta, 0); return true;
-            case '6': this->rotate(0, -delta, 0); return true;
-            case '-': this->rotate(0, 0,  delta); return true;
-            case '+': this->rotate(0, 0, -delta); return true;
-
-            case 'i': fTrans.fZ += 0.1f; SkDebugf("z %g\n", fTrans.fZ); return true;
-            case 'k': fTrans.fZ -= 0.1f; SkDebugf("z %g\n", fTrans.fZ); return true;
-
-            case 'n': fNear += 0.1f; SkDebugf("near %g\n", fNear); return true;
-            case 'N': fNear -= 0.1f; SkDebugf("near %g\n", fNear); return true;
-            case 'f': fFar  += 0.1f; SkDebugf("far  %g\n", fFar); return true;
-            case 'F': fFar  -= 0.1f; SkDebugf("far  %g\n", fFar); return true;
-
-            case 'u': fShowUnclipped = !fShowUnclipped; return true;
-            default: break;
-        }
-        return false;
-    }
-    Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
-        return nullptr;
-    }
-
-    bool onClick(Click* click) override {
-        return false;
-    }
 };
 DEF_SAMPLE( return new HalfPlaneView3(); )
+
+class HalfPlaneCoons : public SampleCameraView {
+    SkPoint fPatch[12];
+    SkColor fColors[4] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorBLACK };
+    SkPoint fTex[4]    = {{0, 0}, {256, 0}, {256, 256}, {0, 256}};
+    sk_sp<SkShader> fShader;
+
+    bool fShowHandles = false;
+    bool fShowSkeleton = false;
+    bool fShowTex = false;
+
+    SkString name() override { return SkString("halfplane-coons"); }
+
+    void onOnceBeforeDraw() override {
+        fPatch[0] = {   0, 0 };
+        fPatch[1] = { 100, 0 };
+        fPatch[2] = { 200, 0 };
+        fPatch[3] = { 300, 0 };
+        fPatch[4] = { 300, 100 };
+        fPatch[5] = { 300, 200 };
+        fPatch[6] = { 300, 300 };
+        fPatch[7] = { 200, 300 };
+        fPatch[8] = { 100, 300 };
+        fPatch[9] = {   0, 300 };
+        fPatch[10] = {  0, 200 };
+        fPatch[11] = {  0, 100 };
+
+        fShader = GetResourceAsImage("images/mandrill_256.png")->makeShader(SkSamplingOptions());
+    }
+
+    void onDrawContent(SkCanvas* canvas) override {
+        SkPaint paint;
+
+        canvas->save();
+        canvas->concat(this->get44({0, 0, 300, 300}));
+
+        const SkPoint* tex = nullptr;
+        const SkColor* col = nullptr;
+        if (!fShowSkeleton) {
+            if (fShowTex) {
+                paint.setShader(fShader);
+                tex = fTex;
+            } else {
+                col = fColors;
+            }
+        }
+        canvas->drawPatch(fPatch, col, tex, SkBlendMode::kSrc, paint);
+        paint.setShader(nullptr);
+
+        if (fShowHandles) {
+            paint.setAntiAlias(true);
+            paint.setStrokeCap(SkPaint::kRound_Cap);
+            paint.setStrokeWidth(8);
+            canvas->drawPoints(SkCanvas::kPoints_PointMode, 12, fPatch, paint);
+            paint.setColor(SK_ColorWHITE);
+            paint.setStrokeWidth(6);
+            canvas->drawPoints(SkCanvas::kPoints_PointMode, 12, fPatch, paint);
+        }
+
+        canvas->restore();
+    }
+
+    Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
+        auto dist = [](SkPoint a, SkPoint b) { return (b - a).length(); };
+
+        const float tol = 15;
+        for (int i = 0; i < 12; ++i) {
+            if (dist({x,y}, fPatch[i]) <= tol) {
+                return new Click([this, i](Click* c) {
+                    fPatch[i] = c->fCurr;
+                    return true;
+                });
+            }
+        }
+        return nullptr;
+    }
+
+    bool onChar(SkUnichar uni) override {
+        switch (uni) {
+            case 'h': fShowHandles = !fShowHandles; return true;
+            case 'k': fShowSkeleton = !fShowSkeleton; return true;
+            case 't': fShowTex = !fShowTex; return true;
+            default: break;
+        }
+        return this->SampleCameraView::onChar(uni);
+    }
+
+};
+DEF_SAMPLE( return new HalfPlaneCoons(); )
diff --git a/third_party/skia/samplecode/SampleClipDrawMatch.cpp b/third_party/skia/samplecode/SampleClipDrawMatch.cpp
deleted file mode 100644
index bdbb54b..0000000
--- a/third_party/skia/samplecode/SampleClipDrawMatch.cpp
+++ /dev/null
@@ -1,252 +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.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkPath.h"
-#include "include/core/SkRRect.h"
-#include "include/core/SkTime.h"
-#include "include/utils/SkInterpolator.h"
-#include "samplecode/Sample.h"
-
-// This slide tests out the match up between BW clipping and rendering. It can
-// draw a large rect through some clip geometry and draw the same geometry
-// normally. Which one is drawn first can be toggled. The pair of objects is translated
-// fractionally (via an animator) to expose snapping bugs. The key bindings are:
-//      1-9: the different geometries
-//      t:   toggle which is drawn first the clip or the normal geometry
-//      f:   flip-flops which corner the bottom AA clip rect occupies in the complex clip cases
-
-// The possible geometric combinations to test
-enum Geometry {
-    kRect_Geometry,
-    kRRect_Geometry,
-    kCircle_Geometry,
-    kConvexPath_Geometry,
-    kConcavePath_Geometry,
-    kRectAndRect_Geometry,
-    kRectAndRRect_Geometry,
-    kRectAndConvex_Geometry,
-    kRectAndConcave_Geometry
-};
-
-// The basic rect used is [kMin,kMin]..[kMax,kMax]
-static const float kMin = 100.5f;
-static const float kMid = 200.0f;
-static const float kMax = 299.5f;
-
-// The translation applied to the base AA rect in the combination cases
-// (i.e., kRectAndRect through kRectAndConcave)
-static const float kXlate = 100.0f;
-
-SkRect create_rect(const SkPoint& offset) {
-    SkRect r = SkRect::MakeLTRB(kMin, kMin, kMax, kMax);
-    r.offset(offset);
-    return r;
-}
-
-SkRRect create_rrect(const SkPoint& offset) {
-    SkRRect rrect;
-    rrect.setRectXY(create_rect(offset), 10, 10);
-    return rrect;
-}
-
-SkRRect create_circle(const SkPoint& offset) {
-    SkRRect circle;
-    circle.setOval(create_rect(offset));
-    return circle;
-}
-
-SkPath create_convex_path(const SkPoint& offset) {
-    SkPath convexPath;
-    convexPath.moveTo(kMin, kMin);
-    convexPath.lineTo(kMax, kMax);
-    convexPath.lineTo(kMin, kMax);
-    convexPath.close();
-    convexPath.offset(offset.fX, offset.fY);
-    return convexPath;
-}
-
-SkPath create_concave_path(const SkPoint& offset) {
-    SkPath concavePath;
-    concavePath.moveTo(kMin, kMin);
-    concavePath.lineTo(kMid, 105.0f);
-    concavePath.lineTo(kMax, kMin);
-    concavePath.lineTo(295.0f, kMid);
-    concavePath.lineTo(kMax, kMax);
-    concavePath.lineTo(kMid, 295.0f);
-    concavePath.lineTo(kMin, kMax);
-    concavePath.lineTo(105.0f, kMid);
-    concavePath.close();
-
-    concavePath.offset(offset.fX, offset.fY);
-    return concavePath;
-}
-
-static void draw_normal_geom(SkCanvas* canvas, const SkPoint& offset, int geom, bool useAA) {
-    SkPaint p;
-    p.setAntiAlias(useAA);
-    p.setColor(SK_ColorBLACK);
-
-    switch (geom) {
-    case kRect_Geometry:                // fall thru
-    case kRectAndRect_Geometry:
-        canvas->drawRect(create_rect(offset), p);
-        break;
-    case kRRect_Geometry:               // fall thru
-    case kRectAndRRect_Geometry:
-        canvas->drawRRect(create_rrect(offset), p);
-        break;
-    case kCircle_Geometry:
-        canvas->drawRRect(create_circle(offset), p);
-        break;
-    case kConvexPath_Geometry:          // fall thru
-    case kRectAndConvex_Geometry:
-        canvas->drawPath(create_convex_path(offset), p);
-        break;
-    case kConcavePath_Geometry:         // fall thru
-    case kRectAndConcave_Geometry:
-        canvas->drawPath(create_concave_path(offset), p);
-        break;
-    }
-}
-
-class ClipDrawMatchView : public Sample {
-    SkInterpolator  fTrans;
-    Geometry        fGeom;
-    bool            fClipFirst = true;
-    int             fSign = 1;
-    const double    fStart = SkTime::GetMSecs();
-
-public:
-    ClipDrawMatchView() : fTrans(2, 5), fGeom(kRect_Geometry) {}
-
-private:
-    void onOnceBeforeDraw() override {
-        SkScalar values[2];
-
-        fTrans.setRepeatCount(999);
-        values[0] = values[1] = 0;
-        fTrans.setKeyFrame(0, GetMSecs() + 1000, values);
-        values[1] = 1;
-        fTrans.setKeyFrame(1, GetMSecs() + 2000, values);
-        values[0] = values[1] = 1;
-        fTrans.setKeyFrame(2, GetMSecs() + 3000, values);
-        values[1] = 0;
-        fTrans.setKeyFrame(3, GetMSecs() + 4000, values);
-        values[0] = 0;
-        fTrans.setKeyFrame(4, GetMSecs() + 5000, values);
-    }
-
-    SkString name() override { return SkString("ClipDrawMatch"); }
-
-    bool onChar(SkUnichar uni) override {
-            switch (uni) {
-                case '1': fGeom = kRect_Geometry; return true;
-                case '2': fGeom = kRRect_Geometry; return true;
-                case '3': fGeom = kCircle_Geometry; return true;
-                case '4': fGeom = kConvexPath_Geometry; return true;
-                case '5': fGeom = kConcavePath_Geometry; return true;
-                case '6': fGeom = kRectAndRect_Geometry; return true;
-                case '7': fGeom = kRectAndRRect_Geometry; return true;
-                case '8': fGeom = kRectAndConvex_Geometry; return true;
-                case '9': fGeom = kRectAndConcave_Geometry; return true;
-                case 'f': fSign = -fSign; return true;
-                case 't': fClipFirst = !fClipFirst; return true;
-                default: break;
-            }
-            return false;
-    }
-
-    void drawClippedGeom(SkCanvas* canvas, const SkPoint& offset, bool useAA) {
-
-        int count = canvas->save();
-
-        switch (fGeom) {
-        case kRect_Geometry:
-            canvas->clipRect(create_rect(offset), useAA);
-            break;
-        case kRRect_Geometry:
-            canvas->clipRRect(create_rrect(offset), useAA);
-            break;
-        case kCircle_Geometry:
-            canvas->clipRRect(create_circle(offset), useAA);
-            break;
-        case kConvexPath_Geometry:
-            canvas->clipPath(create_convex_path(offset), useAA);
-            break;
-        case kConcavePath_Geometry:
-            canvas->clipPath(create_concave_path(offset), useAA);
-            break;
-        case kRectAndRect_Geometry: {
-            SkRect r = create_rect(offset);
-            r.offset(fSign * kXlate, fSign * kXlate);
-            canvas->clipRect(r, true); // AA here forces shader clips
-            canvas->clipRect(create_rect(offset), useAA);
-            } break;
-        case kRectAndRRect_Geometry: {
-            SkRect r = create_rect(offset);
-            r.offset(fSign * kXlate, fSign * kXlate);
-            canvas->clipRect(r, true); // AA here forces shader clips
-            canvas->clipRRect(create_rrect(offset), useAA);
-            } break;
-        case kRectAndConvex_Geometry: {
-            SkRect r = create_rect(offset);
-            r.offset(fSign * kXlate, fSign * kXlate);
-            canvas->clipRect(r, true); // AA here forces shader clips
-            canvas->clipPath(create_convex_path(offset), useAA);
-            } break;
-        case kRectAndConcave_Geometry: {
-            SkRect r = create_rect(offset);
-            r.offset(fSign * kXlate, fSign * kXlate);
-            canvas->clipRect(r, true); // AA here forces shader clips
-            canvas->clipPath(create_concave_path(offset), useAA);
-            } break;
-        }
-
-        SkISize size = canvas->getBaseLayerSize();
-        SkRect bigR = SkRect::MakeWH(SkIntToScalar(size.width()), SkIntToScalar(size.height()));
-
-        SkPaint p;
-        p.setColor(SK_ColorRED);
-
-        canvas->drawRect(bigR, p);
-        canvas->restoreToCount(count);
-    }
-
-    // Draw a big red rect through some clip geometry and also draw that same
-    // geometry in black. The order in which they are drawn can be swapped.
-    // This tests whether the clip and normally drawn geometry match up.
-    void drawGeometry(SkCanvas* canvas, const SkPoint& offset, bool useAA) {
-        if (fClipFirst) {
-            this->drawClippedGeom(canvas, offset, useAA);
-        }
-
-        draw_normal_geom(canvas, offset, fGeom, useAA);
-
-        if (!fClipFirst) {
-            this->drawClippedGeom(canvas, offset, useAA);
-        }
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        SkScalar trans[2];
-        fTrans.timeToValues(GetMSecs(), trans);
-
-        SkPoint offset;
-        offset.set(trans[0], trans[1]);
-
-        int saveCount = canvas->save();
-        this->drawGeometry(canvas, offset, false);
-        canvas->restoreToCount(saveCount);
-    }
-
-    SkMSec GetMSecs() const {
-        return static_cast<SkMSec>(SkTime::GetMSecs() - fStart);
-    }
-};
-
-DEF_SAMPLE( return new ClipDrawMatchView(); )
diff --git a/third_party/skia/samplecode/SampleColorFilter.cpp b/third_party/skia/samplecode/SampleColorFilter.cpp
deleted file mode 100644
index 7f57a32..0000000
--- a/third_party/skia/samplecode/SampleColorFilter.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "include/core/SkCanvas.h"
-#include "include/core/SkColorFilter.h"
-#include "include/core/SkPaint.h"
-#include "include/core/SkShader.h"
-#include "samplecode/Sample.h"
-#include "tools/ToolUtils.h"
-
-static int inflate5To8(int x) {
-    return (x << 3) | (x >> 2);
-}
-
-static int trunc5(int x) {
-    return x >> 3;
-}
-
-#define SK_R16_BITS 5
-
-#ifdef SK_DEBUG
-static int round5_slow(int x) {
-    int orig = x & 7;
-    int fake = x >> 5;
-    int trunc = x >> 3;
-
-    int diff = fake - orig;
-
-    int bias = 0;
-    if (diff > 4) {
-        bias = -1;
-    } else if (diff < -4) {
-        bias = 1;
-    }
-    return trunc + bias;
-}
-#endif
-
-static int round5_fast(int x) {
-    int result = x + 3 - (x >> 5) + (x >> 7);
-    result >>= 3;
-#ifdef SK_DEBUG
-    {
-        int r2 = round5_slow(x);
-        SkASSERT(r2 == result);
-    }
-#endif
-    return result;
-}
-
-static void test_5bits() {
-    int e0 = 0;
-    int e1 = 0;
-    int e2 = 0;
-    int ae0 = 0;
-    int ae1 = 0;
-    int ae2 = 0;
-    for (int i = 0; i < 256; i++) {
-        int t0 = trunc5(i);
-        int t1 = round5_fast(i);
-        int t2 = trunc5(i);
-        int v0 = inflate5To8(t0);
-        int v1 = inflate5To8(t1);
-        int v2 = inflate5To8(t2);
-        int err0 = i - v0;
-        int err1 = i - v1;
-        int err2 = i - v2;
-        SkDebugf("--- %3d : trunc=%3d (%2d) round:%3d (%2d) \n"/*new:%d (%2d)\n"*/, i,
-                 v0, err0, v1, err1, v2, err2);
-
-
-        e0 += err0;
-        e1 += err1;
-        e2 += err2;
-        ae0 += SkAbs32(err0);
-        ae1 += SkAbs32(err1);
-        ae2 += SkAbs32(err2);
-    }
-    SkDebugf("--- trunc: %d %d  round: %d %d new: %d %d\n", e0, ae0, e1, ae1, e2, ae2);
-}
-
-static SkBitmap createBitmap(int n) {
-    SkBitmap bitmap;
-    bitmap.allocN32Pixels(n, n);
-    bitmap.eraseColor(SK_ColorTRANSPARENT);
-
-    SkCanvas canvas(bitmap);
-    SkRect r;
-    r.setWH(SkIntToScalar(n), SkIntToScalar(n));
-    r.inset(SK_Scalar1, SK_Scalar1);
-
-    SkPaint paint;
-    paint.setAntiAlias(true);
-
-    paint.setColor(SK_ColorRED);
-    canvas.drawOval(r, paint);
-
-    r.inset(SK_Scalar1*n/4, SK_Scalar1*n/4);
-    paint.setBlendMode(SkBlendMode::kSrc);
-    paint.setColor(0x800000FF);
-    canvas.drawOval(r, paint);
-
-    return bitmap;
-}
-
-class ColorFilterView : public Sample {
-    SkBitmap fBitmap;
-    sk_sp<SkShader> fShader;
-    enum {
-        N = 64
-    };
-
-    void onOnceBeforeDraw() override {
-        fBitmap = createBitmap(N);
-        fShader = ToolUtils::create_checkerboard_shader(0xFFCCCCCC, 0xFFFFFFFF, 12);
-
-        if (false) { // avoid bit rot, suppress warning
-            test_5bits();
-        }
-    }
-
-    SkString name() override { return SkString("ColorFilter"); }
-
-    void onDrawBackground(SkCanvas* canvas) override {
-        SkPaint paint;
-        paint.setShader(fShader);
-        canvas->drawPaint(paint);
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        if (false) {
-            SkPaint p;
-            p.setAntiAlias(true);
-            SkRect r = { 20.4f, 10, 20.6f, 20 };
-            canvas->drawRect(r, p);
-            r.setLTRB(30.9f, 10, 31.1f, 20);
-            canvas->drawRect(r, p);
-            return;
-        }
-
-        static const SkBlendMode gModes[] = {
-            SkBlendMode::kClear,
-            SkBlendMode::kSrc,
-            SkBlendMode::kDst,
-            SkBlendMode::kSrcOver,
-            SkBlendMode::kDstOver,
-            SkBlendMode::kSrcIn,
-            SkBlendMode::kDstIn,
-            SkBlendMode::kSrcOut,
-            SkBlendMode::kDstOut,
-            SkBlendMode::kSrcATop,
-            SkBlendMode::kDstATop,
-            SkBlendMode::kXor,
-            SkBlendMode::kPlus,
-            SkBlendMode::kModulate,
-        };
-
-        static const SkColor gColors[] = {
-            0xFF000000,
-            0x80000000,
-            0xFF00FF00,
-            0x8000FF00,
-            0x00000000,
-        };
-
-        float scale = 1.5f;
-        SkPaint paint;
-        canvas->translate(N / 8, N / 8);
-
-        for (size_t y = 0; y < SK_ARRAY_COUNT(gColors); y++) {
-            for (size_t x = 0; x < SK_ARRAY_COUNT(gModes); x++) {
-                paint.setColorFilter(SkColorFilters::Blend(gColors[y], gModes[x]));
-                canvas->drawBitmap(fBitmap, x * N * 1.25f, y * N * scale, &paint);
-            }
-        }
-
-    }
-};
-
-DEF_SAMPLE( return new ColorFilterView(); )
diff --git a/third_party/skia/samplecode/SampleComplexClip.cpp b/third_party/skia/samplecode/SampleComplexClip.cpp
index d903148..64e7af5 100644
--- a/third_party/skia/samplecode/SampleComplexClip.cpp
+++ b/third_party/skia/samplecode/SampleComplexClip.cpp
@@ -9,7 +9,6 @@
 #include "include/core/SkFont.h"
 #include "include/core/SkPath.h"
 #include "samplecode/Sample.h"
-#include "src/core/SkClipOpPriv.h"
 
 class ComplexClipView : public Sample {
     void onOnceBeforeDraw() override {
@@ -78,11 +77,8 @@
             SkClipOp    fOp;
             const char* fName;
         } gOps[] = { //extra spaces in names for measureText
-            {kIntersect_SkClipOp,         "Isect "},
-            {kDifference_SkClipOp,        "Diff " },
-            {kUnion_SkClipOp,             "Union "},
-            {kXOR_SkClipOp,               "Xor "  },
-            {kReverseDifference_SkClipOp, "RDiff "}
+            {SkClipOp::kIntersect,         "Isect "},
+            {SkClipOp::kDifference,        "Diff " },
         };
 
         canvas->translate(0, SkIntToScalar(40));
diff --git a/third_party/skia/samplecode/SampleCowboy.cpp b/third_party/skia/samplecode/SampleCowboy.cpp
index 6ba3177..2ed47cb 100644
--- a/third_party/skia/samplecode/SampleCowboy.cpp
+++ b/third_party/skia/samplecode/SampleCowboy.cpp
@@ -7,12 +7,13 @@
 
 #include "include/core/SkTypes.h"
 
-#ifdef SK_XML
+#if defined(SK_ENABLE_SVG)
 
-#include "experimental/svg/model/SkSVGDOM.h"
 #include "include/core/SkCanvas.h"
 #include "include/core/SkRect.h"
 #include "include/core/SkStream.h"
+#include "modules/svg/include/SkSVGDOM.h"
+#include "modules/svg/include/SkSVGNode.h"
 #include "samplecode/Sample.h"
 #include "src/core/SkOSFile.h"
 #include "src/utils/SkOSPath.h"
@@ -21,7 +22,7 @@
 
 namespace {
 class AnimatedSVGSample : public Sample {
-    static constexpr auto kAnimationIterations = 5;
+    inline static constexpr auto kAnimationIterations = 5;
     enum State {
         kZoomIn,
         kScroll,
@@ -47,13 +48,7 @@
         }
         SkMemoryStream svgStream(std::move(data));
 
-        SkDOM xmlDom;
-        if (!xmlDom.build(svgStream)) {
-            SkDebugf("XML parsing failed: \"%s\"\n", fResource);
-            return;
-        }
-
-        fDom = SkSVGDOM::MakeFromDOM(xmlDom);
+        fDom = SkSVGDOM::MakeFromStream(svgStream);
         if (fDom) {
             fDom->setContainerSize(SkSize::Make(this->width(), this->height()));
         }
@@ -61,12 +56,12 @@
 
     void onDrawContent(SkCanvas* canvas) override {
         if (fDom) {
-            canvas->setMatrix(SkMatrix::MakeScale(3));
+            canvas->setMatrix(SkMatrix::Scale(3, 3));
             canvas->clipRect(SkRect::MakeLTRB(0, 0, 400, 400));
             switch (fState) {
                 case kZoomIn:
                     fDelta += 0.2f;
-                    canvas->concat(SkMatrix::MakeScale(fDelta));
+                    canvas->scale(fDelta, fDelta);
                     break;
                 case kScroll:
                     if (fAnimationLoop > kAnimationIterations/2) {
@@ -74,12 +69,12 @@
                     } else {
                         fDelta -= 80.f;
                     }
-                    canvas->concat(SkMatrix::MakeScale(fDelta));
+                    canvas->scale(fDelta, fDelta);
                     canvas->translate(fDelta, 0);
                     break;
                 case kZoomOut:
                     fDelta += 0.2f;
-                    canvas->concat(SkMatrix::MakeScale(fDelta));
+                    canvas->scale(fDelta, fDelta);
                     break;
             }
 
@@ -125,4 +120,4 @@
 
 DEF_SAMPLE( return new AnimatedSVGSample("Cowboy.svg", "SampleCowboy"); )
 
-#endif  // SK_XML
+#endif  // defined(SK_ENABLE_SVG)
diff --git a/third_party/skia/samplecode/SampleCusp.cpp b/third_party/skia/samplecode/SampleCusp.cpp
index 28b1233..543a3a3 100644
--- a/third_party/skia/samplecode/SampleCusp.cpp
+++ b/third_party/skia/samplecode/SampleCusp.cpp
@@ -144,12 +144,14 @@
         bool split;
         path = cusp(pts, pp, split, 8000, .125);
         auto debugOutCubic = [](const SkPoint* pts) {
-            return false; // comment out to capture stream of cusp'd cubics in stdout
-            SkDebugf("{{");
-            for (int i = 0; i < 4; ++i) {
-                SkDebugf("{0x%08x,0x%08x},", SkFloat2Bits(pts[i].fX), SkFloat2Bits(pts[i].fY));
+            if ((false)) { // enable to capture stream of cusp'd cubics in stdout
+                SkDebugf("{{");
+                for (int i = 0; i < 4; ++i) {
+                    SkDebugf("{0x%08x,0x%08x},", SkFloat2Bits(pts[i].fX), SkFloat2Bits(pts[i].fY));
+                }
+                SkDebugf("}},\n");
             }
-            SkDebugf("}},\n");
+            return false;
         };
         if (split) {
             debugOutCubic(&pp[0]);
@@ -162,7 +164,6 @@
         // draw time to make it easier to guess when the bad cubic was drawn
         std::string timeStr = std::to_string((float) (curTime - start) / 1000.f);
         canvas->drawSimpleText(timeStr.c_str(), timeStr.size(), SkTextEncoding::kUTF8, 20, 20, SkFont(), SkPaint());
-        SkDebugf("");
     }
 
     bool onAnimate(double nanos) override {
@@ -175,7 +176,7 @@
 
 private:
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 DEF_SAMPLE( return new CuspView(); )
diff --git a/third_party/skia/samplecode/SampleDegenerateQuads.cpp b/third_party/skia/samplecode/SampleDegenerateQuads.cpp
index 3d48cec..e3ab138 100644
--- a/third_party/skia/samplecode/SampleDegenerateQuads.cpp
+++ b/third_party/skia/samplecode/SampleDegenerateQuads.cpp
@@ -8,12 +8,18 @@
 #include "samplecode/Sample.h"
 
 #include "src/gpu/geometry/GrQuad.h"
-#include "src/gpu/ops/GrQuadPerEdgeAA.h"
+#include "src/gpu/ops/QuadPerEdgeAA.h"
 
 #include "include/core/SkCanvas.h"
 #include "include/core/SkPaint.h"
 #include "include/effects/SkDashPathEffect.h"
 #include "include/pathops/SkPathOps.h"
+#include "include/private/SkTPin.h"
+
+using VertexSpec = skgpu::v1::QuadPerEdgeAA::VertexSpec;
+using ColorType = skgpu::v1::QuadPerEdgeAA::ColorType;
+using Subset = skgpu::v1::QuadPerEdgeAA::Subset;
+using IndexBufferOption = skgpu::v1::QuadPerEdgeAA::IndexBufferOption;
 
 // Draw a line through the two points, outset by a fixed length in screen space
 static void draw_extended_line(SkCanvas* canvas, const SkPaint paint,
@@ -216,11 +222,11 @@
             SkScalar coverage = bary[0] * c0 + bary[1] * c1 + bary[2] * c2;
             if (coverage < 0.5f) {
                 // Check distances to domain
-                SkScalar l = SkScalarPin(point.fX - geomDomain.fLeft, 0.f, 1.f);
-                SkScalar t = SkScalarPin(point.fY - geomDomain.fTop, 0.f, 1.f);
-                SkScalar r = SkScalarPin(geomDomain.fRight - point.fX, 0.f, 1.f);
-                SkScalar b = SkScalarPin(geomDomain.fBottom - point.fY, 0.f, 1.f);
-                coverage = SkMinScalar(coverage, l * t * r * b);
+                SkScalar l = SkTPin(point.fX - geomDomain.fLeft, 0.f, 1.f);
+                SkScalar t = SkTPin(point.fY - geomDomain.fTop, 0.f, 1.f);
+                SkScalar r = SkTPin(geomDomain.fRight - point.fX, 0.f, 1.f);
+                SkScalar b = SkTPin(geomDomain.fBottom - point.fY, 0.f, 1.f);
+                coverage = std::min(coverage, l * t * r * b);
             }
             return coverage;
         }
@@ -406,10 +412,10 @@
     void getTessellatedPoints(SkPoint inset[4], SkScalar insetCoverage[4], SkPoint outset[4],
                               SkScalar outsetCoverage[4], SkRect* domain) const {
         // Fixed vertex spec for extracting the picture frame geometry
-        static const GrQuadPerEdgeAA::VertexSpec kSpec =
-            {GrQuad::Type::kGeneral, GrQuadPerEdgeAA::ColorType::kNone,
-             GrQuad::Type::kAxisAligned, false, GrQuadPerEdgeAA::Domain::kNo,
-             GrAAType::kCoverage, false, GrQuadPerEdgeAA::IndexBufferOption::kPictureFramed};
+        static const VertexSpec kSpec =
+            {GrQuad::Type::kGeneral, ColorType::kNone,
+             GrQuad::Type::kAxisAligned, false, Subset::kNo,
+             GrAAType::kCoverage, false, IndexBufferOption::kPictureFramed};
         static const GrQuad kIgnored(SkRect::MakeEmpty());
 
         GrQuadAAFlags flags = GrQuadAAFlags::kNone;
@@ -421,7 +427,7 @@
         GrQuad quad = GrQuad::MakeFromSkQuad(fCorners, SkMatrix::I());
 
         float vertices[56]; // 2 quads, with x, y, coverage, and geometry domain (7 floats x 8 vert)
-        GrQuadPerEdgeAA::Tessellator tessellator(kSpec, (char*) vertices);
+        skgpu::v1::QuadPerEdgeAA::Tessellator tessellator(kSpec, (char*) vertices);
         tessellator.append(&quad, nullptr, {1.f, 1.f, 1.f, 1.f},
                            SkRect::MakeEmpty(), flags);
 
@@ -448,7 +454,7 @@
         *domain = {vertices[52], vertices[53], vertices[54], vertices[55]};
     }
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 class DegenerateQuadSample::Click : public Sample::Click {
@@ -474,8 +480,8 @@
     void drag(SkPoint* point) {
         SkPoint delta = fCurr - fPrev;
         *point += SkPoint::Make(delta.x() / kViewScale, delta.y() / kViewScale);
-        point->fX = SkMinScalar(fOuterRect.fRight, SkMaxScalar(point->fX, fOuterRect.fLeft));
-        point->fY = SkMinScalar(fOuterRect.fBottom, SkMaxScalar(point->fY, fOuterRect.fTop));
+        point->fX = std::min(fOuterRect.fRight, std::max(point->fX, fOuterRect.fLeft));
+        point->fY = std::min(fOuterRect.fBottom, std::max(point->fY, fOuterRect.fTop));
     }
 };
 
diff --git a/third_party/skia/samplecode/SampleDegenerateTwoPtRadials.cpp b/third_party/skia/samplecode/SampleDegenerateTwoPtRadials.cpp
index f26403e..f0c74be 100644
--- a/third_party/skia/samplecode/SampleDegenerateTwoPtRadials.cpp
+++ b/third_party/skia/samplecode/SampleDegenerateTwoPtRadials.cpp
@@ -73,7 +73,7 @@
 
 private:
     SkScalar           fTime;
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleEffects.cpp b/third_party/skia/samplecode/SampleEffects.cpp
index f22aea1..5a49ded 100644
--- a/third_party/skia/samplecode/SampleEffects.cpp
+++ b/third_party/skia/samplecode/SampleEffects.cpp
@@ -86,9 +86,9 @@
     }
 
 protected:
-    virtual SkString name() { return SkString("Effects"); }
+    SkString name() override { return SkString("Effects"); }
 
-    virtual void onDrawContent(SkCanvas* canvas) {
+    void onDrawContent(SkCanvas* canvas) override {
         canvas->scale(3, 3);
         canvas->translate(10, 30);
         for (size_t i = 0; i < SK_ARRAY_COUNT(fPaint); i++) {
@@ -98,7 +98,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleEmboss.cpp b/third_party/skia/samplecode/SampleEmboss.cpp
index beacecb..0c49a85 100644
--- a/third_party/skia/samplecode/SampleEmboss.cpp
+++ b/third_party/skia/samplecode/SampleEmboss.cpp
@@ -33,9 +33,9 @@
     }
 
 protected:
-    virtual SkString name() { return SkString("Emboss"); }
+    SkString name() override { return SkString("Emboss"); }
 
-    virtual void onDrawContent(SkCanvas* canvas) {
+    void onDrawContent(SkCanvas* canvas) override {
         SkPaint paint;
 
         paint.setAntiAlias(true);
@@ -51,7 +51,7 @@
 
 private:
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleFatBits.cpp b/third_party/skia/samplecode/SampleFatBits.cpp
index f1dcd29..f80fb25 100644
--- a/third_party/skia/samplecode/SampleFatBits.cpp
+++ b/third_party/skia/samplecode/SampleFatBits.cpp
@@ -21,7 +21,6 @@
 #include "include/core/SkSurface.h"
 #include "include/core/SkTypes.h"
 #include "samplecode/Sample.h"
-#include "src/core/SkClipOpPriv.h"
 #include "src/core/SkPointPriv.h"
 #include "tools/ToolUtils.h"
 
@@ -172,7 +171,7 @@
         SkCanvas* canvas = fMaxSurface->getCanvas();
         canvas->save();
         canvas->concat(fMatrix);
-        fMinSurface->draw(canvas, 0, 0, nullptr);
+        fMinSurface->draw(canvas, 0, 0);
         canvas->restore();
 
         SkPaint paint;
@@ -271,7 +270,7 @@
         fMinSurface->getCanvas()->save();
         SkRect r = fClipRect;
         r.inset(SK_Scalar1/3, SK_Scalar1/3);
-        fMinSurface->getCanvas()->clipRect(r, kIntersect_SkClipOp, true);
+        fMinSurface->getCanvas()->clipRect(r, SkClipOp::kIntersect, true);
     }
     fMinSurface->getCanvas()->drawLine(pts[0], pts[1], paint);
     if (fUseClip) {
@@ -284,7 +283,7 @@
     fMatrix.mapPoints(pts, 2);
     this->drawLineSkeleton(max, pts);
 
-    fMaxSurface->draw(canvas, 0, 0, nullptr);
+    fMaxSurface->draw(canvas, 0, 0);
 }
 
 void FatBits::drawRect(SkCanvas* canvas, SkPoint pts[2]) {
@@ -314,7 +313,7 @@
     r.setBounds(pts, 2);
     this->drawRectSkeleton(max, r);
 
-    fMaxSurface->draw(canvas, 0, 0, nullptr);
+    fMaxSurface->draw(canvas, 0, 0);
 }
 
 void FatBits::drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]) {
@@ -356,7 +355,7 @@
     fMatrix.mapPoints(pts, 3);
     this->drawTriangleSkeleton(max, pts);
 
-    fMaxSurface->draw(canvas, 0, 0, nullptr);
+    fMaxSurface->draw(canvas, 0, 0);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -382,7 +381,7 @@
         fPts[0].set(1, 1);
         fPts[1].set(5, 4);
         fPts[2].set(2, 6);
-        SkMatrix::MakeScale(SkIntToScalar(fZoom)).mapPoints(fPts, 3);
+        SkMatrix::Scale(fZoom, fZoom).mapPoints(fPts, 3);
         fIsRect = false;
     }
 
@@ -499,7 +498,7 @@
 
 private:
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleFillType.cpp b/third_party/skia/samplecode/SampleFillType.cpp
index 230f41b..7330549 100644
--- a/third_party/skia/samplecode/SampleFillType.cpp
+++ b/third_party/skia/samplecode/SampleFillType.cpp
@@ -25,7 +25,7 @@
     }
 
 protected:
-    virtual SkString name() { return SkString("FillType"); }
+    SkString name() override{ return SkString("FillType"); }
 
     void showPath(SkCanvas* canvas, int x, int y, SkPathFillType ft,
                   SkScalar scale, const SkPaint& paint) {
@@ -55,7 +55,7 @@
                  scale, paint);
     }
 
-    virtual void onDrawContent(SkCanvas* canvas) {
+    void onDrawContent(SkCanvas* canvas) override {
         canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
 
         SkPaint paint;
@@ -77,7 +77,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleFilter2.cpp b/third_party/skia/samplecode/SampleFilter2.cpp
deleted file mode 100644
index 453bfa7..0000000
--- a/third_party/skia/samplecode/SampleFilter2.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkFont.h"
-#include "include/core/SkString.h"
-#include "include/utils/SkTextUtils.h"
-#include "samplecode/DecodeFile.h"
-#include "samplecode/Sample.h"
-#include "tools/Resources.h"
-
-#include <vector>
-
-static const char* gNames[] = {
-    "images/mandrill_512_q075.jpg",
-    "images/dog.jpg",
-};
-
-struct Filter2View : public Sample {
-    std::vector<SkBitmap> fBitmaps;
-
-    void onOnceBeforeDraw() override {
-        SkASSERT(fBitmaps.empty());
-        fBitmaps.reserve(SK_ARRAY_COUNT(gNames) * 2);
-        for (const char* name : gNames) {
-            SkBitmap bitmap;
-            (void)decode_file(GetResourceAsData(name), &bitmap);
-            fBitmaps.push_back(std::move(bitmap));
-        }
-        for (const char* name : gNames) {
-            SkBitmap bitmap;
-            (void)decode_file(GetResourceAsData(name), &bitmap, kRGB_565_SkColorType);
-            fBitmaps.push_back(std::move(bitmap));
-        }
-        this->setBGColor(SK_ColorGRAY);
-    }
-
-    SkString name() override { return SkString("Filter/Dither"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->translate(SkIntToScalar(10), SkIntToScalar(50));
-
-        const SkScalar W = SkIntToScalar(fBitmaps[0].width() + 1);
-        const SkScalar H = SkIntToScalar(fBitmaps[0].height() + 1);
-        SkPaint paint;
-
-        const SkScalar scale = 0.897917f;
-        canvas->scale(SK_Scalar1, scale);
-
-        for (int k = 0; k < 2; k++) {
-            paint.setFilterQuality(k == 1 ? kLow_SkFilterQuality : kNone_SkFilterQuality);
-            for (int j = 0; j < 2; j++) {
-                paint.setDither(j == 1);
-                for (int i = 0; i < (int)fBitmaps.size(); i++) {
-                    SkScalar x = (k * (int)fBitmaps.size() + j) * W;
-                    SkScalar y = i * H;
-                    x = SkScalarRoundToScalar(x);
-                    y = SkScalarRoundToScalar(y);
-                    canvas->drawBitmap(fBitmaps[i], x, y, &paint);
-                    SkFont font;
-                    font.setSize(SkIntToScalar(18));
-                    if (i == 0) {
-                        SkString s("dither=");
-                        s.appendS32(paint.isDither());
-                        s.append(" filter=");
-                        s.appendS32(paint.getFilterQuality() != kNone_SkFilterQuality);
-                        SkTextUtils::DrawString(canvas, s.c_str(), x + W/2, y - font.getSize(), font, SkPaint(),
-                                                SkTextUtils::kCenter_Align);
-                    }
-                    if (k+j == 2) {
-                        SkString s;
-                        s.append(" depth=");
-                        s.appendS32(fBitmaps[i].colorType() == kRGB_565_SkColorType ? 16 : 32);
-                        SkTextUtils::DrawString(canvas, s.c_str(), x + W + SkIntToScalar(4), y + H/2, font, SkPaint());
-                    }
-                }
-            }
-        }
-    }
-};
-DEF_SAMPLE( return new Filter2View(); )
diff --git a/third_party/skia/samplecode/SampleFilterBounds.cpp b/third_party/skia/samplecode/SampleFilterBounds.cpp
new file mode 100644
index 0000000..682891c
--- /dev/null
+++ b/third_party/skia/samplecode/SampleFilterBounds.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "samplecode/Sample.h"
+
+#include "include/core/SkBitmap.h"
+#include "include/core/SkCanvas.h"
+#include "include/core/SkColor.h"
+#include "include/core/SkFont.h"
+#include "include/core/SkPaint.h"
+#include "include/core/SkPath.h"
+#include "include/core/SkPoint.h"
+#include "include/core/SkRect.h"
+#include "include/effects/SkDashPathEffect.h"
+#include "include/effects/SkGradientShader.h"
+#include "include/effects/SkImageFilters.h"
+
+#include "src/core/SkImageFilterTypes.h"
+#include "src/core/SkImageFilter_Base.h"
+#include "src/core/SkMatrixPriv.h"
+
+#include "tools/ToolUtils.h"
+
+static constexpr float kLineHeight = 16.f;
+static constexpr float kLineInset = 8.f;
+
+static float print_size(SkCanvas* canvas, const char* prefix, const SkIRect& rect,
+                        float x, float y, const SkFont& font, const SkPaint& paint) {
+    canvas->drawString(prefix, x, y, font, paint);
+    y += kLineHeight;
+    SkString sz;
+    sz.appendf("%d x %d", rect.width(), rect.height());
+    canvas->drawString(sz, x, y, font, paint);
+    return y + kLineHeight;
+}
+
+static float print_info(SkCanvas* canvas,
+                        const SkIRect& layerContentBounds,
+                        const SkIRect& outputBounds,
+                        const SkIRect& hintedOutputBounds,
+                        const SkIRect& unhintedLayerBounds) {
+    SkFont font(nullptr, 12);
+    SkPaint text;
+    text.setAntiAlias(true);
+
+    float y = kLineHeight;
+
+    text.setColor(SK_ColorRED);
+    y = print_size(canvas, "Content (in layer)", layerContentBounds, kLineInset, y, font, text);
+    text.setColor(SK_ColorDKGRAY);
+    y = print_size(canvas, "Target (in device)", outputBounds, kLineInset, y, font, text);
+    text.setColor(SK_ColorBLUE);
+    y = print_size(canvas, "Output (w/ hint)", hintedOutputBounds, kLineInset, y, font, text);
+    text.setColor(SK_ColorGREEN);
+    y = print_size(canvas, "Input (w/ no hint)", unhintedLayerBounds, kLineInset, y, font, text);
+
+    return y;
+}
+
+static void print_label(SkCanvas* canvas, float x, float y, float value) {
+    SkFont font(nullptr, 12);
+    SkPaint text;
+    text.setAntiAlias(true);
+
+    SkString label;
+    label.printf("%.3f", value);
+
+    canvas->drawString(label, x, y + kLineHeight / 2.f, font, text);
+}
+
+static SkPaint line_paint(SkColor color, bool dashed = false) {
+    SkPaint paint;
+    paint.setColor(color);
+    paint.setStrokeWidth(0.f);
+    paint.setStyle(SkPaint::kStroke_Style);
+    paint.setAntiAlias(true);
+    if (dashed) {
+        SkScalar dash[2] = {10.f, 10.f};
+        paint.setPathEffect(SkDashPathEffect::Make(dash, 2, 0.f));
+    }
+    return paint;
+}
+
+static SkPath create_axis_path(const SkRect& rect, float axisSpace) {
+    SkPath localSpace;
+    for (float y = rect.fTop + axisSpace; y <= rect.fBottom; y += axisSpace) {
+        localSpace.moveTo(rect.fLeft, y);
+        localSpace.lineTo(rect.fRight, y);
+    }
+    for (float x = rect.fLeft + axisSpace; x <= rect.fRight; x += axisSpace) {
+        localSpace.moveTo(x, rect.fTop);
+        localSpace.lineTo(x, rect.fBottom);
+    }
+    return localSpace;
+}
+
+static const SkColor4f kScaleGradientColors[] =
+                { { 0.05f, 0.0f, 6.f,  1.f },   // Severe downscaling, s < 1/8, log(s) < -3
+                  { 0.6f,  0.6f, 0.8f, 0.6f },  // Okay downscaling,   s < 1/2, log(s) < -1
+                  { 1.f,   1.f,  1.f,  0.2f },  // No scaling,         s = 1,   log(s) = 0
+                  { 0.95f, 0.6f, 0.5f, 0.6f },  // Okay upscaling,     s > 2,   log(s) > 1
+                  { 0.8f,  0.1f, 0.f,  1.f } }; // Severe upscaling,   s > 8,   log(s) > 3
+static const SkScalar kLogScaleFactors[] = { -3.f, -1.f, 0.f, 1.f, 3.f };
+static const SkScalar kGradientStops[] = { 0.f, 0.33333f, 0.5f, 0.66667f, 1.f };
+static const int kStopCount = (int) SK_ARRAY_COUNT(kScaleGradientColors);
+
+static void draw_scale_key(SkCanvas* canvas, float y) {
+    SkRect key = SkRect::MakeXYWH(15.f, y + 30.f, 15.f, 100.f);
+    SkPoint pts[] = {{key.centerX(), key.fTop}, {key.centerX(), key.fBottom}};
+    sk_sp<SkShader> gradient = SkGradientShader::MakeLinear(
+            pts, kScaleGradientColors, nullptr, kGradientStops, kStopCount, SkTileMode::kClamp,
+            SkGradientShader::kInterpolateColorsInPremul_Flag, nullptr);
+    SkPaint keyPaint;
+    keyPaint.setShader(gradient);
+    canvas->drawRect(key, keyPaint);
+    for (int i = 0; i < kStopCount; ++i) {
+        print_label(canvas, key.fRight + 5.f, key.fTop + kGradientStops[i] * key.height(),
+                    SkScalarPow(2.f, kLogScaleFactors[i]));
+    }
+}
+
+static void draw_scale_factors(SkCanvas* canvas, const skif::Mapping& mapping, const SkRect& rect) {
+    SkPoint testPoints[5];
+    testPoints[0] = {rect.centerX(), rect.centerY()};
+    rect.toQuad(testPoints + 1);
+    for (int i = 0; i < 5; ++i) {
+        float scale = SkMatrixPriv::DifferentialAreaScale(
+                mapping.deviceMatrix(),
+                SkPoint(mapping.paramToLayer(skif::ParameterSpace<SkPoint>(testPoints[i]))));
+        SkColor4f color = {0.f, 0.f, 0.f, 1.f};
+
+        if (SkScalarIsFinite(scale)) {
+            float logScale = SkScalarLog2(scale);
+            for (int j = 0; j <= kStopCount; ++j) {
+                if (j == kStopCount) {
+                    color = kScaleGradientColors[j - 1];
+                    break;
+                } else if (kLogScaleFactors[j] >= logScale) {
+                    if (j == 0) {
+                        color = kScaleGradientColors[0];
+                    } else {
+                        SkScalar t = (logScale - kLogScaleFactors[j - 1]) /
+                                    (kLogScaleFactors[j] - kLogScaleFactors[j - 1]);
+
+                        SkColor4f a = kScaleGradientColors[j - 1] * (1.f - t);
+                        SkColor4f b = kScaleGradientColors[j] * t;
+                        color = {a.fR + b.fR, a.fG + b.fG, a.fB + b.fB, a.fA + b.fA};
+                    }
+                    break;
+                }
+            }
+        }
+
+        SkPaint p;
+        p.setAntiAlias(true);
+        p.setColor4f(color, nullptr);
+        canvas->drawRect(SkRect::MakeLTRB(testPoints[i].fX - 4.f, testPoints[i].fY - 4.f,
+                                          testPoints[i].fX + 4.f, testPoints[i].fY + 4.f), p);
+    }
+}
+
+class FilterBoundsSample : public Sample {
+public:
+    FilterBoundsSample() {}
+
+    void onOnceBeforeDraw() override {
+        fBlur = SkImageFilters::Blur(8.f, 8.f, nullptr);
+        fImage = ToolUtils::create_checkerboard_image(
+                300, 300, SK_ColorMAGENTA, SK_ColorLTGRAY, 50);
+    }
+
+    void onDrawContent(SkCanvas* canvas) override {
+        // The local content, e.g. what would be submitted to drawRect or the bounds to saveLayer
+        const SkRect localContentRect = SkRect::MakeLTRB(100.f, 20.f, 180.f, 140.f);
+        SkMatrix ctm = canvas->getLocalToDeviceAs3x3();
+
+        // Base rendering of a filter
+        SkPaint blurPaint;
+        blurPaint.setImageFilter(fBlur);
+        canvas->saveLayer(&localContentRect, &blurPaint);
+        canvas->drawImageRect(fImage.get(), localContentRect, localContentRect,
+                              SkSamplingOptions(SkFilterMode::kLinear),
+                              nullptr, SkCanvas::kFast_SrcRectConstraint);
+        canvas->restore();
+
+        // Now visualize the underlying bounds calculations used to determine the layer for the blur
+        SkIRect target = ctm.mapRect(localContentRect).roundOut();
+        if (!target.intersect(SkIRect::MakeWH(canvas->imageInfo().width(),
+                                              canvas->imageInfo().height()))) {
+            return;
+        }
+        skif::DeviceSpace<SkIRect> targetOutput(target);
+        skif::ParameterSpace<SkRect> contentBounds(localContentRect);
+        skif::ParameterSpace<SkPoint> contentCenter({localContentRect.centerX(),
+                                                     localContentRect.centerY()});
+        skif::Mapping mapping;
+        SkAssertResult(mapping.decomposeCTM(ctm, fBlur.get(), contentCenter));
+
+        // Add axis lines, to show perspective distortion
+        canvas->save();
+        canvas->setMatrix(mapping.deviceMatrix());
+        canvas->drawPath(create_axis_path(SkRect(mapping.paramToLayer(contentBounds)), 20.f),
+                         line_paint(SK_ColorGRAY));
+        canvas->restore();
+
+        // Visualize scale factors at the four corners and center of the local rect
+        draw_scale_factors(canvas, mapping, localContentRect);
+
+        // The device content rect, e.g. the clip bounds if 'localContentRect' were used as a clip
+        // before the draw or saveLayer, representing what the filter must cover if it affects
+        // transparent black or doesn't have a local content hint.
+        canvas->setMatrix(SkMatrix::I());
+        canvas->drawRect(ctm.mapRect(localContentRect), line_paint(SK_ColorDKGRAY));
+
+        // Layer bounds for the filter, in the layer space compatible with the filter's matrix
+        // type requirements.
+        skif::LayerSpace<SkIRect> targetOutputInLayer = mapping.deviceToLayer(targetOutput);
+        skif::LayerSpace<SkIRect> hintedLayerBounds = as_IFB(fBlur)->getInputBounds(
+                mapping, targetOutput, &contentBounds);
+        skif::LayerSpace<SkIRect> unhintedLayerBounds = as_IFB(fBlur)->getInputBounds(
+                mapping, targetOutput, nullptr);
+
+        canvas->setMatrix(mapping.deviceMatrix());
+        canvas->drawRect(SkRect::Make(SkIRect(targetOutputInLayer)),
+                         line_paint(SK_ColorDKGRAY, true));
+        canvas->drawRect(SkRect::Make(SkIRect(hintedLayerBounds)), line_paint(SK_ColorRED));
+        canvas->drawRect(SkRect::Make(SkIRect(unhintedLayerBounds)), line_paint(SK_ColorGREEN));
+
+        // For visualization purposes, we want to show the layer-space output, this is what we get
+        // when contentBounds is provided as a hint in local/parameter space.
+        skif::Mapping layerOnly{mapping.layerMatrix()};
+        skif::DeviceSpace<SkIRect> hintedOutputBounds = as_IFB(fBlur)->getOutputBounds(
+                layerOnly, contentBounds);
+        canvas->drawRect(SkRect::Make(SkIRect(hintedOutputBounds)), line_paint(SK_ColorBLUE));
+
+        canvas->resetMatrix();
+        float y = print_info(canvas, SkIRect(mapping.paramToLayer(contentBounds).roundOut()),
+                             SkIRect(targetOutput),
+                             SkIRect(hintedOutputBounds),
+                             SkIRect(unhintedLayerBounds));
+
+        // Draw color key for layer visualization
+        draw_scale_key(canvas, y);
+    }
+
+    SkString name() override { return SkString("FilterBounds"); }
+
+private:
+    sk_sp<SkImageFilter> fBlur;
+    sk_sp<SkImage>       fImage;
+
+    using INHERITED = Sample;
+};
+
+DEF_SAMPLE(return new FilterBoundsSample();)
diff --git a/third_party/skia/samplecode/SampleFilterQuality.cpp b/third_party/skia/samplecode/SampleFilterQuality.cpp
deleted file mode 100644
index f18a1a6..0000000
--- a/third_party/skia/samplecode/SampleFilterQuality.cpp
+++ /dev/null
@@ -1,292 +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.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkData.h"
-#include "include/core/SkFont.h"
-#include "include/core/SkPath.h"
-#include "include/core/SkSurface.h"
-#include "include/core/SkTime.h"
-#include "include/effects/SkGradientShader.h"
-#include "include/utils/SkInterpolator.h"
-#include "include/utils/SkRandom.h"
-#include "samplecode/Sample.h"
-#include "tools/Resources.h"
-#include "tools/timer/TimeUtils.h"
-
-static sk_sp<SkSurface> make_surface(SkCanvas* canvas, const SkImageInfo& info) {
-    auto surface = canvas->makeSurface(info);
-    if (!surface) {
-        surface = SkSurface::MakeRaster(info);
-    }
-    return surface;
-}
-
-static sk_sp<SkShader> make_shader(const SkRect& bounds) {
-    sk_sp<SkImage> image(GetResourceAsImage("images/mandrill_128.png"));
-    return image ? image->makeShader() : nullptr;
-}
-
-#define N   128
-#define ANGLE_DELTA 3
-#define SCALE_DELTA (SK_Scalar1 / 32)
-
-static sk_sp<SkImage> make_image() {
-    SkImageInfo info = SkImageInfo::MakeN32(N, N, kOpaque_SkAlphaType);
-    auto surface(SkSurface::MakeRaster(info));
-    SkCanvas* canvas = surface->getCanvas();
-    canvas->drawColor(SK_ColorWHITE);
-
-    SkPath path;
-    path.setFillType(SkPathFillType::kEvenOdd);
-
-    path.addRect(SkRect::MakeWH(N/2, N));
-    path.addRect(SkRect::MakeWH(N, N/2));
-    path.moveTo(0, 0); path.lineTo(N, 0); path.lineTo(0, N); path.close();
-
-    SkPaint paint;
-    paint.setShader(make_shader(SkRect::MakeWH(N, N)));
-
-    canvas->drawPath(path, paint);
-    return surface->makeImageSnapshot();
-}
-
-static sk_sp<SkImage> zoom_up(SkSurface* origSurf, SkImage* orig) {
-    const SkScalar S = 16;    // amount to scale up
-    const int D = 2;    // dimension scaling for the offscreen
-    // since we only view the center, don't need to produce the entire thing
-
-    SkImageInfo info = SkImageInfo::MakeN32(orig->width() * D, orig->height() * D,
-                                            kOpaque_SkAlphaType);
-    auto surface(origSurf->makeSurface(info));
-    SkCanvas* canvas = surface->getCanvas();
-    canvas->drawColor(SK_ColorWHITE);
-    canvas->scale(S, S);
-    canvas->translate(-SkScalarHalf(orig->width()) * (S - D) / S,
-                      -SkScalarHalf(orig->height()) * (S - D) / S);
-    canvas->drawImage(orig, 0, 0, nullptr);
-
-    if (S > 3) {
-        SkPaint paint;
-        paint.setColor(SK_ColorWHITE);
-        for (int i = 1; i < orig->height(); ++i) {
-            SkScalar y = SkIntToScalar(i);
-            canvas->drawLine(0, y, SkIntToScalar(orig->width()), y, paint);
-        }
-        for (int i = 1; i < orig->width(); ++i) {
-            SkScalar x = SkIntToScalar(i);
-            canvas->drawLine(x, 0, x, SkIntToScalar(orig->height()), paint);
-        }
-    }
-    return surface->makeImageSnapshot();
-}
-
-struct AnimValue {
-    SkScalar fValue;
-    SkScalar fMin;
-    SkScalar fMax;
-    SkScalar fMod;
-
-    operator SkScalar() const { return fValue; }
-
-    void set(SkScalar value, SkScalar min, SkScalar max) {
-        fValue = value;
-        fMin = min;
-        fMax = max;
-        fMod = 0;
-    }
-
-    void setMod(SkScalar value, SkScalar mod) {
-        fValue = value;
-        fMin = 0;
-        fMax = 0;
-        fMod = mod;
-    }
-
-    SkScalar inc(SkScalar delta) {
-        fValue += delta;
-        return this->fixUp();
-    }
-
-    SkScalar fixUp() {
-        if (fMod) {
-            fValue = SkScalarMod(fValue, fMod);
-        } else {
-            if (fValue > fMax) {
-                fValue = fMax;
-            } else if (fValue < fMin) {
-                fValue = fMin;
-            }
-        }
-        return fValue;
-    }
-};
-
-static void draw_box_frame(SkCanvas* canvas, int width, int height) {
-    SkPaint p;
-    p.setStyle(SkPaint::kStroke_Style);
-    p.setColor(SK_ColorRED);
-    SkRect r = SkRect::MakeIWH(width, height);
-    r.inset(0.5f, 0.5f);
-    canvas->drawRect(r, p);
-    canvas->drawLine(r.left(), r.top(), r.right(), r.bottom(), p);
-    canvas->drawLine(r.left(), r.bottom(), r.right(), r.top(), p);
-}
-
-class FilterQualityView : public Sample {
-    sk_sp<SkImage>  fImage;
-    AnimValue       fScale, fAngle;
-    SkSize          fCell;
-    SkInterpolator  fTrans;
-    SkMSec          fCurrTime;
-    bool            fShowFatBits;
-
-public:
-    FilterQualityView() : fTrans(2, 2), fShowFatBits(true) {
-        fCell.set(256, 256);
-
-        fScale.set(1, SK_Scalar1 / 8, 1);
-        fAngle.setMod(0, 360);
-
-        SkScalar values[2];
-        fTrans.setMirror(true);
-        fTrans.setReset(true);
-
-        fCurrTime = 0;
-
-        fTrans.setRepeatCount(999);
-        values[0] = values[1] = 0;
-        fTrans.setKeyFrame(0, fCurrTime, values);
-        values[0] = values[1] = 1;
-        fTrans.setKeyFrame(1, fCurrTime + 2000, values);
-    }
-
-protected:
-    SkString name() override { return SkString("FilterQuality"); }
-
-    bool onChar(SkUnichar uni) override {
-            switch (uni) {
-                case '1': fAngle.inc(-ANGLE_DELTA); return true;
-                case '2': fAngle.inc( ANGLE_DELTA); return true;
-                case '3': fScale.inc(-SCALE_DELTA); return true;
-                case '4': fScale.inc( SCALE_DELTA); return true;
-                case '5': fShowFatBits = !fShowFatBits; return true;
-                default: break;
-            }
-            return false;
-    }
-
-    void drawTheImage(SkCanvas* canvas, const SkISize& size, SkFilterQuality filter,
-                      SkScalar dx, SkScalar dy) {
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setFilterQuality(filter);
-
-        SkAutoCanvasRestore acr(canvas, true);
-
-        canvas->translate(dx, dy);
-
-        canvas->translate(SkScalarHalf(size.width()), SkScalarHalf(size.height()));
-        canvas->scale(fScale, fScale);
-        canvas->rotate(fAngle);
-        canvas->drawImage(fImage.get(), -SkScalarHalf(fImage->width()), -SkScalarHalf(fImage->height()),
-                          &paint);
-
-        if (false) {
-            acr.restore();
-            draw_box_frame(canvas, size.width(), size.height());
-        }
-    }
-
-    void drawHere(SkCanvas* canvas, SkFilterQuality filter, SkScalar dx, SkScalar dy) {
-        SkCanvas* origCanvas = canvas;
-        SkAutoCanvasRestore acr(canvas, true);
-
-        SkISize size = SkISize::Make(fImage->width(), fImage->height());
-
-        sk_sp<SkSurface> surface;
-        if (fShowFatBits) {
-            // scale up so we don't clip rotations
-            SkImageInfo info = SkImageInfo::MakeN32(fImage->width() * 2, fImage->height() * 2,
-                                                    kOpaque_SkAlphaType);
-            surface = make_surface(canvas, info);
-            canvas = surface->getCanvas();
-            canvas->drawColor(SK_ColorWHITE);
-            size.set(info.width(), info.height());
-        } else {
-            canvas->translate(SkScalarHalf(fCell.width() - fImage->width()),
-                              SkScalarHalf(fCell.height() - fImage->height()));
-        }
-        this->drawTheImage(canvas, size, filter, dx, dy);
-
-        if (surface) {
-            sk_sp<SkImage> orig(surface->makeImageSnapshot());
-            sk_sp<SkImage> zoomed(zoom_up(surface.get(), orig.get()));
-            origCanvas->drawImage(zoomed.get(),
-                                  SkScalarHalf(fCell.width() - zoomed->width()),
-                                  SkScalarHalf(fCell.height() - zoomed->height()));
-        }
-    }
-
-    void drawBorders(SkCanvas* canvas) {
-        SkPaint p;
-        p.setStyle(SkPaint::kStroke_Style);
-        p.setColor(SK_ColorBLUE);
-
-        SkRect r = SkRect::MakeWH(fCell.width() * 2, fCell.height() * 2);
-        r.inset(SK_ScalarHalf, SK_ScalarHalf);
-        canvas->drawRect(r, p);
-        canvas->drawLine(r.left(), r.centerY(), r.right(), r.centerY(), p);
-        canvas->drawLine(r.centerX(), r.top(), r.centerX(), r.bottom(), p);
-    }
-
-    void onOnceBeforeDraw() override {
-        fImage = make_image();
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        fCell.set(this->height() / 2, this->height() / 2);
-
-        SkScalar trans[2];
-        fTrans.timeToValues(fCurrTime, trans);
-
-        for (int y = 0; y < 2; ++y) {
-            for (int x = 0; x < 2; ++x) {
-                int index = y * 2 + x;
-                SkAutoCanvasRestore acr(canvas, true);
-                canvas->translate(fCell.width() * x, fCell.height() * y);
-                SkRect r = SkRect::MakeWH(fCell.width(), fCell.height());
-                r.inset(4, 4);
-                canvas->clipRect(r);
-                this->drawHere(canvas, SkFilterQuality(index), trans[0], trans[1]);
-            }
-        }
-
-        this->drawBorders(canvas);
-
-        const SkScalar textX = fCell.width() * 2 + 30;
-
-        SkFont font(nullptr, 36);
-        SkPaint paint;
-        canvas->drawString(SkStringPrintf("%.8g", (float)fScale), textX, 100, font, paint);
-        canvas->drawString(SkStringPrintf("%.8g", (float)fAngle), textX, 150, font, paint);
-        canvas->drawString(SkStringPrintf("%.8g", trans[0]     ), textX, 200, font, paint);
-        canvas->drawString(SkStringPrintf("%.8g", trans[1]     ), textX, 250, font, paint);
-    }
-
-    bool onAnimate(double nanos) override {
-        fCurrTime = TimeUtils::NanosToMSec(nanos);
-        return true;
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new FilterQualityView(); )
diff --git a/third_party/skia/samplecode/SampleFitCubicToCircle.cpp b/third_party/skia/samplecode/SampleFitCubicToCircle.cpp
new file mode 100644
index 0000000..84042e5
--- /dev/null
+++ b/third_party/skia/samplecode/SampleFitCubicToCircle.cpp
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "samplecode/Sample.h"
+
+#include "include/core/SkCanvas.h"
+#include "include/core/SkFont.h"
+#include "include/core/SkPaint.h"
+#include "include/core/SkPath.h"
+#include <tuple>
+
+// Math constants are not always defined.
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264338327950288
+#endif
+
+#ifndef M_SQRT2
+#define M_SQRT2 1.41421356237309504880168872420969808
+#endif
+
+constexpr static int kCenterX = 300;
+constexpr static int kCenterY = 325;
+constexpr static int kRadius = 250;
+
+// This sample fits a cubic to the arc between two interactive points on a circle. It also finds the
+// T-coordinate of max error, and outputs it and its value in pixels. (It turns out that max error
+// always occurs at T=0.21132486540519.)
+//
+// Press 'E' to iteratively cut the arc in half and report the improvement in max error after each
+// halving. (It turns out that max error improves by exactly 64x on every halving.)
+class SampleFitCubicToCircle : public Sample {
+    SkString name() override { return SkString("FitCubicToCircle"); }
+    void onOnceBeforeDraw() override { this->fitCubic(); }
+    void fitCubic();
+    void onDrawContent(SkCanvas*) override;
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override;
+    bool onClick(Sample::Click*) override;
+    bool onChar(SkUnichar) override;
+
+    // Coordinates of two points on the unit circle. These are the two endpoints of the arc we fit.
+    double fEndptsX[2] = {0, 1};
+    double fEndptsY[2] = {-1, 0};
+
+    // Fitted cubic and info, set by fitCubic().
+    double fControlLength;  // Length of (p1 - p0) and/or (p3 - p2) in unit circle space.
+    double fMaxErrorT;  // T value where the cubic diverges most from the true arc.
+    std::array<double, 4> fCubicX;  // Screen space cubic control points.
+    std::array<double, 4> fCubicY;
+    double fMaxError;  // Max error (in pixels) between the cubic and the screen-space arc.
+    double fTheta;  // Angle of the arc. This is only used for informational purposes.
+    SkTArray<SkString> fInfoStrings;
+
+    class Click;
+};
+
+// Fits a cubic to an arc on the unit circle with endpoints (x0, y0) and (x1, y1). Using the
+// following 3 constraints, we arrive at the formula used in the method:
+//
+//   1) The endpoints and tangent directions at the endpoints must match the arc.
+//   2) The cubic must be symmetric (i.e., length(p1 - p0) == length(p3 - p2)).
+//   3) The height of the cubic must match the height of the arc.
+//
+// Returns the "control length", or length of (p1 - p0) and/or (p3 - p2).
+static float fit_cubic_to_unit_circle(double x0, double y0, double x1, double y1,
+                                      std::array<double, 4>* X, std::array<double, 4>* Y) {
+    constexpr static double kM = -4.0/3;
+    constexpr static double kA = 4*M_SQRT2/3;
+    double d = x0*x1 + y0*y1;
+    double c = (std::sqrt(1 + d) * kM + kA) / std::sqrt(1 - d);
+    *X = {x0, x0 - y0*c, x1 + y1*c, x1};
+    *Y = {y0, y0 + x0*c, y1 - x1*c, y1};
+    return c;
+}
+
+static double lerp(double x, double y, double T) {
+    return x + T*(y - x);
+}
+
+// Evaluates the cubic and 1st and 2nd derivatives at T.
+static std::tuple<double, double, double> eval_cubic(double x[], double T) {
+    // Use De Casteljau's algorithm for better accuracy and stability.
+    double ab = lerp(x[0], x[1], T);
+    double bc = lerp(x[1], x[2], T);
+    double cd = lerp(x[2], x[3], T);
+    double abc = lerp(ab, bc, T);
+    double bcd = lerp(bc, cd, T);
+    double abcd = lerp(abc, bcd, T);
+    return {abcd, 3 * (bcd - abc) /*1st derivative.*/, 6 * (cd - 2*bc + ab) /*2nd derivative.*/};
+}
+
+// Uses newton-raphson convergence to find the point where the provided cubic diverges most from the
+// unit circle. i.e., the point where the derivative of error == 0. For error we use:
+//
+//     error = x^2 + y^2 - 1
+//     error' = 2xx' + 2yy'
+//     error'' = 2xx'' + 2yy'' + 2x'^2 + 2y'^2
+//
+double find_max_error_T(double cubicX[4], double cubicY[4]) {
+    constexpr static double kInitialT = .25;
+    double T = kInitialT;
+    for (int i = 0; i < 64; ++i) {
+        auto [x, dx, ddx] = eval_cubic(cubicX, T);
+        auto [y, dy, ddy] = eval_cubic(cubicY, T);
+        double dError = 2*(x*dx + y*dy);
+        double ddError = 2*(x*ddx + y*ddy + dx*dx + dy*dy);
+        T -= dError / ddError;
+    }
+    return T;
+}
+
+void SampleFitCubicToCircle::fitCubic() {
+    fInfoStrings.reset();
+
+    std::array<double, 4> X, Y;
+    // "Control length" is the length of (p1 - p0) and/or (p3 - p2) in unit circle space.
+    fControlLength = fit_cubic_to_unit_circle(fEndptsX[0], fEndptsY[0], fEndptsX[1], fEndptsY[1],
+                                              &X, &Y);
+    fInfoStrings.push_back().printf("control length=%0.14f", fControlLength);
+
+    fMaxErrorT = find_max_error_T(X.data(), Y.data());
+    fInfoStrings.push_back().printf("max error T=%0.14f", fMaxErrorT);
+
+    for (int i = 0; i < 4; ++i) {
+        fCubicX[i] = X[i] * kRadius + kCenterX;
+        fCubicY[i] = Y[i] * kRadius + kCenterY;
+    }
+    double errX = std::get<0>(eval_cubic(fCubicX.data(), fMaxErrorT)) - kCenterX;
+    double errY = std::get<0>(eval_cubic(fCubicY.data(), fMaxErrorT)) - kCenterY;
+    fMaxError = std::sqrt(errX*errX + errY*errY) - kRadius;
+    fInfoStrings.push_back().printf("max error=%.5gpx", fMaxError);
+
+    fTheta = std::atan2(fEndptsY[1], fEndptsX[1]) - std::atan2(fEndptsY[0], fEndptsX[0]);
+    fTheta = std::abs(fTheta * 180/M_PI);
+    if (fTheta > 180) {
+        fTheta = 360 - fTheta;
+    }
+    fInfoStrings.push_back().printf("(theta=%.2f)", fTheta);
+
+    SkDebugf("\n");
+    for (const SkString& infoString : fInfoStrings) {
+        SkDebugf("%s\n", infoString.c_str());
+    }
+}
+
+void SampleFitCubicToCircle::onDrawContent(SkCanvas* canvas) {
+    canvas->clear(SK_ColorBLACK);
+
+    SkPaint circlePaint;
+    circlePaint.setColor(0x80ffffff);
+    circlePaint.setStyle(SkPaint::kStroke_Style);
+    circlePaint.setStrokeWidth(0);
+    circlePaint.setAntiAlias(true);
+    canvas->drawArc(SkRect::MakeXYWH(kCenterX - kRadius, kCenterY - kRadius, kRadius * 2,
+                                     kRadius * 2), 0, 360, false, circlePaint);
+
+    SkPaint cubicPaint;
+    cubicPaint.setColor(SK_ColorGREEN);
+    cubicPaint.setStyle(SkPaint::kStroke_Style);
+    cubicPaint.setStrokeWidth(10);
+    cubicPaint.setAntiAlias(true);
+    SkPath cubicPath;
+    cubicPath.moveTo(fCubicX[0], fCubicY[0]);
+    cubicPath.cubicTo(fCubicX[1], fCubicY[1], fCubicX[2], fCubicY[2], fCubicX[3], fCubicY[3]);
+    canvas->drawPath(cubicPath, cubicPaint);
+
+    SkPaint endpointsPaint;
+    endpointsPaint.setColor(SK_ColorBLUE);
+    endpointsPaint.setStrokeWidth(8);
+    endpointsPaint.setAntiAlias(true);
+    SkPoint points[2] = {{(float)fCubicX[0], (float)fCubicY[0]},
+                         {(float)fCubicX[3], (float)fCubicY[3]}};
+    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, points, endpointsPaint);
+
+    SkPaint textPaint;
+    textPaint.setColor(SK_ColorWHITE);
+    constexpr static float kInfoTextSize = 16;
+    SkFont font(nullptr, kInfoTextSize);
+    int infoY = 10 + kInfoTextSize;
+    for (const SkString& infoString : fInfoStrings) {
+        canvas->drawString(infoString.c_str(), 10, infoY, font, textPaint);
+        infoY += kInfoTextSize * 3/2;
+    }
+}
+
+class SampleFitCubicToCircle::Click : public Sample::Click {
+public:
+    Click(int ptIdx) : fPtIdx(ptIdx) {}
+
+    void doClick(SampleFitCubicToCircle* that) {
+        double dx = fCurr.fX - kCenterX;
+        double dy = fCurr.fY - kCenterY;
+        double l = std::sqrt(dx*dx + dy*dy);
+        that->fEndptsX[fPtIdx] = dx/l;
+        that->fEndptsY[fPtIdx] = dy/l;
+        if (that->fEndptsX[0] * that->fEndptsY[1] - that->fEndptsY[0] * that->fEndptsX[1] < 0) {
+            std::swap(that->fEndptsX[0], that->fEndptsX[1]);
+            std::swap(that->fEndptsY[0], that->fEndptsY[1]);
+            fPtIdx = 1 - fPtIdx;
+        }
+        that->fitCubic();
+    }
+
+private:
+    int fPtIdx;
+};
+
+Sample::Click* SampleFitCubicToCircle::onFindClickHandler(SkScalar x, SkScalar y,
+                                                          skui::ModifierKey) {
+    double dx0 = x - fCubicX[0];
+    double dy0 = y - fCubicY[0];
+    double dx3 = x - fCubicX[3];
+    double dy3 = y - fCubicY[3];
+    if (dx0*dx0 + dy0*dy0 < dx3*dx3 + dy3*dy3) {
+        return new Click(0);
+    } else {
+        return new Click(1);
+    }
+}
+
+bool SampleFitCubicToCircle::onClick(Sample::Click* click) {
+    Click* myClick = (Click*)click;
+    myClick->doClick(this);
+    return true;
+}
+
+bool SampleFitCubicToCircle::onChar(SkUnichar unichar) {
+    if (unichar == 'E') {
+        constexpr static double kMaxErrorT = 0.21132486540519;  // Always the same.
+        // Split the arc in half until error =~0, and report the improvement after each halving.
+        double lastError = -1;
+        for (double theta = fTheta; lastError != 0; theta /= 2) {
+            double rads = theta * M_PI/180;
+            std::array<double, 4> X, Y;
+            fit_cubic_to_unit_circle(1, 0, std::cos(rads), std::sin(rads), &X, &Y);
+            auto [x, dx, ddx] = eval_cubic(X.data(), kMaxErrorT);
+            auto [y, dy, ddy] = eval_cubic(Y.data(), kMaxErrorT);
+            double error = std::sqrt(x*x + y*y) * kRadius - kRadius;
+            if ((float)error <= 0) {
+                error = 0;
+            }
+            SkDebugf("%6.2f degrees:   error= %10.5gpx", theta, error);
+            if (lastError > 0) {
+                SkDebugf(" (%17.14fx improvement)", lastError / error);
+            }
+            SkDebugf("\n");
+            lastError = error;
+        }
+        return true;
+    }
+    return false;
+}
+
+DEF_SAMPLE(return new SampleFitCubicToCircle;)
diff --git a/third_party/skia/samplecode/SampleFlutterAnimate.cpp b/third_party/skia/samplecode/SampleFlutterAnimate.cpp
index e3e53e0..48198bf 100644
--- a/third_party/skia/samplecode/SampleFlutterAnimate.cpp
+++ b/third_party/skia/samplecode/SampleFlutterAnimate.cpp
@@ -16,10 +16,6 @@
 #include "samplecode/Sample.h"
 #include "tools/timer/Timer.h"
 
-#if SK_SUPPORT_GPU
-#include "include/gpu/GrContext.h"
-#endif
-
 // Create an animation of a bunch of letters that rotate in place. This is intended to stress
 // the glyph atlas and test that we don't see corruption or bad slowdowns.
 class FlutterAnimateView : public Sample {
@@ -37,7 +33,6 @@
     void onDrawContent(SkCanvas* canvas) override {
         SkFont font(fTypeface, 50);
         SkPaint paint;
-        paint.setFilterQuality(kMedium_SkFilterQuality);
 
         // rough center of each glyph
         static constexpr auto kMidX = 35;
@@ -79,7 +74,7 @@
         }
     }
 
-    static constexpr double kDuration = 5.0;
+    inline static constexpr double kDuration = 5.0;
     double fCurrTime;
     double fResetTime;
     SkRandom fRand;
@@ -91,10 +86,10 @@
         SkScalar fEndRotation;
     };
     sk_sp<SkTypeface> fTypeface;
-    static constexpr int kNumChars = 40;
+    inline static constexpr int kNumChars = 40;
     AnimatedChar fChars[kNumChars];
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleFontCache.cpp b/third_party/skia/samplecode/SampleFontCache.cpp
deleted file mode 100644
index 9f39e9c..0000000
--- a/third_party/skia/samplecode/SampleFontCache.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "include/core/SkCanvas.h"
-#include "include/core/SkGraphics.h"
-#include "include/utils/SkRandom.h"
-#include "samplecode/Sample.h"
-
-#include <pthread.h>
-
-static void call_measure() {
-    SkPaint paint;
-    uint16_t text[32];
-    SkRandom rand;
-
-    paint.setAntiAlias(true);
-    paint.setTextEncoding(SkTextEncoding::kUTF16);
-    for (int j = 0; j < SK_ARRAY_COUNT(text); j++)
-        text[j] = (uint16_t)((rand.nextU() & 0xFF) + 32);
-
-    for (int i = 9; i < 36; i++) {
-        SkFontMetrics m;
-
-        paint.setTextSize(SkIntToScalar(i));
-        paint.getFontMetrics(&m);
-        paint.measureText(text, sizeof(text));
-    }
-}
-
-static void call_draw(SkCanvas* canvas) {
-    SkPaint paint;
-    uint16_t text[32];
-    SkRandom rand;
-
-    paint.setAntiAlias(true);
-    paint.setTextEncoding(SkTextEncoding::kUTF16);
-    for (int j = 0; j < SK_ARRAY_COUNT(text); j++)
-        text[j] = (uint16_t)((rand.nextU() & 0xFF) + 32);
-
-    SkScalar x = SkIntToScalar(10);
-    SkScalar y = SkIntToScalar(20);
-
-    canvas->drawColor(SK_ColorWHITE);
-    for (int i = 9; i < 36; i++)
-    {
-        SkFontMetrics m;
-
-        paint.setTextSize(SkIntToScalar(i));
-        paint.getFontMetrics(&m);
-        canvas->drawText(text, sizeof(text), x, y, paint);
-        y += m.fDescent - m.fAscent;
-    }
-}
-
-static bool gDone;
-
-static void* measure_proc(void* context) {
-    while (!gDone) {
-        call_measure();
-    }
-    return nullptr;
-}
-
-static void* draw_proc(void* context) {
-    SkBitmap* bm = (SkBitmap*)context;
-    SkCanvas    canvas(*bm);
-
-    while (!gDone) {
-        call_draw(&canvas);
-    }
-    return nullptr;
-}
-
-class FontCacheView : public Sample {
-public:
-    enum { N = 4 };
-
-    pthread_t   fMThreads[N];
-    pthread_t   fDThreads[N];
-    SkBitmap    fBitmaps[N];
-
-    FontCacheView() {
-        gDone = false;
-        for (int i = 0; i < N; i++) {
-            int status;
-
-            status = pthread_create(&fMThreads[i], nullptr,  measure_proc, nullptr);
-            SkASSERT(0 == status);
-
-            fBitmaps[i].allocPixels(SkImageInfo::Make(320, 240,
-                                                      kRGB_565_SkColorType,
-                                                      kOpaque_SkAlphaType));
-            status = pthread_create(&fDThreads[i], nullptr,  draw_proc, &fBitmaps[i]);
-            SkASSERT(0 == status);
-        }
-        this->setBGColor(0xFFDDDDDD);
-    }
-
-    virtual ~FontCacheView() {
-        gDone = true;
-        for (int i = 0; i < N; i++) {
-            void* ret;
-            int status = pthread_join(fMThreads[i], &ret);
-            SkASSERT(0 == status);
-            status = pthread_join(fDThreads[i], &ret);
-            SkASSERT(0 == status);
-        }
-    }
-
-protected:
-    SkString name() override { return SkString("FontCache"); }
-
-    virtual void onDrawContent(SkCanvas* canvas) {
-        SkScalar x = 0;
-        SkScalar y = 0;
-        for (int i = 0; i < N; i++) {
-            canvas->drawBitmap(fBitmaps[i], x, y);
-            x += SkIntToScalar(fBitmaps[i].width());
-        }
-        this->inval(nullptr);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-static Sample* MyFactory() { return new FontCacheView; }
-static SampleRegister reg(MyFactory);
diff --git a/third_party/skia/samplecode/SampleGlyphTransform.cpp b/third_party/skia/samplecode/SampleGlyphTransform.cpp
index 2260a1a..cd7191b 100644
--- a/third_party/skia/samplecode/SampleGlyphTransform.cpp
+++ b/third_party/skia/samplecode/SampleGlyphTransform.cpp
@@ -1,4 +1,4 @@
-﻿/*
+/*
  * Copyright 2018 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
@@ -75,7 +75,7 @@
     SkScalar fScale;
     SkScalar fRotate;
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleGradients.cpp b/third_party/skia/samplecode/SampleGradients.cpp
index 9eb4e71..a101ec3 100644
--- a/third_party/skia/samplecode/SampleGradients.cpp
+++ b/third_party/skia/samplecode/SampleGradients.cpp
@@ -149,13 +149,13 @@
         canvas->restore();
 
         canvas->translate(0, SkIntToScalar(370));
-        if (false) { // avoid bit rot, suppress warning
+        if ((false)) { // avoid bit rot, suppress warning
             test_alphagradients(canvas);
         }
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleHT.cpp b/third_party/skia/samplecode/SampleHT.cpp
deleted file mode 100644
index bec4a7d..0000000
--- a/third_party/skia/samplecode/SampleHT.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkDrawable.h"
-#include "include/core/SkPictureRecorder.h"
-#include "include/utils/SkInterpolator.h"
-#include "include/utils/SkRandom.h"
-#include "samplecode/Sample.h"
-#include "src/core/SkPointPriv.h"
-#include "tools/timer/TimeUtils.h"
-
-const SkRect gUnitSquare = { -1, -1, 1, 1 };
-
-static void color_to_floats(SkColor c, SkScalar f[4]) {
-    f[0] = SkIntToScalar(SkColorGetA(c));
-    f[1] = SkIntToScalar(SkColorGetR(c));
-    f[2] = SkIntToScalar(SkColorGetG(c));
-    f[3] = SkIntToScalar(SkColorGetB(c));
-}
-
-static SkColor floats_to_color(const SkScalar f[4]) {
-    return SkColorSetARGB(SkScalarRoundToInt(f[0]),
-                          SkScalarRoundToInt(f[1]),
-                          SkScalarRoundToInt(f[2]),
-                          SkScalarRoundToInt(f[3]));
-}
-
-static bool oval_contains(const SkRect& r, SkScalar x, SkScalar y) {
-    SkMatrix m;
-    m.setRectToRect(r, gUnitSquare, SkMatrix::kFill_ScaleToFit);
-    SkPoint pt;
-    m.mapXY(x, y, &pt);
-    return SkPointPriv::LengthSqd(pt) <= 1;
-}
-
-static SkColor rand_opaque_color(uint32_t seed) {
-    SkRandom rand(seed);
-    return rand.nextU() | (0xFF << 24);
-}
-
-class HTDrawable : public SkDrawable {
-    SkRect          fR;
-    SkColor         fColor;
-    SkInterpolator* fInterp;
-    SkMSec          fTime;
-
-public:
-    HTDrawable(SkRandom& rand) {
-        fR = SkRect::MakeXYWH(rand.nextRangeF(0, 640), rand.nextRangeF(0, 480),
-                              rand.nextRangeF(20, 200), rand.nextRangeF(20, 200));
-        fColor = rand_opaque_color(rand.nextU());
-        fInterp = nullptr;
-        fTime = 0;
-    }
-
-    void spawnAnimation(SkMSec now) {
-        this->setTime(now);
-
-        delete fInterp;
-        fInterp = new SkInterpolator(5, 3);
-        SkScalar values[5];
-        color_to_floats(fColor, values); values[4] = 0;
-        fInterp->setKeyFrame(0, now, values);
-        values[0] = 0; values[4] = 180;
-        fInterp->setKeyFrame(1, now + 1000, values);
-        color_to_floats(rand_opaque_color(fColor), values); values[4] = 360;
-        fInterp->setKeyFrame(2, now + 2000, values);
-
-        fInterp->setMirror(true);
-        fInterp->setRepeatCount(3);
-
-        this->notifyDrawingChanged();
-    }
-
-    bool hitTest(SkScalar x, SkScalar y) {
-        return oval_contains(fR, x, y);
-    }
-
-    void setTime(SkMSec time) { fTime = time; }
-
-    void onDraw(SkCanvas* canvas) override {
-        SkAutoCanvasRestore acr(canvas, false);
-
-        SkPaint paint;
-        paint.setAntiAlias(true);
-
-        if (fInterp) {
-            SkScalar values[5];
-            SkInterpolator::Result res = fInterp->timeToValues(fTime, values);
-            fColor = floats_to_color(values);
-
-            canvas->save();
-            canvas->rotate(values[4], fR.centerX(), fR.centerY());
-
-            switch (res) {
-                case SkInterpolator::kFreezeEnd_Result:
-                    delete fInterp;
-                    fInterp = nullptr;
-                    break;
-                default:
-                    break;
-            }
-        }
-        paint.setColor(fColor);
-        canvas->drawRect(fR, paint);
-    }
-
-    SkRect onGetBounds() override { return fR; }
-};
-
-class HTView : public Sample {
-public:
-    enum {
-        N = 50,
-        W = 640,
-        H = 480,
-    };
-
-    struct Rec {
-        HTDrawable* fDrawable;
-    };
-    Rec fArray[N];
-    sk_sp<SkDrawable> fRoot;
-    SkMSec fTime;
-
-    HTView() {
-        SkRandom rand;
-
-        SkPictureRecorder recorder;
-        SkCanvas* canvas = recorder.beginRecording(SkRect::MakeWH(W, H));
-        for (int i = 0; i < N; ++i) {
-            fArray[i].fDrawable = new HTDrawable(rand);
-            canvas->drawDrawable(fArray[i].fDrawable);
-            fArray[i].fDrawable->unref();
-        }
-        fRoot = recorder.finishRecordingAsDrawable();
-    }
-
-protected:
-    SkString name() override { return SkString("HT"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawDrawable(fRoot.get());
-    }
-
-    bool onAnimate(double nanos) override {
-        fTime = TimeUtils::NanosToMSec(nanos);
-        for (int i = 0; i < N; ++i) {
-            fArray[i].fDrawable->setTime(fTime);
-        }
-        return true;
-    }
-
-    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
-        // search backwards to find the top-most
-        for (int i = N - 1; i >= 0; --i) {
-            if (fArray[i].fDrawable->hitTest(x, y)) {
-                fArray[i].fDrawable->spawnAnimation(fTime);
-                break;
-            }
-        }
-        return nullptr;
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new HTView(); )
diff --git a/third_party/skia/samplecode/SampleHairCurves.cpp b/third_party/skia/samplecode/SampleHairCurves.cpp
index 73a6aee..cdb8ed8 100644
--- a/third_party/skia/samplecode/SampleHairCurves.cpp
+++ b/third_party/skia/samplecode/SampleHairCurves.cpp
@@ -114,7 +114,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleHairModes.cpp b/third_party/skia/samplecode/SampleHairModes.cpp
index 5df28f5..6e05fbc 100644
--- a/third_party/skia/samplecode/SampleHairModes.cpp
+++ b/third_party/skia/samplecode/SampleHairModes.cpp
@@ -61,10 +61,8 @@
     *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
     *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC, 0xCC, 0xCC);
 
-    SkMatrix m;
-    m.setScale(SkIntToScalar(6), SkIntToScalar(6));
-
-    return bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &m);
+    return bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, SkSamplingOptions(),
+                         SkMatrix::Scale(6, 6));
 }
 
 class HairModesView : public Sample {
@@ -108,7 +106,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleHairline.cpp b/third_party/skia/samplecode/SampleHairline.cpp
deleted file mode 100644
index a43ac44..0000000
--- a/third_party/skia/samplecode/SampleHairline.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkBitmap.h"
-#include "include/core/SkCanvas.h"
-#include "include/core/SkColorFilter.h"
-#include "include/core/SkColorPriv.h"
-#include "include/core/SkGraphics.h"
-#include "include/core/SkPath.h"
-#include "include/core/SkRegion.h"
-#include "include/core/SkShader.h"
-#include "include/core/SkStream.h"
-#include "include/core/SkTime.h"
-#include "include/core/SkTypeface.h"
-#include "include/effects/SkCornerPathEffect.h"
-#include "include/effects/SkGradientShader.h"
-#include "include/private/SkTo.h"
-#include "include/utils/SkRandom.h"
-#include "samplecode/Sample.h"
-#include "src/utils/SkUTF.h"
-
-static SkRandom gRand;
-
-static void generate_pts(SkPoint pts[], int count, int w, int h) {
-    for (int i = 0; i < count; i++) {
-        pts[i].set(gRand.nextUScalar1() * 3 * w - SkIntToScalar(w),
-                   gRand.nextUScalar1() * 3 * h - SkIntToScalar(h));
-    }
-}
-
-static bool check_zeros(const SkPMColor pixels[], int count, int skip) {
-    for (int i = 0; i < count; i++) {
-        if (*pixels) {
-            return false;
-        }
-        pixels += skip;
-    }
-    return true;
-}
-
-static bool check_bitmap_margin(const SkBitmap& bm, int margin) {
-    size_t rb = bm.rowBytes();
-    for (int i = 0; i < margin; i++) {
-        if (!check_zeros(bm.getAddr32(0, i), bm.width(), 1)) {
-            return false;
-        }
-        int bottom = bm.height() - i - 1;
-        if (!check_zeros(bm.getAddr32(0, bottom), bm.width(), 1)) {
-            return false;
-        }
-        // left column
-        if (!check_zeros(bm.getAddr32(i, 0), bm.height(), SkToInt(rb >> 2))) {
-            return false;
-        }
-        int right = bm.width() - margin + i;
-        if (!check_zeros(bm.getAddr32(right, 0), bm.height(),
-                         SkToInt(rb >> 2))) {
-            return false;
-        }
-    }
-    return true;
-}
-
-#define WIDTH   620
-#define HEIGHT  460
-#define MARGIN  10
-
-static void line_proc(SkCanvas* canvas, const SkPaint& paint,
-                      const SkBitmap& bm) {
-    const int N = 2;
-    SkPoint pts[N];
-    for (int i = 0; i < 400; i++) {
-        generate_pts(pts, N, WIDTH, HEIGHT);
-
-        canvas->drawLine(pts[0], pts[1], paint);
-        if (!check_bitmap_margin(bm, MARGIN)) {
-            SkDebugf("---- hairline failure (%g %g) (%g %g)\n",
-                     pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY);
-            break;
-        }
-    }
-}
-
-static void poly_proc(SkCanvas* canvas, const SkPaint& paint,
-                      const SkBitmap& bm) {
-    const int N = 8;
-    SkPoint pts[N];
-    for (int i = 0; i < 50; i++) {
-        generate_pts(pts, N, WIDTH, HEIGHT);
-
-        SkPath path;
-        path.moveTo(pts[0]);
-        for (int j = 1; j < N; j++) {
-            path.lineTo(pts[j]);
-        }
-        canvas->drawPath(path, paint);
-    }
-}
-
-static SkPoint ave(const SkPoint& a, const SkPoint& b) {
-    SkPoint c = a + b;
-    c.fX = SkScalarHalf(c.fX);
-    c.fY = SkScalarHalf(c.fY);
-    return c;
-}
-
-static void quad_proc(SkCanvas* canvas, const SkPaint& paint,
-                      const SkBitmap& bm) {
-    const int N = 30;
-    SkPoint pts[N];
-    for (int i = 0; i < 10; i++) {
-        generate_pts(pts, N, WIDTH, HEIGHT);
-
-        SkPath path;
-        path.moveTo(pts[0]);
-        for (int j = 1; j < N - 2; j++) {
-            path.quadTo(pts[j], ave(pts[j], pts[j+1]));
-        }
-        path.quadTo(pts[N - 2], pts[N - 1]);
-
-        canvas->drawPath(path, paint);
-    }
-}
-
-static void add_cubic(SkPath* path, const SkPoint& mid, const SkPoint& end) {
-    SkPoint start;
-    path->getLastPt(&start);
-    path->cubicTo(ave(start, mid), ave(mid, end), end);
-}
-
-static void cube_proc(SkCanvas* canvas, const SkPaint& paint,
-                      const SkBitmap& bm) {
-    const int N = 30;
-    SkPoint pts[N];
-    for (int i = 0; i < 10; i++) {
-        generate_pts(pts, N, WIDTH, HEIGHT);
-
-        SkPath path;
-        path.moveTo(pts[0]);
-        for (int j = 1; j < N - 2; j++) {
-            add_cubic(&path, pts[j], ave(pts[j], pts[j+1]));
-        }
-        add_cubic(&path, pts[N - 2], pts[N - 1]);
-
-        canvas->drawPath(path, paint);
-    }
-}
-
-typedef void (*HairProc)(SkCanvas*, const SkPaint&, const SkBitmap&);
-
-static const struct {
-    const char* fName;
-    HairProc    fProc;
-} gProcs[] = {
-    { "line",   line_proc },
-    { "poly",   poly_proc },
-    { "quad",   quad_proc },
-    { "cube",   cube_proc },
-};
-
-static int cycle_hairproc_index(int index) {
-    return (index + 1) % SK_ARRAY_COUNT(gProcs);
-}
-
-class HairlineView : public Sample {
-    SkMSec fNow;
-    int fProcIndex;
-    bool fDoAA;
-public:
-    HairlineView() {
-        fProcIndex = 0;
-        fDoAA = true;
-        fNow = 0;
-    }
-
-protected:
-    SkString name() override { return SkStringPrintf("Hair-%s", gProcs[fProcIndex].fName); }
-
-    void show_bitmaps(SkCanvas* canvas, const SkBitmap& b0, const SkBitmap& b1,
-                      const SkIRect& inset) {
-        canvas->drawBitmap(b0, 0, 0, nullptr);
-        canvas->drawBitmap(b1, SkIntToScalar(b0.width()), 0, nullptr);
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        gRand.setSeed(fNow);
-
-        SkBitmap bm, bm2;
-        bm.allocN32Pixels(WIDTH + MARGIN*2, HEIGHT + MARGIN*2);
-        // this will erase our margin, which we want to always stay 0
-        bm.eraseColor(SK_ColorTRANSPARENT);
-
-        bm2.installPixels(SkImageInfo::MakeN32Premul(WIDTH, HEIGHT),
-                          bm.getAddr32(MARGIN, MARGIN), bm.rowBytes());
-
-        SkCanvas c2(bm2);
-        SkPaint paint;
-        paint.setAntiAlias(fDoAA);
-        paint.setStyle(SkPaint::kStroke_Style);
-
-        bm2.eraseColor(SK_ColorTRANSPARENT);
-        gProcs[fProcIndex].fProc(&c2, paint, bm);
-        canvas->drawBitmap(bm2, SkIntToScalar(10), SkIntToScalar(10), nullptr);
-    }
-
-    bool onAnimate(double /*nanos*/) override {
-        if (fDoAA) {
-            fProcIndex = cycle_hairproc_index(fProcIndex);
-            // todo: signal that we want to rebuild our TITLE
-        }
-        fDoAA = !fDoAA;
-        return true;
-    }
-
-    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
-        fDoAA = !fDoAA;
-        return this->INHERITED::onFindClickHandler(x, y, modi);
-    }
-
-
-private:
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new HairlineView(); )
diff --git a/third_party/skia/samplecode/SampleIdentityScale.cpp b/third_party/skia/samplecode/SampleIdentityScale.cpp
deleted file mode 100644
index 4e7b1dd..0000000
--- a/third_party/skia/samplecode/SampleIdentityScale.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkColorPriv.h"
-#include "include/core/SkFont.h"
-#include "include/core/SkPath.h"
-#include "include/core/SkStream.h"
-#include "include/core/SkTime.h"
-#include "include/effects/SkBlurMaskFilter.h"
-#include "include/utils/SkRandom.h"
-#include "samplecode/DecodeFile.h"
-#include "samplecode/Sample.h"
-#include "src/core/SkClipOpPriv.h"
-#include "tools/Resources.h"
-
-// Intended to exercise pixel snapping observed with scaled images (and
-// with non-scaled images, but for a different reason):  Bug 1145
-
-class IdentityScaleView : public Sample {
-public:
-    IdentityScaleView(const char imageFilename[]) {
-        if (!DecodeDataToBitmap(GetResourceAsData(imageFilename), &fBM)) {
-            fBM.allocN32Pixels(1, 1);
-            *(fBM.getAddr32(0,0)) = 0xFF0000FF; // red == bad
-        }
-    }
-
-protected:
-    SkBitmap fBM;
-
-    SkString name() override { return SkString("IdentityScale"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-
-        SkFont font(nullptr, 48);
-        SkPaint paint;
-
-        paint.setAntiAlias(true);
-        paint.setFilterQuality(kHigh_SkFilterQuality);
-
-        SkTime::DateTime time;
-        SkTime::GetDateTime(&time);
-
-        bool use_scale = (time.fSecond % 2 == 1);
-        const char *text;
-
-        canvas->save();
-        if (use_scale) {
-          text = "Scaled = 1";
-        } else {
-
-          SkRect r = { 100, 100, 356, 356 };
-          SkPath clipPath;
-          clipPath.addRoundRect(r, SkIntToScalar(5), SkIntToScalar(5));
-          canvas->clipPath(clipPath, kIntersect_SkClipOp, true);
-          text = "Scaled = 0";
-        }
-        canvas->drawBitmap( fBM, 100, 100, &paint );
-        canvas->restore();
-        canvas->drawString(text, 100, 400, font, paint);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new IdentityScaleView("images/mandrill_256.png"); )
diff --git a/third_party/skia/samplecode/SampleImageFilterDAG.cpp b/third_party/skia/samplecode/SampleImageFilterDAG.cpp
index 41340b6..3c925d1 100644
--- a/third_party/skia/samplecode/SampleImageFilterDAG.cpp
+++ b/third_party/skia/samplecode/SampleImageFilterDAG.cpp
@@ -42,224 +42,89 @@
     int fDepth;
 
     // The source content rect (this is the same for all nodes, but is stored here for convenience)
-    SkRect fContent;
-    // The portion of the original CTM that is kept as the local matrix/ctm when filtering
-    SkMatrix fLocalCTM;
-    // The portion of the original CTM that the results should be drawn with (or given current
-    // canvas impl., the portion of the CTM that is baked into a new DAG)
-    SkMatrix fRemainingCTM;
+    skif::ParameterSpace<SkRect> fContent;
+    // The mapping for the filter dag (same for all nodes, but stored here for convenience)
+    skif::Mapping fMapping;
 
-    // Cached reverse bounds using device-space clip bounds (e.g. SkCanvas::clipRectBounds with
-    // null first argument). This represents the layer calculated in SkCanvas for the filtering.
-    // FIXME: SkCanvas (and this sample), this is seeded with the device-space clip bounds so that
-    // the implicit matrix node's reverse bounds are updated appropriately when it recurses to the
-    // original root node.
-    SkIRect fLayerBounds;
+    // Cached reverse bounds using device-space clip bounds (e.g. no local bounds hint passed to
+    // saveLayer). This represents the layer calculated in SkCanvas for the filtering.
+    skif::LayerSpace<SkIRect> fUnhintedLayerBounds;
 
-    // Cached reverse bounds using the local draw bounds (e.g. SkCanvas::clipRectBounds with the
-    // draw bounds provided as first argument). For intermediate nodes in a DAG, this is calculated
-    // to match what the filter would compute when being evaluated as part of the original DAG
-    // (i.e. if the implicit matrix filter node were not inserted at the beginning).
-    // fReverseLocalIsolatedBounds is the same, except it represents what would be calculated if
-    // only this node were being applied as the image filter.
-    SkIRect fReverseLocalBounds;
-    SkIRect fReverseLocalIsolatedBounds;
+    // Cached input bounds using the local draw bounds (e.g. saveLayer with a bounds rect, or
+    // an auto-layer for a draw with image filter). This represents the layer bounds up to this
+    // point of the DAG.
+    skif::LayerSpace<SkIRect> fHintedLayerBounds;
 
-    // Cached forward bounds based on local draw bounds. For intermediate nodes in a DAG, this is
-    // calculated to match what the filter computes as part of the whole DAG. fForwardIsolatedBounds
-    // is the same but represents what would be calculated if only this node were applied.
-    SkIRect fForwardBounds;
-    SkIRect fForwardIsolatedBounds;
+    // Cached output bounds based on local draw bounds. This represents the output up to this
+    // point of the DAG.
+    skif::LayerSpace<SkIRect> fOutputBounds;
 
-    // Should be called after the input nodes have been created since this will complete the
-    // entire tree.
-    void computeBounds() {
-        // In normal usage, forward bounds are filter-space bounds of the geometry content, so
-        // fContent mapped by the local matrix, since we assume the layer content is made by
-        // concat(localCTM) -> clipRect(content) -> drawRect(content).
-        // Similarly, in normal usage, reverse bounds are the filter-space bounds of the space to
-        // be filled by image filter results. Since the clip rect is set to the same as the content,
-        // it's the same bounds forward or reverse in this contrived case.
-        SkIRect inputRect;
-        fLocalCTM.mapRect(fContent).roundOut(&inputRect);
-
-        this->computeForwardBounds(inputRect);
-
-        // The layer bounds (matching what SkCanvas computes), use the content rect mapped by the
-        // entire CTM as its input rect. If this is an implicit matrix node, the computeReverseX
-        // functions will switch to using the local-mapped bounds for children in order to simulate
-        // what would happen if the last step were done as a draw. When there's no implicit matrix
-        // node, this calculated rectangle is the same as inputRect.
-        SkIRect deviceRect;
-        SkMatrix ctm = SkMatrix::Concat(fRemainingCTM, fLocalCTM);
-        ctm.mapRect(fContent).roundOut(&deviceRect);
-
-        SkASSERT(this->isImplicitMatrixNode() || inputRect == deviceRect);
-        this->computeReverseLocalIsolatedBounds(deviceRect);
-        this->computeReverseBounds(deviceRect, false);
-        // Unlike the above two calls, calculating layer bounds will keep the device bounds for
-        // intermediate nodes to show the current SkCanvas behavior vs. the ideal
-        this->computeReverseBounds(deviceRect, true);
-    }
-
-    bool isImplicitMatrixNode() const {
-        // In the future we wish to replace the implicit matrix node with direct draws to the final
-        // destination (instead of using an SkMatrixImageFilter). Visualizing the DAG correctly
-        // requires handling these nodes differently since it has part of the canvas CTM built in.
-        return fDepth == 1 && !fRemainingCTM.isIdentity();
+    FilterNode(const SkImageFilter* filter,
+               const skif::Mapping& mapping,
+               const skif::ParameterSpace<SkRect>& content,
+               int depth)
+            : fFilter(sk_ref_sp(filter))
+            , fDepth(depth)
+            , fContent(content)
+            , fMapping(mapping) {
+        this->computeInputBounds();
+        this->computeOutputBounds();
+        if (fFilter) {
+            fInputNodes.reserve_back(fFilter->countInputs());
+            for (int i = 0; i < fFilter->countInputs(); ++i) {
+                fInputNodes.emplace_back(fFilter->getInput(i), mapping, content, depth + 1);
+            }
+        }
     }
 
 private:
-    void computeForwardBounds(const SkIRect srcRect) {
+    void computeOutputBounds() {
         if (fFilter) {
-            // For forward filtering, the leaves of the DAG are evaluated first and are then
-            // propagated to the root. This means that every filter's filterBounds() function sees
-            // the original src rect. It is never dependent on the parent node (unlike reverse
-            // filtering), so calling filterBounds() on an intermediate node gives us the correct
-            // intermediate values.
-            fForwardBounds = fFilter->filterBounds(
-                    srcRect, fLocalCTM, SkImageFilter::kForward_MapDirection, nullptr);
-
-            // For isolated forward filtering, it uses the same input but should not be propagated
-            // to the inputs, so get the filter node bounds directly.
-            fForwardIsolatedBounds = as_IFB(fFilter)->filterNodeBounds(
-                    srcRect, fLocalCTM, SkImageFilter::kForward_MapDirection, nullptr);
+            // For visualization purposes, we want the output bounds in layer space, before it's
+            // been transformed to device space. To achieve that, we mock a new mapping with the
+            // identity matrix transform.
+            skif::Mapping layerOnly{fMapping.layerMatrix()};
+            skif::DeviceSpace<SkIRect> pseudoDeviceBounds =
+                    as_IFB(fFilter)->getOutputBounds(layerOnly, fContent);
+            // Since layerOnly's device matrix is I, this is effectively a cast to layer space
+            fOutputBounds = layerOnly.deviceToLayer(pseudoDeviceBounds);
         } else {
-            fForwardBounds = srcRect;
-            fForwardIsolatedBounds = srcRect;
+            fOutputBounds = fMapping.paramToLayer(fContent).roundOut();
         }
 
         // Fill in children
         for (int i = 0; i < fInputNodes.count(); ++i) {
-            fInputNodes[i].computeForwardBounds(srcRect);
+            fInputNodes[i].computeOutputBounds();
         }
     }
 
-    void computeReverseLocalIsolatedBounds(const SkIRect& srcRect) {
-        if (fFilter) {
-            fReverseLocalIsolatedBounds = as_IFB(fFilter)->filterNodeBounds(
-                    srcRect, fLocalCTM, SkImageFilter::kReverse_MapDirection, &srcRect);
-        } else {
-            fReverseLocalIsolatedBounds = srcRect;
-        }
-
-        SkIRect childSrcRect = srcRect;
-        if (this->isImplicitMatrixNode()) {
-            // Switch srcRect from the device-space bounds to what would be used when the draw is
-            // the final step of filtering, as if the implicit node weren't needed
-            fLocalCTM.mapRect(fContent).roundOut(&childSrcRect);
-        }
-
-        // Fill in children. Unlike regular reverse bounds mapping, the input nodes see the original
-        // bounds. Normally, the bounds that the child nodes see have already been mapped processed
-        // by this node.
-        for (int i = 0; i < fInputNodes.count(); ++i) {
-            fInputNodes[i].computeReverseLocalIsolatedBounds(childSrcRect);
-        }
-    }
-
-    // fReverseLocalBounds and fLayerBounds are computed the same, except they differ in what the
-    // initial bounding rectangle was. It is assumed that the 'srcRect' has already been processed
-    // by the parent node's onFilterNodeBounds() function, as in SkImageFilter::filterBounds().
-    void computeReverseBounds(const SkIRect& srcRect, bool writeToLayerBounds) {
-        SkIRect reverseBounds = srcRect;
+    void computeInputBounds() {
+        // As a proxy for what the base device had, use the content rect mapped to device space
+        // (e.g. clipRect() was called with the same coords prior to the draw).
+        skif::DeviceSpace<SkIRect> targetOutput(fMapping.totalMatrix()
+                                                        .mapRect(SkRect(fContent))
+                                                        .roundOut());
 
         if (fFilter) {
-            // Since srcRect has been through parent's onFilterNodeBounds(), calling filterBounds()
-            // directly on this node will calculate the same rectangle that this filter would report
-            // during the parent node's onFilterBounds() recursion.
-            reverseBounds = fFilter->filterBounds(
-                    srcRect, fLocalCTM, SkImageFilter::kReverse_MapDirection, &srcRect);
-
-            SkIRect nextSrcRect;
-            if (this->isImplicitMatrixNode() && !writeToLayerBounds) {
-                // When not writing to the layer bounds, and we're the implicit matrix node
-                // we reset the src rect to be what it should be if no implicit node was necessary.
-                fLocalCTM.mapRect(fContent).roundOut(&nextSrcRect);
-            } else {
-                // To calculate the appropriate intermediate reverse bounds for the children, we
-                // need this node's onFilterNodeBounds() results based on its parents' bounds (the
-                // current 'srcRect').
-                nextSrcRect = as_IFB(fFilter)->filterNodeBounds(
-                    srcRect, fLocalCTM, SkImageFilter::kReverse_MapDirection, &srcRect);
-            }
-
-            // Fill in the children. The union of these bounds should equal the value calculated
-            // for reverseBounds already.
-            SkDEBUGCODE(SkIRect netReverseBounds = SkIRect::MakeEmpty();)
-            for (int i = 0; i < fInputNodes.count(); ++i) {
-                fInputNodes[i].computeReverseBounds(nextSrcRect, writeToLayerBounds);
-                SkDEBUGCODE(netReverseBounds.join(
-                        writeToLayerBounds ? fInputNodes[i].fLayerBounds
-                                           : fInputNodes[i].fReverseLocalBounds);)
-            }
-            // Because of the resetting done when not computing layer bounds for the implicit
-            // matrix node, this assertion doesn't hold in that particular scenario.
-            SkASSERT(netReverseBounds == reverseBounds ||
-                     (this->isImplicitMatrixNode() && !writeToLayerBounds));
-        }
-
-        if (writeToLayerBounds) {
-            fLayerBounds = reverseBounds;
+            fHintedLayerBounds = as_IFB(fFilter)->getInputBounds(fMapping, targetOutput, &fContent);
+            fUnhintedLayerBounds = as_IFB(fFilter)->getInputBounds(fMapping, targetOutput, nullptr);
         } else {
-            fReverseLocalBounds = reverseBounds;
+            fHintedLayerBounds = fMapping.paramToLayer(fContent).roundOut();
+            fUnhintedLayerBounds = fMapping.deviceToLayer(targetOutput);
         }
     }
 };
 
 } // anonymous namespace
 
-static FilterNode build_dag(const SkMatrix& local, const SkMatrix& remainder, const SkRect& rect,
-                            const SkImageFilter* filter, int depth) {
-    FilterNode node;
-    node.fFilter = sk_ref_sp(filter);
-    node.fDepth = depth;
-    node.fContent = rect;
-
-    node.fLocalCTM = local;
-    node.fRemainingCTM = remainder;
-
-    if (node.fFilter) {
-        if (depth > 0) {
-            // We don't visit children when at the root because the real child filters are replaced
-            // with the internalSaveLayer decomposition emulation, which then cycles back to the
-            // original filter but with an updated matrix (and then we process the children).
-            node.fInputNodes.reserve(node.fFilter->countInputs());
-            for (int i = 0; i < node.fFilter->countInputs(); ++i) {
-                node.fInputNodes.push_back() =
-                        build_dag(local, remainder, rect, node.fFilter->getInput(i), depth + 1);
-            }
-        }
-    }
-
-    return node;
-}
-
 static FilterNode build_dag(const SkMatrix& ctm, const SkRect& rect,
                             const SkImageFilter* rootFilter) {
     // Emulate SkCanvas::internalSaveLayer's decomposition of the CTM.
-    SkMatrix local;
-    sk_sp<SkImageFilter> finalFilter = as_IFB(rootFilter)->applyCTM(ctm, &local);
-
-    // In ApplyCTMToFilter, the CTM is decomposed such that CTM = remainder * local. The matrix
-    // that is embedded in 'finalFilter' is actually local^-1*remainder*local to account for
-    // how SkMatrixImageFilter is specified, but we want the true remainder since it is what should
-    // transform the results to put in the correct place after filtering.
-    SkMatrix invLocal, remaining;
-    if (as_IFB(rootFilter)->uniqueID() != as_IFB(finalFilter)->uniqueID()) {
-        remaining = SkMatrix::Concat(ctm, invLocal);
-    } else {
-        remaining = SkMatrix::I();
-    }
-
-    // Create a root node that represents the full result
-    FilterNode rootNode = build_dag(ctm, SkMatrix::I(), rect, rootFilter, 0);
-    // Set its only child as the modified DAG that handles the CTM decomposition
-    rootNode.fInputNodes.push_back() =
-            build_dag(local, remaining, rect, finalFilter.get(), 1);
-    // Fill in bounds information that requires the entire node DAG to have been extracted first.
-    rootNode.fInputNodes[0].computeBounds();
-    return rootNode;
+    skif::ParameterSpace<SkRect> content(rect);
+    skif::ParameterSpace<SkPoint> center({rect.centerX(), rect.centerY()});
+    skif::Mapping mapping;
+    SkAssertResult(mapping.decomposeCTM(ctm, rootFilter, center));
+    return FilterNode(rootFilter, mapping, content, 0);
 }
 
 static void draw_node(SkCanvas* canvas, const FilterNode& node) {
@@ -268,10 +133,11 @@
     SkPaint filterPaint;
     filterPaint.setImageFilter(node.fFilter);
 
+    SkRect content = SkRect(node.fContent);
     SkPaint paint;
     static const SkColor kColors[2] = {SK_ColorGREEN, SK_ColorWHITE};
-    SkPoint points[2] = { {node.fContent.fLeft + 15.f, node.fContent.fTop + 15.f},
-                          {node.fContent.fRight - 15.f, node.fContent.fBottom - 15.f} };
+    SkPoint points[2] = { {content.fLeft + 15.f, content.fTop + 15.f},
+                          {content.fRight - 15.f, content.fBottom - 15.f} };
     paint.setShader(SkGradientShader::MakeLinear(points, kColors, nullptr, SK_ARRAY_COUNT(kColors),
                                                  SkTileMode::kRepeat));
 
@@ -279,77 +145,40 @@
     line.setStrokeWidth(0.f);
     line.setStyle(SkPaint::kStroke_Style);
 
-    if (node.fDepth == 0) {
-        // The root node, so draw this one the canonical way through SkCanvas to show current
-        // net behavior. Will not include bounds visualization.
-        canvas->save();
-        canvas->concat(node.fLocalCTM);
-        SkASSERT(node.fRemainingCTM.isIdentity());
+    canvas->save();
+    canvas->concat(node.fMapping.deviceMatrix());
+    canvas->save();
+    canvas->concat(node.fMapping.layerMatrix());
 
-        canvas->clipRect(node.fContent, /* aa */ true);
-        canvas->saveLayer(nullptr, &filterPaint);
-        canvas->drawRect(node.fContent, paint);
-        canvas->restore(); // Completes the image filter
-        canvas->restore(); // Undoes matrix and clip
+    canvas->saveLayer(&content, &filterPaint);
+    canvas->drawRect(content, paint);
+    canvas->restore(); // Completes the image filter
 
-        // Draw content rect (no clipping)
-        canvas->save();
-        canvas->concat(node.fLocalCTM);
-        line.setColor(SK_ColorBLACK);
-        canvas->drawRect(node.fContent, line);
-        canvas->restore();
-    } else {
-        canvas->save();
-        if (!node.isImplicitMatrixNode()) {
-            canvas->concat(node.fRemainingCTM);
-        }
-        canvas->concat(node.fLocalCTM);
+    // Draw content-rect bounds
+    line.setColor(SK_ColorBLACK);
+    canvas->drawRect(content, line);
 
-        canvas->saveLayer(nullptr, &filterPaint);
-        canvas->drawRect(node.fContent, paint);
-        canvas->restore(); // Completes the image filter
+    // Bounding boxes have all been mapped by the layer matrix from local to layer space, so undo
+    // the layer matrix, leaving just the device matrix.
+    canvas->restore();
 
-        // Draw content-rect bounds
-        line.setColor(SK_ColorBLACK);
-        if (node.isImplicitMatrixNode()) {
-            canvas->setMatrix(SkMatrix::Concat(node.fRemainingCTM, node.fLocalCTM));
-        }
-        canvas->drawRect(node.fContent, line);
-        canvas->restore(); // Undoes the matrix
+    // The hinted bounds of the layer saved for the filtering
+    line.setColor(SK_ColorRED);
+    canvas->drawRect(SkRect::Make(SkIRect(node.fHintedLayerBounds)).makeOutset(3.f, 3.f), line);
+    // The bounds of the layer if there was no local content hint
+    line.setColor(SK_ColorGREEN);
+    canvas->drawRect(SkRect::Make(SkIRect(node.fUnhintedLayerBounds)).makeOutset(2.f, 2.f), line);
 
-        // Bounding boxes have all been mapped by the local matrix already, so drawing them with
-        // the remaining CTM should align everything to the already drawn filter outputs. The
-        // exception is forward bounds of the implicit matrix node, which also have been mapped
-        // by the remainder matrix.
-        canvas->save();
-        canvas->concat(node.fRemainingCTM);
-
-        // The bounds of the layer saved for the filtering as currently implemented
-        line.setColor(SK_ColorRED);
-        canvas->drawRect(SkRect::Make(node.fLayerBounds).makeOutset(5.f, 5.f), line);
-        // The bounds of the layer that could be saved if the last step were a draw
-        line.setColor(SK_ColorMAGENTA);
-        canvas->drawRect(SkRect::Make(node.fReverseLocalBounds).makeOutset(4.f, 4.f), line);
-
-        // Dashed lines for the isolated shapes
-        static const SkScalar kDashParams[] = {6.f, 12.f};
-        line.setPathEffect(SkDashPathEffect::Make(kDashParams, 2, 0.f));
-        // The bounds of the layer if it were the only filter in the DAG
-        canvas->drawRect(SkRect::Make(node.fReverseLocalIsolatedBounds).makeOutset(3.f, 3.f), line);
-
-        if (node.isImplicitMatrixNode()) {
-            canvas->resetMatrix();
-        }
-        // The output bounds calculated as if the node were the only filter in the DAG
-        line.setColor(SK_ColorBLUE);
-        canvas->drawRect(SkRect::Make(node.fForwardIsolatedBounds).makeOutset(1.f, 1.f), line);
-
-        // The output bounds calculated for the node
-        line.setPathEffect(nullptr);
-        canvas->drawRect(SkRect::Make(node.fForwardBounds).makeOutset(2.f, 2.f), line);
-
-        canvas->restore();
-    }
+    // The output bounds in layer space
+    line.setColor(SK_ColorBLUE);
+    canvas->drawRect(SkRect::Make(SkIRect(node.fOutputBounds)).makeOutset(1.f, 1.f), line);
+    // Device-space bounding box of the output bounds (e.g. what legacy DAG manipulation via
+    // MatrixTransform would produce).
+    static const SkScalar kDashParams[] = {6.f, 12.f};
+    line.setPathEffect(SkDashPathEffect::Make(kDashParams, 2, 0.f));
+    SkRect devOutputBounds = SkRect::Make(SkIRect(node.fMapping.layerToDevice(node.fOutputBounds)));
+    canvas->restore(); // undoes device matrix
+    canvas->drawRect(devOutputBounds, line);
 }
 
 static constexpr float kLineHeight = 16.f;
@@ -385,21 +214,23 @@
     text.setAntiAlias(true);
 
     float y = kLineHeight;
-    if (node.fDepth == 0) {
-        canvas->drawString("Final Results", kLineInset, y, font, text);
-        // The actual interesting matrices are in the root node's first child
-        y = print_matrix(canvas, "Local", node.fInputNodes[0].fLocalCTM,
-                     kLineInset, y + kLineHeight, font, text);
-        y = print_matrix(canvas, "Embedded", node.fInputNodes[0].fRemainingCTM,
-                     kLineInset, y, font, text);
-    } else if (node.fFilter) {
+    if (node.fFilter) {
         canvas->drawString(node.fFilter->getTypeName(), kLineInset, y, font, text);
-        print_size(canvas, "Layer Size", node.fLayerBounds, kLineInset, y + kLineHeight,
-                   font, text);
-        y = print_size(canvas, "Ideal Size", node.fReverseLocalBounds, 10 * kLineInset,
-                       y + kLineHeight, font, text);
+        y += kLineHeight;
+        if (node.fDepth == 0) {
+            // The mapping is the same for all nodes, so only print at the root
+            y = print_matrix(canvas, "Param->Layer", node.fMapping.layerMatrix(),
+                        kLineInset, y, font, text);
+            y = print_matrix(canvas, "Layer->Device", node.fMapping.deviceMatrix(),
+                        kLineInset, y, font, text);
+        }
+
+        y = print_size(canvas, "Layer Size", SkIRect(node.fUnhintedLayerBounds),
+                       kLineInset, y, font, text);
+        y = print_size(canvas, "Layer Size (hinted)", SkIRect(node.fHintedLayerBounds),
+                       kLineInset, y, font, text);
     } else {
-        canvas->drawString("Source Input", kLineInset, kLineHeight, font, text);
+        canvas->drawString("Source Input", kLineInset, y, font, text);
         y += kLineHeight;
     }
 
@@ -448,7 +279,7 @@
         y = draw_dag(canvas, nodeSurface, node.fInputNodes[i]);
         canvas->restore();
     }
-    return SkMaxScalar(y, nodeResults->height() + textHeight + kPad);
+    return std::max(y, nodeResults->height() + textHeight + kPad);
 }
 
 static void draw_dag(SkCanvas* canvas, sk_sp<SkImageFilter> filter,
@@ -509,7 +340,7 @@
 
 private:
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 DEF_SAMPLE(return new ImageFilterDAGSample();)
diff --git a/third_party/skia/samplecode/SampleLCD.cpp b/third_party/skia/samplecode/SampleLCD.cpp
index 3c71415..0fd46a1 100644
--- a/third_party/skia/samplecode/SampleLCD.cpp
+++ b/third_party/skia/samplecode/SampleLCD.cpp
@@ -49,7 +49,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleLayerMask.cpp b/third_party/skia/samplecode/SampleLayerMask.cpp
deleted file mode 100644
index 546c6c4..0000000
--- a/third_party/skia/samplecode/SampleLayerMask.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkBitmap.h"
-#include "include/core/SkCanvas.h"
-#include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
-#include "samplecode/Sample.h"
-
-///////////////////////////////////////////////////////////////////////////////
-
-class LayerMaskView : public Sample {
-public:
-    LayerMaskView() {
-        this->setBGColor(0xFFDDDDDD);
-    }
-
-protected:
-    virtual SkString name() { return SkString("LayerMask"); }
-
-    void drawMask(SkCanvas* canvas, const SkRect& r) {
-        SkPaint paint;
-        paint.setAntiAlias(true);
-
-        if (true) {
-            SkBitmap mask;
-            int w = SkScalarRoundToInt(r.width());
-            int h = SkScalarRoundToInt(r.height());
-            mask.allocN32Pixels(w, h);
-            mask.eraseColor(SK_ColorTRANSPARENT);
-            SkCanvas c(mask);
-            SkRect bounds = r;
-            bounds.offset(-bounds.fLeft, -bounds.fTop);
-            c.drawOval(bounds, paint);
-
-            paint.setBlendMode(SkBlendMode::kDstIn);
-            canvas->drawBitmap(mask, r.fLeft, r.fTop, &paint);
-        } else {
-            SkPath p;
-            p.addOval(r);
-            p.setFillType(SkPathFillType::kInverseWinding);
-            paint.setBlendMode(SkBlendMode::kDstOut);
-            canvas->drawPath(p, paint);
-        }
-    }
-
-    virtual void onDrawContent(SkCanvas* canvas) {
-        SkRect  r;
-        r.setLTRB(20, 20, 120, 120);
-        canvas->saveLayer(&r, nullptr);
-        canvas->drawColor(SK_ColorRED);
-        drawMask(canvas, r);
-        canvas->restore();
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new LayerMaskView(); )
diff --git a/third_party/skia/samplecode/SampleLayers.cpp b/third_party/skia/samplecode/SampleLayers.cpp
index aeddc46..c228578 100644
--- a/third_party/skia/samplecode/SampleLayers.cpp
+++ b/third_party/skia/samplecode/SampleLayers.cpp
@@ -15,12 +15,9 @@
 #include "include/core/SkShader.h"
 #include "include/core/SkTime.h"
 #include "include/core/SkTypeface.h"
-#include "include/effects/SkBlurMaskFilter.h"
 #include "include/effects/SkGradientShader.h"
 #include "include/utils/SkCamera.h"
-#include "include/utils/SkInterpolator.h"
 #include "samplecode/Sample.h"
-#include "src/core/SkClipOpPriv.h"
 #include "src/utils/SkUTF.h"
 
 static void make_paint(SkPaint* paint, const SkMatrix& localMatrix) {
@@ -37,9 +34,6 @@
 
     SkRect r;
 
-    SkPaint p;
-    p.setAlpha(0x88);
-
     SkAutoCanvasRestore ar2(canvas, false);
 
     // create the layers
@@ -56,7 +50,7 @@
 
     // now draw the "content"
 
-    if (true) {
+    if ((true)) {
         r.setWH(100, 100);
 
         canvas->saveLayerAlpha(&r, 0x80);
@@ -109,7 +103,7 @@
     void onDrawContent(SkCanvas* canvas) override {
         this->drawBG(canvas);
 
-        if (true) {
+        if ((true)) {
             SkRect r;
             r.setWH(220, 120);
             SkPaint p;
@@ -122,7 +116,7 @@
             return;
         }
 
-        if (false) {
+        if ((false)) {
             SkRect r;
             r.setWH(220, 120);
             SkPaint p;
@@ -141,7 +135,7 @@
             canvas->drawOval(r, p);
         }
 
-        if (false) {
+        if ((false)) {
             SkPaint p;
             p.setAlpha(0x88);
             p.setAntiAlias(true);
@@ -164,7 +158,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 DEF_SAMPLE( return new LayersView; )
 
@@ -191,7 +185,7 @@
     SkString name() override { return SkString("Backdrop"); }
 
     void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawImage(fImage.get(), 0, 0, nullptr);
+        canvas->drawImage(fImage.get(), 0, 0);
 
         const SkScalar w = 250;
         const SkScalar h = 150;
@@ -202,12 +196,12 @@
         m.postTranslate(fCenter.x(), fCenter.y());
         path.transform(m);
 
-        canvas->clipPath(path, kIntersect_SkClipOp, true);
+        canvas->clipPath(path, SkClipOp::kIntersect, true);
         const SkRect bounds = path.getBounds();
 
         SkPaint paint;
         paint.setAlpha(0xCC);
-        canvas->saveLayer({ &bounds, &paint, fFilter.get(), nullptr, nullptr, 0 });
+        canvas->saveLayer(SkCanvas::SaveLayerRec(&bounds, &paint, fFilter.get(), 0));
 
         canvas->restore();
     }
@@ -227,6 +221,6 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 DEF_SAMPLE( return new BackdropView; )
diff --git a/third_party/skia/samplecode/SampleLighting.cpp b/third_party/skia/samplecode/SampleLighting.cpp
deleted file mode 100644
index 24a0a64..0000000
--- a/third_party/skia/samplecode/SampleLighting.cpp
+++ /dev/null
@@ -1,97 +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.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkPoint3.h"
-#include "samplecode/DecodeFile.h"
-#include "samplecode/Sample.h"
-#include "src/core/SkNormalSource.h"
-#include "src/shaders/SkLightingShader.h"
-#include "tools/Resources.h"
-
-static sk_sp<SkLights> create_lights(SkScalar angle, SkScalar blue) {
-
-    const SkVector3 dir = SkVector3::Make(SkScalarSin(angle)*SkScalarSin(SK_ScalarPI*0.25f),
-                                          SkScalarCos(angle)*SkScalarSin(SK_ScalarPI*0.25f),
-                                          SkScalarCos(SK_ScalarPI*0.25f));
-
-    SkLights::Builder builder;
-
-    builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, blue), dir));
-    builder.setAmbientLightColor(SkColor3f::Make(0.1f, 0.1f, 0.1f));
-
-    return builder.finish();
-}
-
-////////////////////////////////////////////////////////////////////////////
-
-class LightingView : public Sample {
-public:
-    LightingView() : fLightAngle(0.0f), fColorFactor(0.0f) {}
-
-protected:
-    SkString name() override { return SkString("Lighting"); }
-
-    void onOnceBeforeDraw() override {
-        {
-            SkBitmap diffuseBitmap;
-            SkAssertResult(GetResourceAsBitmap("images/brickwork-texture.jpg", &diffuseBitmap));
-
-            fRect = SkRect::MakeIWH(diffuseBitmap.width(), diffuseBitmap.height());
-
-            fDiffuseShader = diffuseBitmap.makeShader();
-        }
-
-        {
-            SkBitmap normalBitmap;
-            SkAssertResult(GetResourceAsBitmap("images/brickwork_normal-map.jpg", &normalBitmap));
-
-            sk_sp<SkShader> normalMap = normalBitmap.makeShader();
-            fNormalSource = SkNormalSource::MakeFromNormalMap(std::move(normalMap), SkMatrix::I());
-        }
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        sk_sp<SkLights> lights(create_lights(fLightAngle, fColorFactor));
-
-        SkPaint paint;
-        paint.setShader(SkLightingShader::Make(fDiffuseShader,
-                                               fNormalSource,
-                                               std::move(lights)));
-        paint.setColor(SK_ColorBLACK);
-
-        canvas->drawRect(fRect, paint);
-    }
-
-    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
-        return this->INHERITED::onFindClickHandler(x, y, modi);
-    }
-
-    bool onAnimate(double nanos) override {
-        fLightAngle += 0.015f;
-        fColorFactor += 0.01f;
-        if (fColorFactor > 1.0f) {
-            fColorFactor = 0.0f;
-        }
-
-        return true;
-    }
-
-private:
-    SkRect                fRect;
-    sk_sp<SkShader>       fDiffuseShader;
-    sk_sp<SkNormalSource> fNormalSource;
-
-    SkScalar              fLightAngle;
-    SkScalar              fColorFactor;
-
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new LightingView(); )
diff --git a/third_party/skia/samplecode/SampleLitAtlas.cpp b/third_party/skia/samplecode/SampleLitAtlas.cpp
deleted file mode 100644
index d43e6d7..0000000
--- a/third_party/skia/samplecode/SampleLitAtlas.cpp
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkDrawable.h"
-#include "include/core/SkRSXform.h"
-#include "include/utils/SkRandom.h"
-#include "samplecode/Sample.h"
-#include "src/core/SkNormalSource.h"
-#include "src/shaders/SkBitmapProcShader.h"
-#include "src/shaders/SkLightingShader.h"
-#include "src/shaders/SkLights.h"
-
-#include "tools/ToolUtils.h"
-
-// A crude normal mapped asteroids-like sample
-class DrawLitAtlasDrawable : public SkDrawable {
-public:
-    DrawLitAtlasDrawable(const SkRect& r)
-            : fBounds(r)
-            , fUseColors(false)
-            , fLightDir(SkVector3::Make(1.0f, 0.0f, 0.0f)) {
-        fAtlas = MakeAtlas();
-
-        SkRandom rand;
-        for (int i = 0; i < kNumAsteroids; ++i) {
-            fAsteroids[i].initAsteroid(&rand, fBounds, &fDiffTex[i], &fNormTex[i]);
-        }
-
-        fShip.initShip(fBounds, &fDiffTex[kNumAsteroids], &fNormTex[kNumAsteroids]);
-
-        this->updateLights();
-    }
-
-    void toggleUseColors() {
-        fUseColors = !fUseColors;
-    }
-
-    void rotateLight() {
-        SkScalar r = SK_ScalarPI / 6.0f,
-                 s = SkScalarSin(r),
-                 c = SkScalarCos(r);
-
-        SkScalar newX = c * fLightDir.fX - s * fLightDir.fY;
-        SkScalar newY = s * fLightDir.fX + c * fLightDir.fY;
-
-        fLightDir.set(newX, newY, 0.0f);
-
-        this->updateLights();
-    }
-
-    void left() {
-        SkScalar newRot = SkScalarMod(fShip.rot() + (2*SK_ScalarPI - SK_ScalarPI/32.0f),
-                                      2 * SK_ScalarPI);
-        fShip.setRot(newRot);
-    }
-
-    void right() {
-        SkScalar newRot = SkScalarMod(fShip.rot() + SK_ScalarPI/32.0f, 2 * SK_ScalarPI);
-        fShip.setRot(newRot);
-    }
-
-    void thrust() {
-        SkScalar s = SkScalarSin(fShip.rot()),
-                 c = SkScalarCos(fShip.rot());
-
-        SkVector newVel = fShip.velocity();
-        newVel.fX += s;
-        newVel.fY += -c;
-
-        SkScalar len = newVel.length();
-        if (len > kMaxShipSpeed) {
-            newVel.setLength(SkIntToScalar(kMaxShipSpeed));
-        }
-
-        fShip.setVelocity(newVel);
-    }
-
-protected:
-    void onDraw(SkCanvas* canvas) override {
-        SkRSXform xforms[kNumAsteroids+kNumShips];
-        SkColor colors[kNumAsteroids+kNumShips];
-
-        for (int i = 0; i < kNumAsteroids; ++i) {
-            fAsteroids[i].advance(fBounds);
-            xforms[i] = fAsteroids[i].asRSXform();
-            if (fUseColors) {
-                colors[i] = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF);
-            }
-        }
-
-        fShip.advance(fBounds);
-        xforms[kNumAsteroids] = fShip.asRSXform();
-        if (fUseColors) {
-            colors[kNumAsteroids] = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF);
-        }
-
-#ifdef SK_DEBUG
-        canvas->drawBitmap(fAtlas, 0, 0); // just to see the atlas
-
-        this->drawLightDir(canvas, fBounds.centerX(), fBounds.centerY());
-#endif
-
-#if 0
-        // TODO: revitalize when drawLitAtlas API lands
-        SkPaint paint;
-        paint.setFilterQuality(kLow_SkFilterQuality);
-
-        const SkRect cull = this->getBounds();
-        const SkColor* colorsPtr = fUseColors ? colors : NULL;
-
-        canvas->drawLitAtlas(fAtlas, xforms, fDiffTex, fNormTex, colorsPtr, kNumAsteroids+1,
-                             SkXfermode::kModulate_Mode, &cull, &paint, fLights);
-#else
-        SkMatrix diffMat, normalMat;
-
-        for (int i = 0; i < kNumAsteroids+1; ++i) {
-            colors[i] = colors[i] & 0xFF000000; // to silence compilers
-            SkPaint paint;
-
-            SkRect r = fDiffTex[i];
-            r.offsetTo(0, 0);
-
-            diffMat.setRectToRect(fDiffTex[i], r, SkMatrix::kFill_ScaleToFit);
-            normalMat.setRectToRect(fNormTex[i], r, SkMatrix::kFill_ScaleToFit);
-
-            SkMatrix m;
-            m.setRSXform(xforms[i]);
-
-            sk_sp<SkShader> normalMap = fAtlas.makeShader(&normalMat);
-            sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap(
-                    std::move(normalMap), m);
-            sk_sp<SkShader> diffuseShader = fAtlas.makeShader(&diffMat);
-            paint.setShader(SkLightingShader::Make(std::move(diffuseShader),
-                    std::move(normalSource), fLights));
-
-            canvas->save();
-                canvas->setMatrix(m);
-                canvas->drawRect(r, paint);
-            canvas->restore();
-        }
-#endif
-
-#ifdef SK_DEBUG
-        {
-            SkPaint paint;
-            paint.setColor(SK_ColorRED);
-
-            for (int i = 0; i < kNumAsteroids; ++i) {
-                canvas->drawCircle(fAsteroids[i].pos().x(), fAsteroids[i].pos().y(), 2, paint);
-            }
-            canvas->drawCircle(fShip.pos().x(), fShip.pos().y(), 2, paint);
-
-            paint.setStyle(SkPaint::kStroke_Style);
-            canvas->drawRect(this->getBounds(), paint);
-        }
-#endif
-    }
-
-    SkRect onGetBounds() override {
-        return fBounds;
-    }
-
-private:
-
-    enum ObjType {
-        kBigAsteroid_ObjType = 0,
-        kMedAsteroid_ObjType,
-        kSmAsteroid_ObjType,
-        kShip_ObjType,
-
-        kLast_ObjType = kShip_ObjType
-    };
-
-    static const int kObjTypeCount = kLast_ObjType + 1;
-
-    void updateLights() {
-        SkLights::Builder builder;
-
-        builder.add(SkLights::Light::MakeDirectional(
-                SkColor3f::Make(1.0f, 1.0f, 1.0f), fLightDir));
-        builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f));
-
-        fLights = builder.finish();
-    }
-
-#ifdef SK_DEBUG
-    // Draw a vector to the light
-    void drawLightDir(SkCanvas* canvas, SkScalar centerX, SkScalar centerY) {
-        static const int kBgLen = 30;
-        static const int kSmLen = 5;
-
-        // TODO: change the lighting coordinate system to be right handed
-        SkPoint p1 = SkPoint::Make(centerX + kBgLen * fLightDir.fX,
-                                   centerY - kBgLen * fLightDir.fY);
-        SkPoint p2 = SkPoint::Make(centerX + (kBgLen-kSmLen) * fLightDir.fX,
-                                   centerY - (kBgLen-kSmLen) * fLightDir.fY);
-
-        SkPaint p;
-        canvas->drawLine(centerX, centerY, p1.fX, p1.fY, p);
-        canvas->drawLine(p1.fX, p1.fY,
-                         p2.fX - kSmLen * fLightDir.fY, p2.fY - kSmLen * fLightDir.fX, p);
-        canvas->drawLine(p1.fX, p1.fY,
-                         p2.fX + kSmLen * fLightDir.fY, p2.fY + kSmLen * fLightDir.fX, p);
-    }
-#endif
-
-    // Create the mixed diffuse & normal atlas
-    //
-    //    big color circle  |  big normal hemi
-    //    ------------------------------------
-    //    med color circle  |  med normal pyra
-    //    ------------------------------------
-    //    sm color circle   |   sm normal hemi
-    //    ------------------------------------
-    //    big ship          | big tetra normal
-    static SkBitmap MakeAtlas() {
-
-        SkBitmap atlas;
-        atlas.allocN32Pixels(kAtlasWidth, kAtlasHeight);
-
-        for (int y = 0; y < kAtlasHeight; ++y) {
-            int x = 0;
-            for ( ; x < kBigSize+kPad; ++x) {
-                *atlas.getAddr32(x, y) = SK_ColorTRANSPARENT;
-            }
-            for ( ; x < kAtlasWidth; ++x) {
-                *atlas.getAddr32(x, y) = SkPackARGB32(0xFF, 0x88, 0x88, 0xFF);
-            }
-        }
-
-        // big asteroid
-        {
-            SkPoint bigCenter = SkPoint::Make(kDiffXOff + kBigSize/2.0f, kBigYOff + kBigSize/2.0f);
-
-            for (int y = kBigYOff; y < kBigYOff+kBigSize; ++y) {
-                for (int x = kDiffXOff; x < kDiffXOff+kBigSize; ++x) {
-                    SkScalar distSq = (x - bigCenter.fX) * (x - bigCenter.fX) +
-                                      (y - bigCenter.fY) * (y - bigCenter.fY);
-                    if (distSq > kBigSize*kBigSize/4.0f) {
-                        *atlas.getAddr32(x, y) = SkPreMultiplyARGB(0, 0, 0, 0);
-                    } else {
-                        *atlas.getAddr32(x, y) = SkPackARGB32(0xFF, 0xFF, 0, 0);
-                    }
-                }
-            }
-
-            ToolUtils::create_hemi_normal_map(
-                    &atlas, SkIRect::MakeXYWH(kNormXOff, kBigYOff, kBigSize, kBigSize));
-        }
-
-        // medium asteroid
-        {
-            for (int y = kMedYOff; y < kMedYOff+kMedSize; ++y) {
-                for (int x = kDiffXOff; x < kDiffXOff+kMedSize; ++x) {
-                    *atlas.getAddr32(x, y) = SkPackARGB32(0xFF, 0, 0xFF, 0);
-                }
-            }
-
-            ToolUtils::create_frustum_normal_map(
-                    &atlas, SkIRect::MakeXYWH(kNormXOff, kMedYOff, kMedSize, kMedSize));
-        }
-
-        // small asteroid
-        {
-            SkPoint smCenter = SkPoint::Make(kDiffXOff + kSmSize/2.0f, kSmYOff + kSmSize/2.0f);
-
-            for (int y = kSmYOff; y < kSmYOff+kSmSize; ++y) {
-                for (int x = kDiffXOff; x < kDiffXOff+kSmSize; ++x) {
-                    SkScalar distSq = (x - smCenter.fX) * (x - smCenter.fX) +
-                                      (y - smCenter.fY) * (y - smCenter.fY);
-                    if (distSq > kSmSize*kSmSize/4.0f) {
-                        *atlas.getAddr32(x, y) = SkPreMultiplyARGB(0, 0, 0, 0);
-                    } else {
-                        *atlas.getAddr32(x, y) = SkPackARGB32(0xFF, 0, 0, 0xFF);
-                    }
-                }
-            }
-
-            ToolUtils::create_hemi_normal_map(
-                    &atlas, SkIRect::MakeXYWH(kNormXOff, kSmYOff, kSmSize, kSmSize));
-        }
-
-        // ship
-        {
-            SkScalar shipMidLine = kDiffXOff + kMedSize/2.0f;
-
-            for (int y = kShipYOff; y < kShipYOff+kMedSize; ++y) {
-                SkScalar scaledY = (y - kShipYOff)/(float)kMedSize; // 0..1
-
-                for (int x = kDiffXOff; x < kDiffXOff+kMedSize; ++x) {
-                    SkScalar scaledX;
-
-                    if (x < shipMidLine) {
-                        scaledX = 1.0f - (x - kDiffXOff)/(kMedSize/2.0f); // 0..1
-                    } else {
-                        scaledX = (x - shipMidLine)/(kMedSize/2.0f);      // 0..1
-                    }
-
-                    if (scaledX < scaledY) {
-                        *atlas.getAddr32(x, y) = SkPackARGB32(0xFF, 0, 0xFF, 0xFF);
-                    } else {
-                        *atlas.getAddr32(x, y) = SkPackARGB32(0, 0, 0, 0);
-                    }
-                }
-            }
-
-            ToolUtils::create_tetra_normal_map(
-                    &atlas, SkIRect::MakeXYWH(kNormXOff, kShipYOff, kMedSize, kMedSize));
-        }
-
-        return atlas;
-    }
-
-    class ObjectRecord {
-    public:
-        void initAsteroid(SkRandom *rand, const SkRect& bounds,
-                          SkRect* diffTex, SkRect* normTex) {
-            static const SkScalar gMaxSpeeds[3] = { 1, 2, 5 }; // smaller asteroids can go faster
-            static const SkScalar gYOffs[3] = { kBigYOff, kMedYOff, kSmYOff };
-            static const SkScalar gSizes[3] = { kBigSize, kMedSize, kSmSize };
-
-            static unsigned int asteroidType = 0;
-            fObjType = static_cast<ObjType>(asteroidType++ % 3);
-
-            fPosition.set(bounds.fLeft + rand->nextUScalar1() * bounds.width(),
-                          bounds.fTop + rand->nextUScalar1() * bounds.height());
-            fVelocity.fX = rand->nextSScalar1();
-            fVelocity.fY = sqrt(1.0f - fVelocity.fX * fVelocity.fX);
-            SkASSERT(SkScalarNearlyEqual(fVelocity.length(), 1.0f));
-            fVelocity *= gMaxSpeeds[fObjType];
-            fRot = 0;
-            fDeltaRot = rand->nextSScalar1() / 32;
-
-            diffTex->setXYWH(SkIntToScalar(kDiffXOff), gYOffs[fObjType],
-                             gSizes[fObjType], gSizes[fObjType]);
-            normTex->setXYWH(SkIntToScalar(kNormXOff), gYOffs[fObjType],
-                             gSizes[fObjType], gSizes[fObjType]);
-        }
-
-        void initShip(const SkRect& bounds, SkRect* diffTex, SkRect* normTex) {
-            fObjType = kShip_ObjType;
-            fPosition.set(bounds.centerX(), bounds.centerY());
-            fVelocity = SkVector::Make(0.0f, 0.0f);
-            fRot = 0.0f;
-            fDeltaRot = 0.0f;
-
-            diffTex->setXYWH(SkIntToScalar(kDiffXOff), SkIntToScalar(kShipYOff),
-                             SkIntToScalar(kMedSize), SkIntToScalar(kMedSize));
-            normTex->setXYWH(SkIntToScalar(kNormXOff), SkIntToScalar(kShipYOff),
-                             SkIntToScalar(kMedSize), SkIntToScalar(kMedSize));
-        }
-
-        void advance(const SkRect& bounds) {
-            fPosition += fVelocity;
-            if (fPosition.fX > bounds.right()) {
-                SkASSERT(fVelocity.fX > 0);
-                fVelocity.fX = -fVelocity.fX;
-            } else if (fPosition.fX < bounds.left()) {
-                SkASSERT(fVelocity.fX < 0);
-                fVelocity.fX = -fVelocity.fX;
-            }
-            if (fPosition.fY > bounds.bottom()) {
-                if (fVelocity.fY > 0) {
-                    fVelocity.fY = -fVelocity.fY;
-                }
-            } else if (fPosition.fY < bounds.top()) {
-                if (fVelocity.fY < 0) {
-                    fVelocity.fY = -fVelocity.fY;
-                }
-            }
-
-            fRot += fDeltaRot;
-            fRot = SkScalarMod(fRot, 2 * SK_ScalarPI);
-        }
-
-        const SkPoint& pos() const { return fPosition; }
-
-        SkScalar rot() const { return fRot; }
-        void setRot(SkScalar rot) { fRot = rot; }
-
-        const SkPoint& velocity() const { return fVelocity; }
-        void setVelocity(const SkPoint& velocity) { fVelocity = velocity; }
-
-        SkRSXform asRSXform() const {
-            static const SkScalar gHalfSizes[kObjTypeCount] = {
-                SkScalarHalf(kBigSize),
-                SkScalarHalf(kMedSize),
-                SkScalarHalf(kSmSize),
-                SkScalarHalf(kMedSize),
-            };
-
-            return SkRSXform::MakeFromRadians(1.0f, fRot, fPosition.x(), fPosition.y(),
-                                              gHalfSizes[fObjType],
-                                              gHalfSizes[fObjType]);
-        }
-
-    private:
-        ObjType     fObjType;
-        SkPoint     fPosition;
-        SkVector    fVelocity;
-        SkScalar    fRot;        // In radians.
-        SkScalar    fDeltaRot;   // In radiands. Not used by ship.
-    };
-
-private:
-    static const int kNumLights = 2;
-    static const int kNumAsteroids = 6;
-    static const int kNumShips = 1;
-
-    static const int kBigSize = 128;
-    static const int kMedSize = 64;
-    static const int kSmSize = 32;
-    static const int kPad = 1;
-    static const int kAtlasWidth = kBigSize + kBigSize + 2 * kPad; // 2 pads in the middle
-    static const int kAtlasHeight = kBigSize + kMedSize + kSmSize + kMedSize + 3 * kPad;
-
-    static const int kDiffXOff = 0;
-    static const int kNormXOff = kBigSize + 2 * kPad;
-
-    static const int kBigYOff = 0;
-    static const int kMedYOff = kBigSize + kPad;
-    static const int kSmYOff = kMedYOff + kMedSize + kPad;
-    static const int kShipYOff = kSmYOff + kSmSize + kPad;
-    static const int kMaxShipSpeed = 5;
-
-    SkBitmap        fAtlas;
-    ObjectRecord    fAsteroids[kNumAsteroids];
-    ObjectRecord    fShip;
-    SkRect          fDiffTex[kNumAsteroids+kNumShips];
-    SkRect          fNormTex[kNumAsteroids+kNumShips];
-    SkRect          fBounds;
-    bool            fUseColors;
-    SkVector3       fLightDir;
-    sk_sp<SkLights> fLights;
-
-    typedef SkDrawable INHERITED;
-};
-
-class DrawLitAtlasView : public Sample {
-public:
-    DrawLitAtlasView() : fDrawable(new DrawLitAtlasDrawable(SkRect::MakeWH(640, 480))) {}
-
-protected:
-    SkString name() override { return SkString("DrawLitAtlas"); }
-
-    bool onChar(SkUnichar uni) override {
-            switch (uni) {
-                case 'C':
-                    fDrawable->toggleUseColors();
-                    return true;
-                case 'j':
-                    fDrawable->left();
-                    return true;
-                case 'k':
-                    fDrawable->thrust();
-                    return true;
-                case 'l':
-                    fDrawable->right();
-                    return true;
-                case 'o':
-                    fDrawable->rotateLight();
-                    return true;
-                default:
-                    break;
-            }
-            return false;
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawDrawable(fDrawable.get());
-    }
-
-    bool onAnimate(double nanos) override { return true; }
-
-private:
-    sk_sp<DrawLitAtlasDrawable> fDrawable;
-
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new DrawLitAtlasView(); )
diff --git a/third_party/skia/samplecode/SampleLua.cpp b/third_party/skia/samplecode/SampleLua.cpp
deleted file mode 100644
index 1a094bb..0000000
--- a/third_party/skia/samplecode/SampleLua.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkData.h"
-#include "include/utils/SkLua.h"
-#include "samplecode/Sample.h"
-#include "tools/Resources.h"
-
-extern "C" {
-#include "lua.h"
-#include "lualib.h"
-#include "lauxlib.h"
-}
-
-//#define LUA_FILENAME    "lua/test.lua"
-#define LUA_FILENAME    "lua/slides.lua"
-
-static const char gDrawName[] = "onDrawContent";
-static const char gClickName[] = "onClickHandler";
-static const char gUnicharName[] = "onCharHandler";
-
-static const char gMissingCode[] = ""
-    "local paint = Sk.newPaint()"
-    "paint:setAntiAlias(true)"
-    "paint:setTextSize(30)"
-    ""
-    "function onDrawContent(canvas)"
-    "   canvas:drawText('missing \"test.lua\"', 20, 50, paint)"
-    "end"
-    ;
-
-class LuaView : public Sample {
-public:
-    LuaView() : fLua(nullptr) {}
-
-    ~LuaView() override { delete fLua; }
-
-    void setImageFilename(lua_State* L) {
-        SkString str = GetResourcePath("images/mandrill_256.png");
-
-        lua_getglobal(L, "setImageFilename");
-        if (lua_isfunction(L, -1)) {
-            fLua->pushString(str.c_str());
-            if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
-                SkDebugf("lua err: %s\n", lua_tostring(L, -1));
-            }
-        }
-    }
-
-    lua_State* ensureLua() {
-        if (nullptr == fLua) {
-            fLua = new SkLua;
-
-            sk_sp<SkData> data = GetResourceAsData(LUA_FILENAME);
-            if (data) {
-                fLua->runCode(data->data(), data->size());
-                this->setImageFilename(fLua->get());
-            } else {
-                fLua->runCode(gMissingCode);
-            }
-        }
-        return fLua->get();
-    }
-
-protected:
-    SkString name() override { return SkString("Lua"); }
-
-    bool onChar(SkUnichar uni) override {
-            lua_State* L = this->ensureLua();
-            lua_getglobal(L, gUnicharName);
-            if (lua_isfunction(L, -1)) {
-                SkString str;
-                str.appendUnichar(uni);
-                fLua->pushString(str.c_str());
-                if (lua_pcall(L, 1, 1, 0) != LUA_OK) {
-                    SkDebugf("lua err: %s\n", lua_tostring(L, -1));
-                } else {
-                    if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        lua_State* L = this->ensureLua();
-
-        lua_getglobal(L, gDrawName);
-        if (!lua_isfunction(L, -1)) {
-            int t = lua_type(L, -1);
-            SkDebugf("--- expected %s function %d, ignoring.\n", gDrawName, t);
-            lua_pop(L, 1);
-        } else {
-            // does it make sense to try to "cache" the lua version of this
-            // canvas between draws?
-            fLua->pushCanvas(canvas);
-            fLua->pushScalar(this->width());
-            fLua->pushScalar(this->height());
-            if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
-                SkDebugf("lua err: %s\n", lua_tostring(L, -1));
-            }
-        }
-    }
-
-    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
-                                              skui::ModifierKey modi) override {
-        lua_State* L = this->ensureLua();
-        lua_getglobal(L, gClickName);
-        if (lua_isfunction(L, -1)) {
-            fLua->pushScalar(x);
-            fLua->pushScalar(y);
-            fLua->pushString("down");
-            if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
-                SkDebugf("lua err: %s\n", lua_tostring(L, -1));
-            } else {
-                if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
-                    return new Click();
-                }
-            }
-        }
-        return this->INHERITED::onFindClickHandler(x, y, modi);
-    }
-
-    bool onClick(Click* click) override {
-        const char* state = nullptr;
-        switch (click->fState) {
-            case skui::InputState::kMove:
-                state = "moved";
-                break;
-            case skui::InputState::kUp:
-                state = "up";
-                break;
-            default:
-                break;
-        }
-        if (state) {
-            lua_State* L = fLua->get();
-            lua_getglobal(L, gClickName);
-            fLua->pushScalar(click->fCurr.x());
-            fLua->pushScalar(click->fCurr.y());
-            fLua->pushString(state);
-            lua_pcall(L, 3, 1, 0);
-            return lua_isboolean(L, -1) && lua_toboolean(L, -1);
-        }
-        return true;
-    }
-
-private:
-    SkLua* fLua;
-
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new LuaView(); )
diff --git a/third_party/skia/samplecode/SampleManyRects.cpp b/third_party/skia/samplecode/SampleManyRects.cpp
index cfd66c9..ba3bdb1 100644
--- a/third_party/skia/samplecode/SampleManyRects.cpp
+++ b/third_party/skia/samplecode/SampleManyRects.cpp
@@ -38,7 +38,7 @@
 
             canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
             // Uncomment to test rotated rect draw combining.
-            if (false) {
+            if ((false)) {
                 SkMatrix rotate;
                 rotate.setRotate(fRandom.nextUScalar1() * 360,
                                  SkIntToScalar(x) + SkScalarHalf(rect.fRight),
@@ -59,7 +59,7 @@
 
 private:
     SkRandom fRandom;
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleMaterialShadows.cpp b/third_party/skia/samplecode/SampleMaterialShadows.cpp
new file mode 100644
index 0000000..8cb951f
--- /dev/null
+++ b/third_party/skia/samplecode/SampleMaterialShadows.cpp
@@ -0,0 +1,147 @@
+
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "include/core/SkCanvas.h"
+#include "include/core/SkColorFilter.h"
+#include "include/core/SkPath.h"
+#include "include/core/SkPoint3.h"
+#include "include/pathops/SkPathOps.h"
+#include "include/utils/SkCamera.h"
+#include "include/utils/SkShadowUtils.h"
+#include "samplecode/Sample.h"
+#include "src/core/SkBlurMask.h"
+#include "src/utils/SkUTF.h"
+#include "tools/ToolUtils.h"
+#include "tools/timer/TimeUtils.h"
+
+////////////////////////////////////////////////////////////////////////////
+
+class MaterialShadowsView : public Sample {
+    SkPath    fCirclePath;
+    SkPath    fCapsulePath;
+    SkPath    fLargeRRPath;
+    SkPath    fSmallRRPath;
+
+    SkPoint3  fLightPos;
+
+    void onOnceBeforeDraw() override {
+        fCirclePath.addCircle(0, 0, 56/2);
+        fCapsulePath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-64, -24, 128, 48), 24, 24));
+        fLargeRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-64, -64, 128, 128), 4, 4));
+        fSmallRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-40, -40, 80, 80), 4, 4));
+
+        fLightPos = SkPoint3::Make(0, -700, 700);
+    }
+
+    SkString name() override { return SkString("MaterialShadows"); }
+
+    void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
+                          const SkPoint3& zPlaneParams,
+                          const SkPaint& paint, SkScalar ambientAlpha,
+                          const SkPoint3& lightPos, SkScalar lightRadius, SkScalar spotAlpha) {
+        uint32_t flags = 0;
+        flags |= SkShadowFlags::kDirectionalLight_ShadowFlag;
+
+        SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
+        SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
+        SkShadowUtils::DrawShadow(canvas, path, zPlaneParams, lightPos, lightRadius,
+                                  ambientColor, spotColor, flags);
+
+        canvas->drawPath(path, paint);
+    }
+
+    void onDrawContent(SkCanvas* canvas) override {
+        canvas->drawColor(0xFFFFFFFF);
+
+        const SkScalar kLightRadius = 1.1f;
+        const SkScalar kAmbientAlpha = 0.05f;
+        const SkScalar kSpotAlpha = 0.35f;
+
+        const SkScalar elevations[] = { 1, 3, 6, 8, 12, 24 };
+
+        SkPaint paint;
+        paint.setAntiAlias(true);
+
+        SkPoint3 lightPos = fLightPos;
+        SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, 0);
+
+        paint.setColor(SK_ColorWHITE);
+        canvas->save();
+        canvas->translate(80, 80);
+        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
+            zPlaneParams.fZ = elevations[i];
+            this->drawShadowedPath(canvas, fCirclePath, zPlaneParams, paint, kAmbientAlpha,
+                                   lightPos, kLightRadius, kSpotAlpha);
+            canvas->translate(80, 0);
+        }
+        canvas->restore();
+
+        canvas->save();
+        canvas->translate(120, 175);
+        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
+            zPlaneParams.fZ = elevations[i];
+            this->drawShadowedPath(canvas, fCapsulePath, zPlaneParams, paint, kAmbientAlpha,
+                                   lightPos, kLightRadius, kSpotAlpha);
+            canvas->translate(160, 0);
+        }
+        canvas->restore();
+
+        canvas->save();
+        canvas->translate(120, 320);
+        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
+            zPlaneParams.fZ = elevations[i];
+            this->drawShadowedPath(canvas, fLargeRRPath, zPlaneParams, paint, kAmbientAlpha,
+                                   lightPos, kLightRadius, kSpotAlpha);
+            canvas->translate(160, 0);
+        }
+        canvas->restore();
+
+        canvas->save();
+        canvas->translate(100, 475);
+        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
+            zPlaneParams.fZ = elevations[i];
+            this->drawShadowedPath(canvas, fSmallRRPath, zPlaneParams, paint, kAmbientAlpha,
+                                   lightPos, kLightRadius, kSpotAlpha);
+            canvas->translate(160, 0);
+        }
+        canvas->restore();
+
+        canvas->save();
+        canvas->translate(100, 600);
+        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
+            canvas->save();
+            zPlaneParams.fZ = elevations[i];
+            canvas->rotate(10);
+            this->drawShadowedPath(canvas, fSmallRRPath, zPlaneParams, paint, kAmbientAlpha,
+                                   lightPos, kLightRadius, kSpotAlpha);
+            canvas->restore();
+            canvas->translate(160, 0);
+        }
+        canvas->restore();
+
+        canvas->save();
+        canvas->translate(100, 725);
+        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
+            canvas->save();
+            zPlaneParams.fZ = elevations[i];
+            canvas->rotate(45);
+            this->drawShadowedPath(canvas, fSmallRRPath, zPlaneParams, paint, kAmbientAlpha,
+                                   lightPos, kLightRadius, kSpotAlpha);
+            canvas->restore();
+            canvas->translate(160, 0);
+        }
+        canvas->restore();
+
+    }
+
+private:
+    using INHERITED = Sample;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_SAMPLE( return new MaterialShadowsView(); )
diff --git a/third_party/skia/samplecode/SampleMegaStroke.cpp b/third_party/skia/samplecode/SampleMegaStroke.cpp
index 33fa431..15579d9 100644
--- a/third_party/skia/samplecode/SampleMegaStroke.cpp
+++ b/third_party/skia/samplecode/SampleMegaStroke.cpp
@@ -76,7 +76,7 @@
     SkRect      fClip;
     int         fAngle;
     int         fPlusMinus;
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleMixer.cpp b/third_party/skia/samplecode/SampleMixer.cpp
index 7e39ab1..aa164b4 100644
--- a/third_party/skia/samplecode/SampleMixer.cpp
+++ b/third_party/skia/samplecode/SampleMixer.cpp
@@ -40,13 +40,14 @@
     void dodraw(SkCanvas* canvas, sk_sp<SkColorFilter> cf0, sk_sp<SkColorFilter> cf1, float gap) {
         SkPaint paint;
         paint.setColorFilter(cf0);
-        canvas->drawImage(fImg, 0, 0, &paint);
+        canvas->drawImage(fImg, 0, 0, SkSamplingOptions(), &paint);
 
         paint.setColorFilter(SkColorFilters::Lerp(fWeight, cf0, cf1));
-        canvas->drawImage(fImg, fImg->width() + gap * fWeight, 0, &paint);
+        canvas->drawImage(fImg, fImg->width() + gap * fWeight, 0,
+                          SkSamplingOptions(), &paint);
 
         paint.setColorFilter(cf1);
-        canvas->drawImage(fImg, 2*fImg->width() + gap, 0, &paint);
+        canvas->drawImage(fImg, 2*fImg->width() + gap, 0, SkSamplingOptions(), &paint);
     }
 
     void onDrawContent(SkCanvas* canvas) override {
@@ -71,7 +72,7 @@
         }
     }
 
-    virtual Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override {
+    Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override {
         return fRect.contains(SkScalarRoundToInt(x),
                               SkScalarRoundToInt(y)) ? new Click() : nullptr;
     }
@@ -85,94 +86,6 @@
 private:
     SkIRect fRect;
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 DEF_SAMPLE( return new MixerView; )
-
-//////////////////////////////////////////////////////////////////////////////
-
-#include "include/core/SkMaskFilter.h"
-#include "include/core/SkSurface.h"
-
-static sk_sp<SkShader> make_resource_shader(const char path[], int size) {
-    auto img = GetResourceAsImage(path);
-    if (!img) {
-        return nullptr;
-    }
-    SkRect src = SkRect::MakeIWH(img->width(), img->height());
-    SkRect dst = SkRect::MakeIWH(size, size);
-    SkMatrix m;
-    m.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
-    return img->makeShader(&m);
-}
-
-class ShaderMixerView : public Sample {
-    sk_sp<SkShader>     fSH0;
-    sk_sp<SkShader>     fSH1;
-    sk_sp<SkSurface>    fSurface;
-    SkBlendMode         fMode = SkBlendMode::kClear;
-
-    enum { SIZE = 256 };
-
-    const SkRect fRect = SkRect::MakeXYWH(10, 10 + SIZE + 10, SIZE, SIZE);
-
-public:
-    ShaderMixerView() {}
-
-    void onOnceBeforeDraw() override {
-        fSH0 = make_resource_shader("images/mandrill_256.png", SIZE);
-        fSH1 = make_resource_shader("images/baby_tux.png", SIZE);
-    }
-
-protected:
-    SkString name() override { return SkString("ShaderMixer"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        if (!fSurface) {
-            fSurface = canvas->makeSurface(SkImageInfo::MakeN32Premul(SIZE, SIZE));
-        }
-
-        SkPaint paint;
-        const SkRect r = SkRect::MakeIWH(SIZE, SIZE);
-
-        canvas->translate(10, 10);
-
-        canvas->save();
-        paint.setShader(fSH0); canvas->drawRect(r, paint);
-        canvas->translate(SIZE + 10.f, 0);
-        paint.setShader(fSH1); canvas->drawRect(r, paint);
-        canvas->restore();
-
-        canvas->translate(0, SIZE + 10.f);
-
-        auto sh = fSurface->makeImageSnapshot()->makeShader();
-
-        canvas->save();
-        paint.setShader(sh); canvas->drawRect(r, paint);
-        canvas->translate(SIZE + 10.f, 0);
-        paint.setShader(SkShaders::Lerp(sh, fSH0, fSH1)); canvas->drawRect(r, paint);
-        canvas->restore();
-    }
-
-    virtual Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override {
-        fMode = (fMode == SkBlendMode::kSrcOver) ? SkBlendMode::kClear : SkBlendMode::kSrcOver;
-        return fRect.contains(SkScalarRoundToInt(x),
-                              SkScalarRoundToInt(y)) ? new Click() : nullptr;
-    }
-
-    bool onClick(Click* click) override {
-        SkPaint p;
-        p.setAntiAlias(true);
-        p.setColor(SK_ColorRED);
-        p.setBlendMode(fMode);
-        p.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 12));
-        SkScalar x = click->fCurr.fX - fRect.fLeft;
-        SkScalar y = click->fCurr.fY - fRect.fTop;
-        fSurface->getCanvas()->drawCircle(x, y, 10, p);
-        return true;
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-DEF_SAMPLE( return new ShaderMixerView; )
diff --git a/third_party/skia/samplecode/SampleParagraph.cpp b/third_party/skia/samplecode/SampleParagraph.cpp
deleted file mode 100644
index cc10e03..0000000
--- a/third_party/skia/samplecode/SampleParagraph.cpp
+++ /dev/null
@@ -1,1720 +0,0 @@
-// Copyright 2019 Google LLC.
-#include "include/core/SkCanvas.h"
-#include "include/core/SkColorFilter.h"
-#include "include/core/SkColorPriv.h"
-#include "include/core/SkGraphics.h"
-#include "include/core/SkPath.h"
-#include "include/core/SkRegion.h"
-#include "include/core/SkShader.h"
-#include "include/core/SkStream.h"
-#include "include/core/SkTextBlob.h"
-#include "include/core/SkTime.h"
-#include "include/core/SkTypeface.h"
-#include "include/effects/SkBlurMaskFilter.h"
-#include "include/effects/SkGradientShader.h"
-#include "include/utils/SkRandom.h"
-#include "modules/skparagraph/include/Paragraph.h"
-#include "modules/skparagraph/include/TypefaceFontProvider.h"
-#include "modules/skparagraph/src/ParagraphBuilderImpl.h"
-#include "modules/skparagraph/src/ParagraphImpl.h"
-#include "modules/skparagraph/utils/TestFontCollection.h"
-#include "samplecode/Sample.h"
-#include "src/core/SkOSFile.h"
-#include "src/shaders/SkColorShader.h"
-#include "src/utils/SkOSPath.h"
-#include "src/utils/SkUTF.h"
-#include "tools/Resources.h"
-
-using namespace skia::textlayout;
-namespace {
-
-class ParagraphView_Base : public Sample {
-protected:
-    sk_sp<TestFontCollection> getFontCollection() {
-        // If we reset font collection we need to reset paragraph cache
-        static sk_sp<TestFontCollection> fFC = nullptr;
-        if (fFC == nullptr) {
-            fFC = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
-        }
-        return fFC;
-    }
-};
-
-sk_sp<SkShader> setgrad(const SkRect& r, SkColor c0, SkColor c1) {
-    SkColor colors[] = {c0, c1};
-    SkPoint pts[] = {{r.fLeft, r.fTop}, {r.fRight, r.fTop}};
-    return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
-}
-/*
-void writeHtml(const char* name, Paragraph* paragraph) {
-        SkString tmpDir = skiatest::GetTmpDir();
-        if (!tmpDir.isEmpty()) {
-            SkString path = SkOSPath::Join(tmpDir.c_str(), name);
-            SkFILEWStream file(path.c_str());
-            file.write(nullptr, 0);
-        }
-}
-*/
-}  // namespace
-
-class ParagraphView1 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph1"); }
-
-    void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) {
-        const std::vector<
-            std::tuple<std::string, bool, bool, int, SkColor, SkColor, bool, TextDecorationStyle>>
-            gParagraph = {{"monospace", true, false, 14, SK_ColorWHITE, SK_ColorRED, true,
-                           TextDecorationStyle::kDashed},
-                          {"Assyrian", false, false, 20, SK_ColorWHITE, SK_ColorBLUE, false,
-                           TextDecorationStyle::kDotted},
-                          {"serif", true, true, 10, SK_ColorWHITE, SK_ColorRED, true,
-                           TextDecorationStyle::kDouble},
-                          {"Arial", false, true, 16, SK_ColorGRAY, SK_ColorGREEN, true,
-                           TextDecorationStyle::kSolid},
-                          {"sans-serif", false, false, 8, SK_ColorWHITE, SK_ColorRED, false,
-                           TextDecorationStyle::kWavy}};
-        SkAutoCanvasRestore acr(canvas, true);
-
-        canvas->clipRect(SkRect::MakeWH(w, h));
-        canvas->drawColor(SK_ColorWHITE);
-
-        SkScalar margin = 20;
-
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setColor(fg);
-
-        SkPaint blue;
-        blue.setColor(SK_ColorBLUE);
-
-        TextStyle defaultStyle;
-        defaultStyle.setBackgroundColor(blue);
-        defaultStyle.setForegroundColor(paint);
-        ParagraphStyle paraStyle;
-
-        auto fontCollection = sk_make_sp<FontCollection>();
-        fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
-        for (auto i = 1; i < 5; ++i) {
-            defaultStyle.setFontSize(24 * i);
-            paraStyle.setTextStyle(defaultStyle);
-            ParagraphBuilderImpl builder(paraStyle, fontCollection);
-            std::string name = "Paragraph: " + std::to_string(24 * i);
-            builder.addText(name.c_str(), name.length());
-            for (auto para : gParagraph) {
-                TextStyle style;
-                style.setFontFamilies({SkString(std::get<0>(para).c_str())});
-                SkFontStyle fontStyle(std::get<1>(para) ? SkFontStyle::Weight::kBold_Weight
-                                                        : SkFontStyle::Weight::kNormal_Weight,
-                                      SkFontStyle::Width::kNormal_Width,
-                                      std::get<2>(para) ? SkFontStyle::Slant::kItalic_Slant
-                                                        : SkFontStyle::Slant::kUpright_Slant);
-                style.setFontStyle(fontStyle);
-                style.setFontSize(std::get<3>(para) * i);
-                SkPaint background;
-                background.setColor(std::get<4>(para));
-                style.setBackgroundColor(background);
-                SkPaint foreground;
-                foreground.setColor(std::get<5>(para));
-                foreground.setAntiAlias(true);
-                style.setForegroundColor(foreground);
-                if (std::get<6>(para)) {
-                    style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(5, 5), 2));
-                }
-
-                auto decoration = (i % 4);
-                if (decoration == 3) {
-                    decoration = 4;
-                }
-
-                bool test = (TextDecoration)decoration != TextDecoration::kNoDecoration;
-                std::string deco = std::to_string((int)decoration);
-                if (test) {
-                    style.setDecoration((TextDecoration)decoration);
-                    style.setDecorationStyle(std::get<7>(para));
-                    style.setDecorationColor(std::get<5>(para));
-                }
-                builder.pushStyle(style);
-                std::string name = " " + std::get<0>(para) + " " +
-                                   (std::get<1>(para) ? ", bold" : "") +
-                                   (std::get<2>(para) ? ", italic" : "") + " " +
-                                   std::to_string(std::get<3>(para) * i) +
-                                   (std::get<4>(para) != bg ? ", background" : "") +
-                                   (std::get<5>(para) != fg ? ", foreground" : "") +
-                                   (std::get<6>(para) ? ", shadow" : "") +
-                                   (test ? ", decorations " + deco : "") + ";";
-                builder.addText(name.c_str(), name.length());
-                builder.pop();
-            }
-
-            auto paragraph = builder.Build();
-            paragraph->layout(w - margin * 2);
-            paragraph->paint(canvas, margin, margin);
-
-            canvas->translate(0, paragraph->getHeight());
-        }
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        drawTest(canvas, this->width(), this->height(), SK_ColorRED, SK_ColorWHITE);
-    }
-
-private:
-
-    typedef Sample INHERITED;
-};
-
-class ParagraphView2 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph2"); }
-
-    void drawCode(SkCanvas* canvas, SkScalar w, SkScalar h) {
-        SkPaint comment;
-        comment.setColor(SK_ColorGRAY);
-        SkPaint constant;
-        constant.setColor(SK_ColorMAGENTA);
-        SkPaint null;
-        null.setColor(SK_ColorMAGENTA);
-        SkPaint literal;
-        literal.setColor(SK_ColorGREEN);
-        SkPaint code;
-        code.setColor(SK_ColorDKGRAY);
-        SkPaint number;
-        number.setColor(SK_ColorBLUE);
-        SkPaint name;
-        name.setColor(SK_ColorRED);
-
-        SkPaint white;
-        white.setColor(SK_ColorWHITE);
-
-        TextStyle defaultStyle;
-        defaultStyle.setBackgroundColor(white);
-        defaultStyle.setForegroundColor(code);
-        defaultStyle.setFontFamilies({SkString("monospace")});
-        defaultStyle.setFontSize(30);
-        ParagraphStyle paraStyle;
-        paraStyle.setTextStyle(defaultStyle);
-
-        auto fontCollection = sk_make_sp<FontCollection>();
-        fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
-        ParagraphBuilderImpl builder(paraStyle, fontCollection);
-
-        const char* text1 = "RaisedButton";
-        const char* text2 = "(\n";
-        const char* text3 = "  child: ";
-        const char* text4 = "const";
-        const char* text5 = "Text";
-        const char* text6 = "'BUTTON TITLE'";
-        const char* text7 = "),\n";
-
-        builder.pushStyle(style(name));
-        builder.addText(text1, strlen(text1));
-        builder.pop();
-        builder.addText(text2, strlen(text2));
-        builder.addText(text3, strlen(text3));
-        builder.pushStyle(style(constant));
-        builder.addText(text4, strlen(text4));
-        builder.pop();
-        builder.addText(" ", 1);
-        builder.pushStyle(style(name));
-        builder.addText(text5, strlen(text5));
-        builder.pop();
-        builder.addText("(", 1);
-        builder.pushStyle(style(literal));
-        builder.addText(text6, strlen(text6));
-        builder.pop();
-        builder.addText(text7, strlen(text7));
-
-        auto paragraph = builder.Build();
-        paragraph->layout(w - 20);
-
-        paragraph->paint(canvas, 20, 20);
-    }
-
-    TextStyle style(SkPaint paint) {
-        TextStyle style;
-        paint.setAntiAlias(true);
-        style.setForegroundColor(paint);
-        style.setFontFamilies({SkString("monospace")});
-        style.setFontSize(30);
-
-        return style;
-    }
-
-    void drawText(SkCanvas* canvas, SkScalar w, SkScalar h, std::vector<const char*>& text,
-                  SkColor fg = SK_ColorDKGRAY, SkColor bg = SK_ColorWHITE,
-                  const char* ff = "sans-serif", SkScalar fs = 24,
-                  size_t lineLimit = 30,
-                  const std::u16string& ellipsis = u"\u2026") {
-        SkAutoCanvasRestore acr(canvas, true);
-
-        canvas->clipRect(SkRect::MakeWH(w, h));
-        canvas->drawColor(bg);
-
-        SkScalar margin = 20;
-
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setColor(fg);
-
-        SkPaint blue;
-        blue.setColor(SK_ColorBLUE);
-
-        SkPaint background;
-        background.setColor(bg);
-
-        TextStyle style;
-        style.setBackgroundColor(blue);
-        style.setForegroundColor(paint);
-        style.setFontFamilies({SkString(ff)});
-        style.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight,
-                                       SkFontStyle::kNormal_Width,
-                                       SkFontStyle::kUpright_Slant));
-        style.setFontSize(fs);
-        ParagraphStyle paraStyle;
-        paraStyle.setTextStyle(style);
-        paraStyle.setMaxLines(lineLimit);
-
-        paraStyle.setEllipsis(ellipsis);
-        TextStyle defaultStyle;
-        defaultStyle.setFontSize(20);
-        paraStyle.setTextStyle(defaultStyle);
-        ParagraphBuilderImpl builder(paraStyle, getFontCollection());
-
-        SkPaint foreground;
-        foreground.setColor(fg);
-        style.setForegroundColor(foreground);
-        style.setBackgroundColor(background);
-
-        for (auto& part : text) {
-            builder.pushStyle(style);
-            builder.addText(part, strlen(part));
-            builder.pop();
-        }
-
-        auto paragraph = builder.Build();
-        paragraph->layout(w - margin * 2);
-        paragraph->paint(canvas, margin, margin);
-
-        canvas->translate(0, paragraph->getHeight() + margin);
-    }
-
-    void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
-                  TextAlign align) {
-        SkAutoCanvasRestore acr(canvas, true);
-
-        canvas->clipRect(SkRect::MakeWH(w, h));
-        canvas->drawColor(SK_ColorWHITE);
-
-        SkScalar margin = 20;
-
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setColor(SK_ColorBLUE);
-
-        SkPaint gray;
-        gray.setColor(SK_ColorLTGRAY);
-
-        TextStyle style;
-        style.setBackgroundColor(gray);
-        style.setForegroundColor(paint);
-        style.setFontFamilies({SkString("Arial")});
-        style.setFontSize(30);
-        ParagraphStyle paraStyle;
-        paraStyle.setTextStyle(style);
-        paraStyle.setTextAlign(align);
-
-        auto fontCollection = sk_make_sp<FontCollection>();
-        fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
-        ParagraphBuilderImpl builder(paraStyle, fontCollection);
-        builder.addText(text.c_str(), text.length());
-
-        auto paragraph = builder.Build();
-        paragraph->layout(w - margin * 2);
-        paragraph->layout(w - margin);
-        paragraph->paint(canvas, margin, margin);
-
-        canvas->translate(0, paragraph->getHeight() + margin);
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        std::vector<const char*> cupertino = {
-                "google_logogoogle_gsuper_g_logo 1 "
-                "google_logogoogle_gsuper_g_logo 12 "
-                "google_logogoogle_gsuper_g_logo 123 "
-                "google_logogoogle_gsuper_g_logo 1234 "
-                "google_logogoogle_gsuper_g_logo 12345 "
-                "google_logogoogle_gsuper_g_logo 123456 "
-                "google_logogoogle_gsuper_g_logo 1234567 "
-                "google_logogoogle_gsuper_g_logo 12345678 "
-                "google_logogoogle_gsuper_g_logo 123456789 "
-                "google_logogoogle_gsuper_g_logo 1234567890 "
-                "google_logogoogle_gsuper_g_logo 123456789 "
-                "google_logogoogle_gsuper_g_logo 12345678 "
-                "google_logogoogle_gsuper_g_logo 1234567 "
-                "google_logogoogle_gsuper_g_logo 123456 "
-                "google_logogoogle_gsuper_g_logo 12345 "
-                "google_logogoogle_gsuper_g_logo 1234 "
-                "google_logogoogle_gsuper_g_logo 123 "
-                "google_logogoogle_gsuper_g_logo 12 "
-                "google_logogoogle_gsuper_g_logo 1 "
-                "google_logogoogle_gsuper_g_logo "
-                "google_logogoogle_gsuper_g_logo "
-                "google_logogoogle_gsuper_g_logo "
-                "google_logogoogle_gsuper_g_logo "
-                "google_logogoogle_gsuper_g_logo "
-                "google_logogoogle_gsuper_g_logo"};
-        std::vector<const char*> text = {
-                "My neighbor came over to say,\n"
-                "Although not in a neighborly way,\n\n"
-                "That he'd knock me around,\n\n\n"
-                "If I didn't stop the sound,\n\n\n\n"
-                "Of the classical music I play."};
-
-        std::vector<const char*> long_word = {
-                "A_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
-                "very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
-                "very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
-                "very_very_very_very_very_very_very_long_text"};
-
-        std::vector<const char*> very_long = {
-                "A very very very very very very very very very very very very very very very very "
-                "very very very very very very very very very very very very very very very very "
-                "very very very very very very very very very very very very very very very very "
-                "very very very very very very very long text"};
-
-        std::vector<const char*> very_word = {
-                "A very_very_very_very_very_very_very_very_very_very "
-                "very_very_very_very_very_very_very_very_very_very very very very very very very "
-                "very very very very very very very very very very very very very very very very "
-                "very very very very very very very very very very very very very long text"};
-
-        SkScalar width = this->width() / 5;
-        SkScalar height = this->height();
-        drawText(canvas, width, height, long_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
-        canvas->translate(width, 0);
-        drawText(canvas, width, height, very_long, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
-        canvas->translate(width, 0);
-        drawText(canvas, width, height, very_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
-        canvas->translate(width, 0);
-        drawText(canvas, width, height / 2, text, SK_ColorBLACK, SK_ColorWHITE, "Roboto", 20, 100,
-                 u"\u2026");
-        canvas->translate(0, height / 2);
-        drawCode(canvas, width, height / 2);
-        canvas->translate(width, -height / 2);
-
-        drawText(canvas, width, height, cupertino, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView3 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph3"); }
-
-    void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
-                  TextAlign align, size_t lineLimit = std::numeric_limits<size_t>::max(),
-                  bool RTL = false, SkColor background = SK_ColorGRAY,
-                  const std::u16string& ellipsis = u"\u2026") {
-        SkAutoCanvasRestore acr(canvas, true);
-
-        canvas->clipRect(SkRect::MakeWH(w, h));
-        canvas->drawColor(SK_ColorWHITE);
-
-        SkScalar margin = 20;
-
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setColor(SK_ColorBLACK);
-
-        SkPaint gray;
-        gray.setColor(background);
-
-        SkPaint yellow;
-        yellow.setColor(SK_ColorYELLOW);
-
-        TextStyle style;
-        style.setBackgroundColor(gray);
-        style.setForegroundColor(paint);
-        style.setFontFamilies({SkString("sans-serif")});
-        style.setFontSize(30);
-        ParagraphStyle paraStyle;
-        paraStyle.setTextStyle(style);
-        paraStyle.setTextAlign(align);
-        paraStyle.setMaxLines(lineLimit);
-        paraStyle.setEllipsis(ellipsis);
-        // paraStyle.setTextDirection(RTL ? SkTextDirection::rtl : SkTextDirection::ltr);
-
-        auto fontCollection = sk_make_sp<FontCollection>();
-        fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
-        ParagraphBuilderImpl builder(paraStyle, fontCollection);
-        if (RTL) {
-            builder.addText(mirror(text));
-        } else {
-            builder.addText(normal(text));
-        }
-
-        canvas->drawRect(SkRect::MakeXYWH(margin, margin, w - margin * 2, h - margin * 2), yellow);
-        auto paragraph = builder.Build();
-        paragraph->layout(w - margin * 2);
-        paragraph->paint(canvas, margin, margin);
-    }
-
-    std::u16string mirror(const std::string& text) {
-        std::u16string result;
-        result += u"\u202E";
-        // for (auto i = text.size(); i > 0; --i) {
-        //  result += text[i - 1];
-        //}
-
-        for (auto i = text.size(); i > 0; --i) {
-            auto ch = text[i - 1];
-            if (ch == ',') {
-                result += u"!";
-            } else if (ch == '.') {
-                result += u"!";
-            } else {
-                result += ch;
-            }
-        }
-
-        result += u"\u202C";
-        return result;
-    }
-
-    std::u16string normal(const std::string& text) {
-        std::u16string result;
-        result += u"\u202D";
-        for (auto ch : text) {
-            result += ch;
-        }
-        result += u"\u202C";
-        return result;
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        const std::string options =  // { "open-source open-source open-source open-source" };
-                {"Flutter is an open-source project to help developers "
-                 "build high-performance, high-fidelity, mobile apps for "
-                 "iOS and Android "
-                 "from a single codebase. This design lab is a playground "
-                 "and showcase of Flutter's many widgets, behaviors, "
-                 "animations, layouts, and more."};
-
-        canvas->drawColor(SK_ColorDKGRAY);
-        SkScalar width = this->width() / 4;
-        SkScalar height = this->height() / 2;
-
-        const std::string line =
-                "World domination is such an ugly phrase - I prefer to call it world optimisation";
-
-        drawLine(canvas, width, height, line, TextAlign::kLeft, 1, false, SK_ColorLTGRAY);
-        canvas->translate(width, 0);
-        drawLine(canvas, width, height, line, TextAlign::kRight, 2, false, SK_ColorLTGRAY);
-        canvas->translate(width, 0);
-        drawLine(canvas, width, height, line, TextAlign::kCenter, 3, false, SK_ColorLTGRAY);
-        canvas->translate(width, 0);
-        drawLine(canvas, width, height, line, TextAlign::kJustify, 4, false, SK_ColorLTGRAY);
-        canvas->translate(-width * 3, height);
-
-        drawLine(canvas, width, height, line, TextAlign::kLeft, 1, true, SK_ColorLTGRAY);
-        canvas->translate(width, 0);
-        drawLine(canvas, width, height, line, TextAlign::kRight, 2, true, SK_ColorLTGRAY);
-        canvas->translate(width, 0);
-        drawLine(canvas, width, height, line, TextAlign::kCenter, 3, true, SK_ColorLTGRAY);
-        canvas->translate(width, 0);
-        drawLine(canvas, width, height, line, TextAlign::kJustify, 4, true, SK_ColorLTGRAY);
-        canvas->translate(width, 0);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView4 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph4"); }
-
-    void drawFlutter(SkCanvas* canvas, SkScalar w, SkScalar h,
-                     const char* ff = "Google Sans", SkScalar fs = 30,
-                     size_t lineLimit = std::numeric_limits<size_t>::max(),
-                     const std::u16string& ellipsis = u"\u2026") {
-        SkAutoCanvasRestore acr(canvas, true);
-
-        canvas->clipRect(SkRect::MakeWH(w, h));
-
-        SkScalar margin = 20;
-
-        SkPaint black;
-        black.setAntiAlias(true);
-        black.setColor(SK_ColorBLACK);
-
-        SkPaint blue;
-        blue.setAntiAlias(true);
-        blue.setColor(SK_ColorBLUE);
-
-        SkPaint red;
-        red.setAntiAlias(true);
-        red.setColor(SK_ColorRED);
-
-        SkPaint green;
-        green.setAntiAlias(true);
-        green.setColor(SK_ColorGREEN);
-
-        SkPaint gray;
-        gray.setColor(SK_ColorLTGRAY);
-
-        SkPaint yellow;
-        yellow.setColor(SK_ColorYELLOW);
-
-        SkPaint magenta;
-        magenta.setAntiAlias(true);
-        magenta.setColor(SK_ColorMAGENTA);
-
-        TextStyle style;
-        style.setFontFamilies({SkString(ff)});
-        style.setFontSize(fs);
-
-        TextStyle style0;
-        style0.setForegroundColor(black);
-        style0.setBackgroundColor(gray);
-        style0.setFontFamilies({SkString(ff)});
-        style0.setFontSize(fs);
-        style0.setDecoration(TextDecoration::kUnderline);
-        style0.setDecorationStyle(TextDecorationStyle::kDouble);
-        style0.setDecorationColor(SK_ColorBLACK);
-
-        TextStyle style1;
-        style1.setForegroundColor(blue);
-        style1.setBackgroundColor(yellow);
-        style1.setFontFamilies({SkString(ff)});
-        style1.setFontSize(fs);
-        style1.setDecoration(TextDecoration::kOverline);
-        style1.setDecorationStyle(TextDecorationStyle::kWavy);
-        style1.setDecorationColor(SK_ColorBLACK);
-
-        TextStyle style2;
-        style2.setForegroundColor(red);
-        style2.setFontFamilies({SkString(ff)});
-        style2.setFontSize(fs);
-
-        TextStyle style3;
-        style3.setForegroundColor(green);
-        style3.setFontFamilies({SkString(ff)});
-        style3.setFontSize(fs);
-
-        TextStyle style4;
-        style4.setForegroundColor(magenta);
-        style4.setFontFamilies({SkString(ff)});
-        style4.setFontSize(fs);
-
-        ParagraphStyle paraStyle;
-        paraStyle.setTextStyle(style);
-        paraStyle.setMaxLines(lineLimit);
-
-        paraStyle.setEllipsis(ellipsis);
-
-        const char* logo1 = "google_";
-        const char* logo2 = "logo";
-        const char* logo3 = "go";
-        const char* logo4 = "ogle_logo";
-        const char* logo5 = "google_lo";
-        const char* logo6 = "go";
-        {
-            ParagraphBuilderImpl builder(paraStyle, getFontCollection());
-
-            builder.pushStyle(style0);
-            builder.addText(logo1, strlen(logo1));
-            builder.pop();
-            builder.pushStyle(style1);
-            builder.addText(logo2, strlen(logo2));
-            builder.pop();
-
-            builder.addText(" ", 1);
-
-            builder.pushStyle(style0);
-            builder.addText(logo3, strlen(logo3));
-            builder.pop();
-            builder.pushStyle(style1);
-            builder.addText(logo4, strlen(logo4));
-            builder.pop();
-
-            builder.addText(" ", 1);
-
-            builder.pushStyle(style0);
-            builder.addText(logo5, strlen(logo5));
-            builder.pop();
-            builder.pushStyle(style1);
-            builder.addText(logo6, strlen(logo6));
-            builder.pop();
-
-            auto paragraph = builder.Build();
-            paragraph->layout(w - margin * 2);
-            paragraph->paint(canvas, margin, margin);
-            canvas->translate(0, h + margin);
-        }
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-        SkScalar width = this->width();
-        SkScalar height = this->height();
-
-        drawFlutter(canvas, width, height / 2);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView5 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph5"); }
-
-    void bidi(SkCanvas* canvas, SkScalar w, SkScalar h, const std::u16string& text,
-              const std::u16string& expected, size_t lineLimit = std::numeric_limits<size_t>::max(),
-              const char* ff = "Roboto", SkScalar fs = 30,
-              const std::u16string& ellipsis = u"\u2026") {
-        SkAutoCanvasRestore acr(canvas, true);
-
-        canvas->clipRect(SkRect::MakeWH(w, h));
-
-        SkScalar margin = 20;
-
-        SkPaint black;
-        black.setColor(SK_ColorBLACK);
-        SkPaint gray;
-        gray.setColor(SK_ColorLTGRAY);
-
-        TextStyle style;
-        style.setForegroundColor(black);
-        style.setFontFamilies({SkString(ff)});
-        style.setFontSize(fs);
-
-        TextStyle style0;
-        style0.setForegroundColor(black);
-        style0.setFontFamilies({SkString(ff)});
-        style0.setFontSize(fs);
-        style0.setFontStyle(SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
-                                        SkFontStyle::kItalic_Slant));
-
-        TextStyle style1;
-        style1.setForegroundColor(gray);
-        style1.setFontFamilies({SkString(ff)});
-        style1.setFontSize(fs);
-        style1.setFontStyle(SkFontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
-                                        SkFontStyle::kUpright_Slant));
-
-        ParagraphStyle paraStyle;
-        paraStyle.setTextStyle(style);
-        paraStyle.setMaxLines(lineLimit);
-
-        paraStyle.setEllipsis(ellipsis);
-
-        ParagraphBuilderImpl builder(paraStyle, getFontCollection());
-
-        if (text.empty()) {
-            const std::u16string text0 = u"\u202Dabc";
-            const std::u16string text1 = u"\u202EFED";
-            const std::u16string text2 = u"\u202Dghi";
-            const std::u16string text3 = u"\u202ELKJ";
-            const std::u16string text4 = u"\u202Dmno";
-            builder.pushStyle(style0);
-            builder.addText(text0);
-            builder.pop();
-            builder.pushStyle(style1);
-            builder.addText(text1);
-            builder.pop();
-            builder.pushStyle(style0);
-            builder.addText(text2);
-            builder.pop();
-            builder.pushStyle(style1);
-            builder.addText(text3);
-            builder.pop();
-            builder.pushStyle(style0);
-            builder.addText(text4);
-            builder.pop();
-        } else {
-            // icu::UnicodeString unicode((UChar*) text.data(), SkToS32(text.size()));
-            // std::string str;
-            // unicode.toUTF8String(str);
-            // SkDebugf("Text: %s\n", str.c_str());
-            builder.addText(text + expected);
-        }
-
-        auto paragraph = builder.Build();
-        paragraph->layout(w - margin * 2);
-        paragraph->paint(canvas, margin, margin);
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-        SkScalar width = this->width();
-        SkScalar height = this->height() / 8;
-
-        const std::u16string text1 =
-                u"A \u202ENAC\u202Cner, exceedingly \u202ENAC\u202Cny,\n"
-                "One morning remarked to his granny:\n"
-                "A \u202ENAC\u202Cner \u202ENAC\u202C \u202ENAC\u202C,\n"
-                "Anything that he \u202ENAC\u202C,\n"
-                "But a \u202ENAC\u202Cner \u202ENAC\u202C't \u202ENAC\u202C a \u202ENAC\u202C, "
-                "\u202ENAC\u202C he?";
-        bidi(canvas, width, height * 3, text1, u"", 5);
-        canvas->translate(0, height * 3);
-
-        bidi(canvas, width, height, u"\u2067DETALOSI\u2069", u"");
-        canvas->translate(0, height);
-
-        bidi(canvas, width, height, u"\u202BDEDDEBME\u202C", u"");
-        canvas->translate(0, height);
-
-        bidi(canvas, width, height, u"\u202EEDIRREVO\u202C", u"");
-        canvas->translate(0, height);
-
-        bidi(canvas, width, height, u"\u200FTICILPMI\u200E", u"");
-        canvas->translate(0, height);
-
-        bidi(canvas, width, height, u"123 456 7890 \u202EZYXWV UTS RQP ONM LKJ IHG FED CBA\u202C.",
-             u"", 2);
-        canvas->translate(0, height);
-
-        // bidi(canvas, width, height, u"", u"");
-        // canvas->translate(0, height);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView6 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph6"); }
-
-    void hangingS(SkCanvas* canvas, SkScalar w, SkScalar h, SkScalar fs = 60.0) {
-        auto ff = "HangingS";
-
-        canvas->drawColor(SK_ColorLTGRAY);
-
-        SkPaint black;
-        black.setAntiAlias(true);
-        black.setColor(SK_ColorBLACK);
-
-        SkPaint blue;
-        blue.setAntiAlias(true);
-        blue.setColor(SK_ColorBLUE);
-
-        SkPaint red;
-        red.setAntiAlias(true);
-        red.setColor(SK_ColorRED);
-
-        SkPaint green;
-        green.setAntiAlias(true);
-        green.setColor(SK_ColorGREEN);
-
-        SkPaint gray;
-        gray.setColor(SK_ColorCYAN);
-
-        SkPaint yellow;
-        yellow.setColor(SK_ColorYELLOW);
-
-        SkPaint magenta;
-        magenta.setAntiAlias(true);
-        magenta.setColor(SK_ColorMAGENTA);
-
-        SkFontStyle fontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
-                              SkFontStyle::kItalic_Slant);
-
-        TextStyle style;
-        style.setFontFamilies({SkString(ff)});
-        style.setFontSize(fs);
-        style.setFontStyle(fontStyle);
-
-        TextStyle style0;
-        style0.setForegroundColor(black);
-        style0.setBackgroundColor(gray);
-        style0.setFontFamilies({SkString(ff)});
-        style0.setFontSize(fs);
-        style0.setFontStyle(fontStyle);
-
-        TextStyle style1;
-        style1.setForegroundColor(blue);
-        style1.setBackgroundColor(yellow);
-        style1.setFontFamilies({SkString(ff)});
-        style1.setFontSize(fs);
-        style1.setFontStyle(fontStyle);
-
-        TextStyle style2;
-        style2.setForegroundColor(red);
-        style2.setFontFamilies({SkString(ff)});
-        style2.setFontSize(fs);
-        style2.setFontStyle(fontStyle);
-
-        TextStyle style3;
-        style3.setForegroundColor(green);
-        style3.setFontFamilies({SkString(ff)});
-        style3.setFontSize(fs);
-        style3.setFontStyle(fontStyle);
-
-        TextStyle style4;
-        style4.setForegroundColor(magenta);
-        style4.setFontFamilies({SkString(ff)});
-        style4.setFontSize(fs);
-        style4.setFontStyle(fontStyle);
-
-        ParagraphStyle paraStyle;
-        paraStyle.setTextStyle(style);
-
-        const char* logo1 = "S";
-        const char* logo2 = "kia";
-        const char* logo3 = "Sk";
-        const char* logo4 = "ia";
-        const char* logo5 = "Ski";
-        const char* logo6 = "a";
-        {
-            ParagraphBuilderImpl builder(paraStyle, getFontCollection());
-
-            builder.pushStyle(style0);
-            builder.addText(logo1, strlen(logo1));
-            builder.pop();
-            builder.pushStyle(style1);
-            builder.addText(logo2, strlen(logo2));
-            builder.pop();
-
-            builder.addText("   ", 3);
-
-            builder.pushStyle(style0);
-            builder.addText(logo3, strlen(logo3));
-            builder.pop();
-            builder.pushStyle(style1);
-            builder.addText(logo4, strlen(logo4));
-            builder.pop();
-
-            builder.addText("   ", 3);
-
-            builder.pushStyle(style0);
-            builder.addText(logo5, strlen(logo5));
-            builder.pop();
-            builder.pushStyle(style1);
-            builder.addText(logo6, strlen(logo6));
-            builder.pop();
-
-            auto paragraph = builder.Build();
-            paragraph->layout(w);
-            paragraph->paint(canvas, 40, 40);
-            canvas->translate(0, h);
-        }
-
-        const char* logo11 = "S";
-        const char* logo12 = "S";
-        const char* logo13 = "S";
-        const char* logo14 = "S";
-        const char* logo15 = "S";
-        const char* logo16 = "S";
-        {
-            ParagraphBuilderImpl builder(paraStyle, getFontCollection());
-
-            builder.pushStyle(style0);
-            builder.addText(logo11, strlen(logo1));
-            builder.pop();
-            builder.pushStyle(style1);
-            builder.addText(logo12, strlen(logo2));
-            builder.pop();
-
-            builder.addText("   ", 3);
-
-            builder.pushStyle(style0);
-            builder.addText(logo13, strlen(logo3));
-            builder.pop();
-            builder.pushStyle(style1);
-            builder.addText(logo14, strlen(logo4));
-            builder.pop();
-
-            builder.addText("   ", 3);
-
-            builder.pushStyle(style0);
-            builder.addText(logo15, strlen(logo5));
-            builder.pop();
-            builder.pushStyle(style1);
-            builder.addText(logo16, strlen(logo6));
-            builder.pop();
-
-            auto paragraph = builder.Build();
-            paragraph->layout(w);
-            paragraph->paint(canvas, 40, h);
-            canvas->translate(0, h);
-        }
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-        SkScalar width = this->width();
-        SkScalar height = this->height() / 4;
-
-        hangingS(canvas, width, height);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView7 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph7"); }
-
-    void drawText(SkCanvas* canvas, SkColor background, SkScalar letterSpace, SkScalar w,
-                  SkScalar h) {
-        SkAutoCanvasRestore acr(canvas, true);
-        canvas->clipRect(SkRect::MakeWH(w, h));
-        canvas->drawColor(background);
-
-        const char* line =
-                "World domination is such an ugly phrase - I prefer to call it world optimisation.";
-
-        ParagraphStyle paragraphStyle;
-        paragraphStyle.setTextAlign(TextAlign::kLeft);
-        paragraphStyle.setMaxLines(10);
-        paragraphStyle.turnHintingOff();
-        TextStyle textStyle;
-        textStyle.setFontFamilies({SkString("Roboto")});
-        textStyle.setFontSize(30);
-        textStyle.setLetterSpacing(letterSpace);
-        textStyle.setColor(SK_ColorBLACK);
-        textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
-                                           SkFontStyle::kUpright_Slant));
-
-        ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
-        builder.pushStyle(textStyle);
-        builder.addText(line, strlen(line));
-        builder.pop();
-
-        auto paragraph = builder.Build();
-        paragraph->layout(w - 20);
-        paragraph->paint(canvas, 10, 10);
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-
-        auto h = this->height() / 4;
-        auto w = this->width() / 2;
-
-        drawText(canvas, SK_ColorGRAY, 1, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorLTGRAY, 2, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorCYAN, 3, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorGRAY, 4, w, h);
-        canvas->translate(w, -3 * h);
-
-        drawText(canvas, SK_ColorYELLOW, 5, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorGREEN, 10, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorRED, 15, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorBLUE, 20, w, h);
-        canvas->translate(0, h);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView8 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph8"); }
-
-    void drawText(SkCanvas* canvas, SkColor background, SkScalar wordSpace, SkScalar w,
-                  SkScalar h) {
-        SkAutoCanvasRestore acr(canvas, true);
-        canvas->clipRect(SkRect::MakeWH(w, h));
-        canvas->drawColor(background);
-
-        const char* line =
-                "World domination is such an ugly phrase - I prefer to call it world optimisation.";
-
-        ParagraphStyle paragraphStyle;
-        paragraphStyle.setTextAlign(TextAlign::kLeft);
-        paragraphStyle.setMaxLines(10);
-        paragraphStyle.turnHintingOff();
-        TextStyle textStyle;
-        textStyle.setFontFamilies({SkString("Roboto")});
-        textStyle.setFontSize(30);
-        textStyle.setWordSpacing(wordSpace);
-        textStyle.setColor(SK_ColorBLACK);
-        textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
-                                           SkFontStyle::kUpright_Slant));
-
-        ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
-        builder.pushStyle(textStyle);
-        builder.addText(line, strlen(line));
-        builder.pop();
-
-        auto paragraph = builder.Build();
-        paragraph->layout(w - 20);
-        paragraph->paint(canvas, 10, 10);
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-
-        auto h = this->height() / 4;
-        auto w = this->width() / 2;
-
-        drawText(canvas, SK_ColorGRAY, 1, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorLTGRAY, 2, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorCYAN, 3, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorGRAY, 4, w, h);
-        canvas->translate(w, -3 * h);
-
-        drawText(canvas, SK_ColorYELLOW, 5, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorGREEN, 10, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorRED, 15, w, h);
-        canvas->translate(0, h);
-
-        drawText(canvas, SK_ColorBLUE, 20, w, h);
-        canvas->translate(0, h);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView9 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph9"); }
-
-    bool onChar(SkUnichar uni) override {
-            switch (uni) {
-                case 'w':
-                    ++wordSpacing;
-                    return true;
-                case 'q':
-                    if (wordSpacing > 0) --wordSpacing;
-                    return true;
-                case 'l':
-                    ++letterSpacing;
-                    return true;
-                case 'k':
-                    if (letterSpacing > 0) --letterSpacing;
-                    return true;
-                default:
-                    break;
-            }
-            return false;
-    }
-
-    void drawText(SkCanvas* canvas, SkColor background, SkScalar w, SkScalar h) {
-        SkAutoCanvasRestore acr(canvas, true);
-        canvas->clipRect(SkRect::MakeWH(w, h));
-        canvas->drawColor(background);
-
-        auto fontCollection = sk_make_sp<FontCollection>();
-        fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
-        fontCollection->enableFontFallback();
-
-        const char* text =
-                "(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)("
-                "　´･‿･｀)(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)("
-                "　´･‿･｀)(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)(　´･‿･｀)";
-        auto multiplier = 5.67;
-        ParagraphStyle paragraphStyle;
-        paragraphStyle.setTextAlign(TextAlign::kLeft);
-        paragraphStyle.setMaxLines(10);
-        paragraphStyle.turnHintingOff();
-        TextStyle textStyle;
-        textStyle.setFontFamilies({SkString("Roboto")});
-        textStyle.setFontSize(5 * multiplier);
-        textStyle.setHeight(1.3f);
-        textStyle.setColor(SK_ColorBLACK);
-        textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
-                                           SkFontStyle::kUpright_Slant));
-
-        ParagraphBuilderImpl builder(paragraphStyle, fontCollection);
-        builder.pushStyle(textStyle);
-        builder.addText(text, strlen(text));
-        builder.pop();
-
-        auto paragraph = builder.Build();
-        paragraph->layout(200 * multiplier);
-
-        std::vector<size_t> sizes = {0, 1, 2, 8, 19, 21, 22, 30, 150};
-
-        std::vector<size_t> colors = {SK_ColorBLUE, SK_ColorCYAN,  SK_ColorLTGRAY, SK_ColorGREEN,
-                                      SK_ColorRED,  SK_ColorWHITE, SK_ColorYELLOW, SK_ColorMAGENTA};
-
-        RectHeightStyle rect_height_style = RectHeightStyle::kTight;
-        RectWidthStyle rect_width_style = RectWidthStyle::kTight;
-
-        for (size_t i = 0; i < sizes.size() - 1; ++i) {
-            size_t from = sizes[i];
-            size_t to = sizes[i + 1];
-            auto boxes = paragraph->getRectsForRange(from, to, rect_height_style, rect_width_style);
-            if (boxes.empty()) {
-                continue;
-            }
-            for (auto& box : boxes) {
-                SkPaint paint;
-                paint.setColor(colors[i % colors.size()]);
-                paint.setShader(setgrad(box.rect, colors[i % colors.size()], SK_ColorWHITE));
-                canvas->drawRect(box.rect, paint);
-            }
-        }
-
-        paragraph->paint(canvas, 0, 0);
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-
-        auto h = this->height();
-        auto w = this->width();
-
-        drawText(canvas, SK_ColorGRAY, w, h);
-    }
-
-private:
-    typedef Sample INHERITED;
-    SkScalar letterSpacing;
-    SkScalar wordSpacing;
-};
-
-class ParagraphView10 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph10"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-        auto multiplier = 5.67;
-        const char* text = "English English 字典 字典 😀😃😄 😀😃😄";
-
-        auto fontCollection = sk_make_sp<FontCollection>();
-        fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
-        fontCollection->enableFontFallback();
-
-        ParagraphStyle paragraph_style;
-        paragraph_style.turnHintingOff();
-        ParagraphBuilderImpl builder(paragraph_style, fontCollection);
-
-        TextStyle text_style;
-        text_style.setFontFamilies({SkString("Roboto"),
-                                    SkString("Noto Color Emoji"),
-                                    SkString("Noto Serif CJK JP")});
-        text_style.setFontSize(10 * multiplier);
-        text_style.setLetterSpacing(0);
-        text_style.setWordSpacing(0);
-        text_style.setColor(SK_ColorBLACK);
-        text_style.setHeight(1);
-        builder.pushStyle(text_style);
-        builder.addText(text, strlen(text));
-        builder.pop();
-
-        auto paragraph = builder.Build();
-        paragraph->layout(width());
-
-        paragraph->paint(canvas, 0, 0);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView11 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph11"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-
-        auto text = "\U0001f469\U0000200D\U0001f469\U0000200D\U0001f466\U0001f469\U0000200D\U0001f469\U0000200D\U0001f467\U0000200D\U0001f467\U0001f1fa\U0001f1f8";
-
-        TextStyle text_style;
-        text_style.setFontFamilies({SkString("Ahem")});
-        text_style.setColor(SK_ColorBLACK);
-        text_style.setFontSize(60);
-        text_style.setLetterSpacing(0);
-        text_style.setWordSpacing(0);
-        ParagraphStyle paragraph_style;
-        paragraph_style.setTextStyle(text_style);
-
-        auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), true, true);
-        ParagraphBuilderImpl builder(paragraph_style, fontCollection);
-        builder.addText(text, strlen(text));
-        auto paragraph = builder.Build();
-        paragraph->layout(1000);
-        paragraph->paint(canvas, 0, 0);
-
-        struct pair {
-            unsigned fX;
-            unsigned fY;
-        };
-
-        pair hit1[] =
-              {{ 0, 8},{1, 33}, {2, 34}, { 3, 19}, {4, 20},
-               { 5, 21}, { 6, 22 }, { 7, 23 }, {8, 24 }, { 9, 25},
-               { 10, 26}, { 11, 27}, {12, 28}, { 13, 21}, {14, 22 },
-               { 15, 23}, {16, 24}, {17, 21}, { 18, 22}, {19, 21},
-               { 20, 24}, { 21, 23}, };
-
-        pair miss[] =
-              {{ 0, 4},{1, 17}, {2, 18}, { 3, 11}, {4, 12},
-               { 5, 13}, { 6, 14 }, { 7, 15 }, {8, 16 }, { 9, 17},
-               { 10, 18}, { 11, 19}, {12, 20}, { 13, 17}, {14, 18 },
-               { 15, 19}, {16, 20}, {17, 19}, { 18, 20},
-               { 20, 22}, };
-
-        auto rects = paragraph->getRectsForRange(7, 9, RectHeightStyle::kTight, RectWidthStyle::kTight);
-        SkPaint paint;
-        paint.setColor(SK_ColorRED);
-        paint.setStyle(SkPaint::kStroke_Style);
-        paint.setAntiAlias(true);
-        paint.setStrokeWidth(1);
-        if (!rects.empty()) {
-            canvas->drawRect(rects[0].rect, paint);
-        }
-
-        for (auto& query : hit1) {
-            auto rects = paragraph->getRectsForRange(query.fX, query.fY, RectHeightStyle::kTight, RectWidthStyle::kTight);
-            if (rects.size() >= 1 && rects[0].rect.width() > 0) {
-            } else {
-                SkDebugf("+[%d:%d): Bad\n", query.fX, query.fY);
-            }
-        }
-
-        for (auto& query : miss) {
-            auto miss = paragraph->getRectsForRange(query.fX, query.fY, RectHeightStyle::kTight, RectWidthStyle::kTight);
-            if (miss.empty()) {
-            } else {
-                SkDebugf("-[%d:%d): Bad\n", query.fX, query.fY);
-            }
-        }
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView12 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph12"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-
-        const char* text = "Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges";
-        TextStyle text_style;
-        text_style.setFontFamilies({SkString("Ahem")});
-        text_style.setColor(SK_ColorBLACK);
-        text_style.setFontSize(16);
-        //text_style.setLetterSpacing(-0.41);
-        StrutStyle strut_style;
-        strut_style.setStrutEnabled(false);
-        ParagraphStyle paragraph_style;
-        paragraph_style.setStrutStyle(strut_style);
-        paragraph_style.setTextStyle(text_style);
-        ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
-        builder.addText(text);
-        auto paragraph = builder.Build();
-        paragraph->layout(1095.000000);
-        auto result = paragraph->getRectsForRange(65, 66, RectHeightStyle::kTight, RectWidthStyle::kTight);
-        paragraph->paint(canvas, 0, 0);
-
-        SkPaint paint;
-        paint.setColor(SK_ColorRED);
-        paint.setStyle(SkPaint::kStroke_Style);
-        paint.setAntiAlias(true);
-        paint.setStrokeWidth(1);
-        canvas->drawRect(result.front().rect, paint);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView14 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph14"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-        TextStyle text_style;
-        text_style.setFontFamilies({SkString("Ahem")});
-        text_style.setColor(SK_ColorBLACK);
-        text_style.setFontSize(25);
-        text_style.setDecoration((TextDecoration)(TextDecoration::kUnderline | TextDecoration::kOverline | TextDecoration::kLineThrough));
-        text_style.setDecorationColor(SK_ColorBLUE);
-        text_style.setDecorationStyle(TextDecorationStyle::kWavy);
-        text_style.setDecorationThicknessMultiplier(4.0f);
-        ParagraphStyle paragraph_style;
-        paragraph_style.setTextStyle(text_style);
-        paragraph_style.setTextDirection(TextDirection::kRtl);
-        ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
-        builder.pushStyle(text_style);
-        builder.addText("Hello, wor!\nabcd.");
-        auto paragraph = builder.Build();
-        paragraph->layout(300);
-        paragraph->paint(canvas, 0, 0);
-        SkPaint paint;
-        paint.setColor(SK_ColorRED);
-        paint.setStyle(SkPaint::kStroke_Style);
-        paint.setAntiAlias(true);
-        paint.setStrokeWidth(1);
-        canvas->drawRect(SkRect::MakeXYWH(0, 0, 300, 100), paint);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView15 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph15"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-
-        TextStyle text_style;
-        text_style.setFontFamilies({SkString("abc.ttf")});
-        text_style.setFontSize(50);
-
-        auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false);
-
-        fontCollection->addFontFromFile("abc/abc.ttf", "abc");
-        fontCollection->addFontFromFile("abc/abc+grave.ttf", "abc+grave");
-        fontCollection->addFontFromFile("abc/abc+agrave.ttf", "abc+agrave");
-
-        ParagraphStyle paragraph_style;
-        ParagraphBuilderImpl builder(paragraph_style, fontCollection);
-
-        text_style.setFontFamilies({SkString("abc"), SkString("abc+grave")});
-        text_style.setColor(SK_ColorBLUE);
-        builder.pushStyle(text_style);
-        builder.addText(u"a\u0300");
-        text_style.setColor(SK_ColorMAGENTA);
-        builder.pushStyle(text_style);
-        builder.addText(u"à");
-
-        text_style.setFontFamilies({SkString("abc"), SkString("abc+agrave")});
-
-        text_style.setColor(SK_ColorRED);
-        builder.pushStyle(text_style);
-        builder.addText(u"a\u0300");
-        text_style.setColor(SK_ColorGREEN);
-        builder.pushStyle(text_style);
-        builder.addText(u"à");
-
-        auto paragraph = builder.Build();
-        paragraph->layout(800);
-        paragraph->paint(canvas, 50, 50);
-
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView16 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph16"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-
-        const char* text = "content";
-
-        ParagraphStyle paragraph_style;
-        paragraph_style.setMaxLines(1);
-        paragraph_style.setEllipsis(u"\u2026");
-        //auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
-        auto fontCollection = sk_make_sp<FontCollection>();
-        fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
-        fontCollection->enableFontFallback();
-        ParagraphBuilderImpl builder(paragraph_style, fontCollection);
-
-        TextStyle text_style;
-        text_style.setFontFamilies({SkString(".SF Pro Text")});
-        text_style.setColor(SK_ColorBLACK);
-        text_style.setFontSize(17.0f * 99.0f);
-        text_style.setLetterSpacing(0.41f);
-        builder.pushStyle(text_style);
-        builder.addText(text);
-
-        auto paragraph = builder.Build();
-        paragraph->layout(800);
-        paragraph->paint(canvas, 0, 0);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView17 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph17"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-
-        auto fontCollection = sk_make_sp<FontCollection>();
-        fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
-        fontCollection->enableFontFallback();
-        auto navy = SkColorSetRGB(0, 0, 139);
-        auto ltgray = SkColorSetRGB(211, 211, 211);
-        auto multiplier = 5.67;
-
-        const char* text = ">Sͬ͑̀͐̈͒̈́̋̎ͮͩ̽̓ͬ̂̆̔͗́̓ͣͧ͊ͫ͛̉͌̐̑ͪ͗̚͝҉̴͉͢k̡̊̓ͫͭͩ͂͊ͨͪͬ̑ͫ̍̌̄͛̌̂̑̂̋̊̔ͫ͛̽̑ͨ̍ͭ̓̀ͪͪ̉͐͗̌̓̃̚͟͝҉̢͏̫̞̙͇͖̮͕̗̟͕͇͚̻͈̣̻̪͉̰̲̣̫ͅͅP̴̅̍͒̿͗͗̇ͩ̃͆͌̀̽͏̧̡͕͖̝̖̼̺̰̣̬͔͖͔̼͙̞̦̫͓̘͜a̸̴̸̴̢̢̨̨̫͍͓̥̼̭̼̻̤̯̙̤̻̠͚̍̌͋̂ͦͨ̽̇͌͌͆̀̽̎͒̄ͪ̐ͦ̈ͫ͐͗̓̚̚͜ͅr͐͐ͤͫ̐ͥ͂̈́̿́ͮ̃͗̓̏ͫ̀̿͏̸̵̧́͘̕͟͝͠͞͠҉̷̧͚͢͟a̓̽̎̄͗̔͛̄̐͊͛ͫ͂͌̂̂̈̈̓̔̅̅̄͊̉́ͪ̑̄͆ͬ̍͆ͭ͋̐ͬ͏̷̵̨̢̩̹̖͓̥̳̰͔̱̬͖̙͓̙͇̀̀̕͜͟͟͢͟͜͠͡g̨̅̇ͦ͋̂ͦͨͭ̓͐͆̏̂͛̉ͧ̑ͫ̐̒͛ͫ̍̒͛́̚҉̷̨̛̛̀͜͢͞҉̩̘̲͍͎̯̹̝̭̗̱͇͉̲̱͔̯̠̹̥̻͉̲̜̤̰̪̗̺̖̺r̷͌̓̇̅ͭ̀̐̃̃ͭ͑͗̉̈̇̈́ͥ̓ͣ́ͤ͂ͤ͂̏͌̆̚҉̴̸̧̢̢̛̫͉̦̥̤̙͈͉͈͉͓̙̗̟̳̜͈̗̺̟̠̠͖͓̖̪͕̠̕̕͝ͅả̸̴̡̡̧͠͞͡͞҉̛̕͟͏̷̘̪̱͈̲͉̞̠̞̪̫͎̲̬̖̀̀͟͝͞͞͠p̛͂̈͐̚͠҉̵̸̡̢̢̩̹͙̯͖̙̙̮̥̙͚̠͔̥̭̮̞̣̪̬̥̠̖̝̥̪͎́̀̕͜͡͡ͅͅh̵̷̵̡̛ͤ̂͌̐̓̐̋̋͊̒̆̽́̀̀̀͢͠͞͞҉̷̸̢̕҉͚̯͖̫̜̞̟̠̱͉̝̲̹̼͉̟͉̩̮͔̤͖̞̭̙̹̬ͅ<";
-
-        ParagraphStyle paragraph_style;
-        ParagraphBuilderImpl builder(paragraph_style, fontCollection);
-        SkPaint paint;
-        paint.setColor(ltgray);
-        TextStyle text_style;
-        text_style.setBackgroundColor(paint);
-        text_style.setColor(navy);
-        text_style.setFontFamilies({SkString("Roboto")});
-        text_style.setFontSize(20 * multiplier);
-        builder.pushStyle(text_style);
-        builder.addText(text);
-        auto paragraph = builder.Build();
-        paragraph->layout(10000);
-        paragraph->paint(canvas, 0, 0);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class Zalgo {
-    private:
-    std::u16string COMBINING_DOWN = u"\u0316\u0317\u0318\u0319\u031c\u031d\u031e\u031f\u0320\u0324\u0325\u0326\u0329\u032a\u032b\u032c\u032d\u032e\u032f\u0330\u0331\u0332\u0333\u0339\u033a\u033b\u033c\u0345\u0347\u0348\u0349\u034d\u034e\u0353\u0354\u0355\u0356\u0359\u035a\u0323";
-    std::u16string COMBINING_UP = u"\u030d\u030e\u0304\u0305\u033f\u0311\u0306\u0310\u0352\u0357\u0351\u0307\u0308\u030a\u0342\u0343\u0344\u034a\u034b\u034c\u0303\u0302\u030c\u0350\u0300\u0301\u030b\u030f\u0312\u0313\u0314\u033d\u0309\u0363\u0364\u0365\u0366\u0367\u0368\u0369\u036a\u036b\u036c\u036d\u036e\u035b\u0346\u031a";
-    std::u16string COMBINING_MIDDLE = u"\u0315\u031b\u0340\u0341\u0358\u0321\u0322\u0327\u0328\u0334\u0335\u0336\u034f\u035c\u035d\u035e\u035f\u0360\u0362\u0338\u0337\u0361\u0489";
-
-    std::u16string randomMarks(std::u16string& combiningMarks) {
-        std::u16string result;
-        auto num = std::rand() % (combiningMarks.size() / 1);
-        for (size_t i = 0; i < num; ++i) {
-            auto index = std::rand() % combiningMarks.size();
-            result += combiningMarks[index];
-        }
-        return result;
-    }
-
-public:
-    std::u16string zalgo(std::string victim) {
-        std::u16string result;
-        for (auto& c : victim) {
-            result += c;
-            result += randomMarks(COMBINING_UP);
-            result += randomMarks(COMBINING_MIDDLE);
-            result += randomMarks(COMBINING_DOWN);
-        }
-        return result;
-    }
-};
-
-class ParagraphView18 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph18"); }
-
-    bool onChar(SkUnichar uni) override {
-            switch (uni) {
-                case ' ':
-                    fLimit = 400;
-                    return true;
-                case 's':
-                    fLimit += 10;
-                    return true;
-                case 'f':
-                    if (fLimit > 10) {
-                        fLimit -= 10;
-                    }
-                    return true;
-                default:
-                    break;
-            }
-            return false;
-    }
-
-    bool onAnimate(double nanos) override {
-        if (++fIndex > fLimit) {
-            fRedraw = true;
-            fIndex = 0;
-        } else {
-            fRepeat = true;
-        }
-        return true;
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-
-        auto navy = SkColorSetRGB(0, 0, 139);
-        auto ltgray = SkColorSetRGB(211, 211, 211);
-
-        auto multiplier = 5.67;
-        auto fontCollection = sk_make_sp<FontCollection>();
-        fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
-        fontCollection->enableFontFallback();
-
-        ParagraphStyle paragraph_style;
-        TextStyle text_style;
-        text_style.setFontFamilies({SkString("Roboto")});
-        text_style.setFontSize(20 * multiplier);
-        text_style.setColor(navy);
-        SkPaint paint;
-        paint.setColor(ltgray);
-        text_style.setBackgroundColor(paint);
-
-        Zalgo zalgo;
-
-        if (fRedraw || fRepeat) {
-
-            if (fRedraw || fParagraph.get() == nullptr) {
-                ParagraphBuilderImpl builder(paragraph_style, fontCollection);
-                builder.pushStyle(text_style);
-                auto utf16text = zalgo.zalgo("SkParagraph");
-                icu::UnicodeString unicode((UChar*)utf16text.data(), SkToS32(utf16text.size()));
-                std::string str;
-                unicode.toUTF8String(str);
-                SkDebugf("Text:>%s<\n", str.data());
-                builder.addText(utf16text);
-                fParagraph = builder.Build();
-            }
-
-            auto impl = static_cast<ParagraphImpl*>(fParagraph.get());
-            impl->setState(InternalState::kUnknown);
-            fParagraph->layout(1000);
-            fParagraph->paint(canvas, 300, 200);
-
-            for (auto& run : impl->runs()) {
-                SkString fontFamily("unresolved");
-                if (run.font().getTypeface() != nullptr) {
-                    run.font().getTypeface()->getFamilyName(&fontFamily);
-                }
-                if (run.font().getTypeface() != nullptr) {
-                    for (size_t i = 0; i < run.size(); ++i) {
-                        auto glyph = run.glyphs().begin() + i;
-                        if (*glyph == 0) {
-                            SkDebugf("Run[%d] @pos=%d\n", run.index(), i);
-                            SkASSERT(false);
-                        }
-                    }
-                } else {
-                    SkDebugf("Run[%d]: %s\n", run.index(), fontFamily.c_str());
-                    SkASSERT(false);
-                }
-            }
-            fRedraw = false;
-            fRepeat = false;
-        }
-    }
-
-private:
-    bool fRedraw = true;
-    bool fRepeat = false;
-    size_t fIndex = 0;
-    size_t fLimit = 20;
-    std::unique_ptr<Paragraph> fParagraph;
-    typedef Sample INHERITED;
-};
-
-class ParagraphView19 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph19"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-
-        auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
-
-        const char* text = "World domination is such an ugly phrase - I prefer to call it world optimisation";
-        ParagraphStyle paragraph_style;
-        paragraph_style.setMaxLines(7);
-        paragraph_style.setEllipsis(u"\u2026");
-        ParagraphBuilderImpl builder(paragraph_style, fontCollection);
-        TextStyle text_style;
-        text_style.setColor(SK_ColorBLACK);
-        text_style.setFontFamilies({SkString("Roboto")});
-        text_style.setFontSize(40);
-        builder.pushStyle(text_style);
-        builder.addText(text);
-        auto paragraph = builder.Build();
-        paragraph->layout(this->width());
-
-        paragraph->paint(canvas, 0, 0);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-class ParagraphView20 : public ParagraphView_Base {
-protected:
-    SkString name() override { return SkString("Paragraph20"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawColor(SK_ColorWHITE);
-
-        auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
-
-        const char* text = "";
-        ParagraphStyle paragraph_style;
-        paragraph_style.setMaxLines(std::numeric_limits<size_t>::max());
-        //paragraph_style.setEllipsis(u"\u2026");
-        ParagraphBuilderImpl builder(paragraph_style, fontCollection);
-        TextStyle text_style;
-        text_style.setColor(SK_ColorBLACK);
-        text_style.setFontFamilies({SkString("Roboto")});
-        text_style.setFontSize(40);
-        builder.pushStyle(text_style);
-        builder.addText(text);
-        auto paragraph = builder.Build();
-        paragraph->layout(this->width());
-
-        paragraph->paint(canvas, 0, 0);
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE(return new ParagraphView1();)
-DEF_SAMPLE(return new ParagraphView2();)
-DEF_SAMPLE(return new ParagraphView3();)
-DEF_SAMPLE(return new ParagraphView4();)
-DEF_SAMPLE(return new ParagraphView5();)
-DEF_SAMPLE(return new ParagraphView6();)
-DEF_SAMPLE(return new ParagraphView7();)
-DEF_SAMPLE(return new ParagraphView8();)
-DEF_SAMPLE(return new ParagraphView9();)
-DEF_SAMPLE(return new ParagraphView10();)
-DEF_SAMPLE(return new ParagraphView11();)
-DEF_SAMPLE(return new ParagraphView12();)
-DEF_SAMPLE(return new ParagraphView14();)
-DEF_SAMPLE(return new ParagraphView15();)
-DEF_SAMPLE(return new ParagraphView16();)
-DEF_SAMPLE(return new ParagraphView17();)
-DEF_SAMPLE(return new ParagraphView18();)
-DEF_SAMPLE(return new ParagraphView19();)
-DEF_SAMPLE(return new ParagraphView20();)
diff --git a/third_party/skia/samplecode/SamplePatch.cpp b/third_party/skia/samplecode/SamplePatch.cpp
index 3fd7d3d..98dde31 100644
--- a/third_party/skia/samplecode/SamplePatch.cpp
+++ b/third_party/skia/samplecode/SamplePatch.cpp
@@ -34,7 +34,7 @@
     SkBitmap bm;
     decode_file(GetResourceAsData("images/dog.jpg"), &bm);
     *size = SkIPoint{bm.width(), bm.height()};
-    return bm.makeShader();
+    return bm.makeShader(SkSamplingOptions(SkFilterMode::kLinear));
 }
 
 static sk_sp<SkShader> make_shader1(const SkIPoint& size) {
@@ -241,7 +241,6 @@
 
         SkPaint paint;
         paint.setDither(true);
-        paint.setFilterQuality(kLow_SkFilterQuality);
 
         canvas->translate(DX, DY);
 
@@ -314,7 +313,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 }  // namespace
 DEF_SAMPLE( return new PatchView(); )
@@ -345,8 +344,7 @@
 
     int vertCount = pts.count();
     int indexCount = 0; // no texture
-    unsigned flags = SkVertices::kHasColors_BuilderFlag |
-                     SkVertices::kIsNonVolatile_BuilderFlag;
+    unsigned flags = SkVertices::kHasColors_BuilderFlag;
     SkVertices::Builder builder(SkVertices::kTriangleStrip_VertexMode,
                                 vertCount, indexCount, flags);
     memcpy(builder.positions(), pts.begin(), vertCount * sizeof(SkPoint));
@@ -416,7 +414,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 }  // namespace
 DEF_SAMPLE( return new PseudoInkView(); )
@@ -503,7 +501,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 }  // namespace
 DEF_SAMPLE( return new ManyStrokesView(); )
diff --git a/third_party/skia/samplecode/SamplePath.cpp b/third_party/skia/samplecode/SamplePath.cpp
index 478f6a0..ac725d9 100644
--- a/third_party/skia/samplecode/SamplePath.cpp
+++ b/third_party/skia/samplecode/SamplePath.cpp
@@ -11,7 +11,7 @@
 #include "include/core/SkColorPriv.h"
 #include "include/core/SkFont.h"
 #include "include/core/SkGraphics.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/core/SkRegion.h"
 #include "include/core/SkShader.h"
 #include "include/core/SkTime.h"
@@ -195,7 +195,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 DEF_SAMPLE( return new PathView; )
 
@@ -279,38 +279,29 @@
         canvas->drawPath(path, fSkeletonPaint);
     }
 
-    bool onClick(Click* click) override {
-        int32_t index;
-        if (click->fMeta.findS32("index", &index)) {
-            SkASSERT((unsigned)index < N);
-            fPts[index] = click->fCurr;
-            return true;
-        }
-        return false;
-    }
-
     Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
         const SkScalar tol = 4;
         const SkRect r = SkRect::MakeXYWH(x - tol, y - tol, tol * 2, tol * 2);
         for (int i = 0; i < N; ++i) {
             if (r.intersects(SkRect::MakeXYWH(fPts[i].fX, fPts[i].fY, 1, 1))) {
-                Click* click = new Click();
-                click->fMeta.setS32("index", i);
-                return click;
+                return new Click([this, i](Click* c) {
+                    fPts[i] = c->fCurr;
+                    return true;
+                });
             }
         }
         return nullptr;
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 DEF_SAMPLE( return new ArcToView; )
 
 /////////////
 
 class FatStroke : public Sample {
-    bool fClosed, fShowStroke, fShowHidden, fShowSkeleton;
+    bool fClosed, fShowStroke, fShowHidden, fShowSkeleton, fAsCurves = false;
     int  fJoinType, fCapType;
     float fWidth = 30;
     SkPaint fPtsPaint, fHiddenPaint, fSkeletonPaint, fStrokePaint;
@@ -366,6 +357,7 @@
                 case '4': this->toggle3(fJoinType); return true;
                 case '5': this->toggle3(fCapType); return true;
                 case '6': this->toggle(fClosed); return true;
+                case 'c': this->toggle(fAsCurves); return true;
                 case '-': fWidth -= 5; return true;
                 case '=': fWidth += 5; return true;
                 default: break;
@@ -375,8 +367,15 @@
 
     void makePath(SkPath* path) {
         path->moveTo(fPts[0]);
-        for (int i = 1; i < N; ++i) {
-            path->lineTo(fPts[i]);
+        if (fAsCurves) {
+            for (int i = 1; i < N-2; ++i) {
+                path->quadTo(fPts[i], (fPts[i+1] + fPts[i]) * 0.5f);
+            }
+            path->quadTo(fPts[N-2], fPts[N-1]);
+        } else {
+            for (int i = 1; i < N; ++i) {
+                path->lineTo(fPts[i]);
+            }
         }
         if (fClosed) {
             path->close();
@@ -407,31 +406,22 @@
         canvas->drawPoints(SkCanvas::kPoints_PointMode, N, fPts, fPtsPaint);
     }
 
-    bool onClick(Click* click) override {
-        int32_t index;
-        if (click->fMeta.findS32("index", &index)) {
-            SkASSERT((unsigned)index < N);
-            fPts[index] = click->fCurr;
-            return true;
-        }
-        return false;
-    }
-
     Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
         const SkScalar tol = 4;
         const SkRect r = SkRect::MakeXYWH(x - tol, y - tol, tol * 2, tol * 2);
         for (int i = 0; i < N; ++i) {
             if (r.intersects(SkRect::MakeXYWH(fPts[i].fX, fPts[i].fY, 1, 1))) {
-                Click* click = new Click();
-                click->fMeta.setS32("index", i);
-                return click;
+                return new Click([this, i](Click* c) {
+                    fPts[i] = c->fCurr;
+                    return true;
+                });
             }
         }
         return nullptr;
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 DEF_SAMPLE( return new FatStroke; )
 
@@ -524,31 +514,22 @@
         }
     }
 
-    bool onClick(Click* click) override {
-        int32_t index;
-        if (click->fMeta.findS32("index", &index)) {
-            SkASSERT((unsigned)index < N);
-            fPts[index] = click->fCurr;
-            return true;
-        }
-        return false;
-    }
-
     Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
         const SkScalar tol = 8;
         const SkRect r = SkRect::MakeXYWH(x - tol, y - tol, tol * 2, tol * 2);
         for (int i = 0; i < N; ++i) {
             if (r.intersects(SkRect::MakeXYWH(fPts[i].fX, fPts[i].fY, 1, 1))) {
-                Click* click = new Click();
-                click->fMeta.setS32("index", i);
-                return click;
+                return new Click([this, i](Click* c) {
+                    fPts[i] = c->fCurr;
+                    return true;
+                });
             }
         }
         return this->INHERITED::onFindClickHandler(x, y, modi);
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 DEF_SAMPLE( return new CubicCurve; )
 
@@ -581,6 +562,7 @@
     SkScalar fT = 0.5f;
     bool fShowSub = false;
     bool fShowFlatness = false;
+    bool fShowInnerQuads = false;
     SkScalar fScale = 0.75;
 
     CubicCurve2() {
@@ -603,18 +585,25 @@
                 case 'f': fShowFlatness = !fShowFlatness; break;
                 case '-': fT -= 1.0f / 32; break;
                 case '=': fT += 1.0f / 32; break;
+                case 'q': fShowInnerQuads = !fShowInnerQuads; break;
                 default: return false;
             }
             fT = std::min(1.0f, std::max(0.0f, fT));
             return true;
     }
 
+    static void Dot(SkCanvas* canvas, SkPoint p, SkScalar radius, SkColor c) {
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setColor(c);
+        canvas->drawCircle(p.fX, p.fY, radius, paint);
+    }
+
     void showFrame(SkCanvas* canvas, const SkPoint pts[], int count, const SkPaint& p) {
         SkPaint paint(p);
         SkPoint storage[3 + 2 + 1];
         SkPoint* tmp = storage;
         const SkPoint* prev = pts;
-        int n = count;
         for (int n = count; n > 0; --n) {
             for (int i = 0; i < n; ++i) {
                 canvas->drawLine(prev[i], prev[i+1], paint);
@@ -626,9 +615,9 @@
 
         paint.setColor(SK_ColorBLUE);
         paint.setStyle(SkPaint::kFill_Style);
-        n = tmp - storage;
+        int n = tmp - storage;
         for (int i = 0; i < n; ++i) {
-            canvas->drawCircle(storage[i].fX, storage[i].fY, 4, paint);
+            Dot(canvas, storage[i], 4, SK_ColorBLUE);
         }
     }
 
@@ -672,6 +661,33 @@
         // not sure we can get here
     }
 
+    void showInnerQuads(SkCanvas* canvas) {
+        auto draw_quad = [canvas](SkPoint a, SkPoint b, SkPoint c, SkColor color) {
+            SkPaint paint;
+            paint.setAntiAlias(true);
+            paint.setStroke(true);
+            paint.setColor(color);
+
+            canvas->drawPath(SkPathBuilder().moveTo(a).quadTo(b, c).detach(), paint);
+        };
+
+        SkPoint p0 = SkEvalQuadAt(&fPts[0], fT),
+                p1 = SkEvalQuadAt(&fPts[1], fT),
+                p2 = lerp(p0, p1, fT);
+
+        draw_quad(fPts[0], fPts[1], fPts[2], SK_ColorRED);
+        Dot(canvas, p0, 4, SK_ColorRED);
+
+        draw_quad(fPts[1], fPts[2], fPts[3], SK_ColorBLUE);
+        Dot(canvas, p1, 4, SK_ColorBLUE);
+
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setColor(0xFF008800);
+        canvas->drawLine(p0, p1, paint);
+        Dot(canvas, p2, 4, 0xFF00AA00);
+    }
+
     void onDrawContent(SkCanvas* canvas) override {
         SkPaint paint;
         paint.setAntiAlias(true);
@@ -702,13 +718,20 @@
             this->showFlattness(canvas);
         }
 
-        paint.setStyle(SkPaint::kFill_Style);
-        paint.setColor(SK_ColorRED);
-        for (SkPoint p : fPts) {
-            canvas->drawCircle(p.fX, p.fY, 7, paint);
+        if (fShowInnerQuads) {
+            this->showInnerQuads(canvas);
         }
 
-        {
+        paint.setColor(SK_ColorGRAY);
+        paint.setStroke(true);
+        canvas->drawPath(SkPathBuilder().addPolygon(fPts, 4, false).detach(), paint);
+        canvas->drawPath(SkPathBuilder().addPolygon(fQuad, 3, false).detach(), paint);
+
+        for (SkPoint p : fPts) {
+            Dot(canvas, p, 7, SK_ColorBLACK);
+        }
+
+        if ((false)) {
             SkScalar ts[2];
             int n = SkFindCubicInflections(fPts, ts);
             for (int i = 0; i < n; ++i) {
@@ -720,31 +743,22 @@
 
     }
 
-    bool onClick(Click* click) override {
-        int32_t index;
-        if (click->fMeta.findS32("index", &index)) {
-            SkASSERT((unsigned)index < N);
-            fPts[index] = click->fCurr;
-            return true;
-        }
-        return false;
-    }
-
     Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
         const SkScalar tol = 8;
         const SkRect r = SkRect::MakeXYWH(x - tol, y - tol, tol * 2, tol * 2);
         for (int i = 0; i < N; ++i) {
             if (r.intersects(SkRect::MakeXYWH(fPts[i].fX, fPts[i].fY, 1, 1))) {
-                Click* click = new Click();
-                click->fMeta.setS32("index", i);
-                return click;
+                return new Click([this, i](Click* c) {
+                    fPts[i] = c->fCurr;
+                    return true;
+                });
             }
         }
         return this->INHERITED::onFindClickHandler(x, y, modi);
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 DEF_SAMPLE( return new CubicCurve2; )
 
diff --git a/third_party/skia/samplecode/SamplePathClip.cpp b/third_party/skia/samplecode/SamplePathClip.cpp
index c7852ab..8db008d 100644
--- a/third_party/skia/samplecode/SamplePathClip.cpp
+++ b/third_party/skia/samplecode/SamplePathClip.cpp
@@ -53,16 +53,14 @@
     }
 
     Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override {
-        return new Click();
-    }
-
-    bool onClick(Click* click) override {
-        fCenter.set(click->fCurr.fX, click->fCurr.fY);
-        return false;
+        return new Click([&](Click* c) {
+            fCenter = c->fCurr;
+            return false;
+        });
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 DEF_SAMPLE( return new PathClipView; )
 
@@ -298,11 +296,11 @@
 
     bool onClick(Click* click) override {
         ((MyClick*)click)->handleMove();
-        return false;
+        return true;
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 DEF_SAMPLE( return new EdgeClipView; )
diff --git a/third_party/skia/samplecode/SamplePathEffects.cpp b/third_party/skia/samplecode/SamplePathEffects.cpp
index ccdc541..5ed3241 100644
--- a/third_party/skia/samplecode/SamplePathEffects.cpp
+++ b/third_party/skia/samplecode/SamplePathEffects.cpp
@@ -137,7 +137,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SamplePathOverstroke.cpp b/third_party/skia/samplecode/SamplePathOverstroke.cpp
index a01562b..9ebf1d4 100644
--- a/third_party/skia/samplecode/SamplePathOverstroke.cpp
+++ b/third_party/skia/samplecode/SamplePathOverstroke.cpp
@@ -191,7 +191,7 @@
     }
 
    private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SamplePathTessellators.cpp b/third_party/skia/samplecode/SamplePathTessellators.cpp
new file mode 100644
index 0000000..30f4383
--- /dev/null
+++ b/third_party/skia/samplecode/SamplePathTessellators.cpp
@@ -0,0 +1,367 @@
+/*
+ * Copyright 2019 Google LLC.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/core/SkCanvas.h"
+#include "samplecode/Sample.h"
+#include "src/core/SkPathPriv.h"
+
+#if SK_SUPPORT_GPU
+
+#include "src/core/SkCanvasPriv.h"
+#include "src/gpu/GrOpFlushState.h"
+#include "src/gpu/GrRecordingContextPriv.h"
+#include "src/gpu/ops/GrDrawOp.h"
+#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
+#include "src/gpu/ops/TessellationPathRenderer.h"
+#include "src/gpu/tessellate/AffineMatrix.h"
+#include "src/gpu/tessellate/MiddleOutPolygonTriangulator.h"
+#include "src/gpu/tessellate/PathCurveTessellator.h"
+#include "src/gpu/tessellate/PathWedgeTessellator.h"
+#include "src/gpu/tessellate/shaders/GrPathTessellationShader.h"
+#include "src/gpu/v1/SurfaceDrawContext_v1.h"
+
+namespace skgpu {
+
+namespace {
+
+enum class Mode {
+    kWedgeMiddleOut,
+    kCurveMiddleOut,
+    kWedgeTessellate,
+    kCurveTessellate
+};
+
+static const char* ModeName(Mode mode) {
+    switch (mode) {
+        case Mode::kWedgeMiddleOut:
+            return "MiddleOutShader (kWedges)";
+        case Mode::kCurveMiddleOut:
+            return "MiddleOutShader (kCurves)";
+        case Mode::kWedgeTessellate:
+            return "HardwareWedgeShader";
+        case Mode::kCurveTessellate:
+            return "HardwareCurveShader";
+    }
+    SkUNREACHABLE;
+}
+
+// Draws a path directly to the screen using a specific tessellator.
+class SamplePathTessellatorOp : public GrDrawOp {
+private:
+    DEFINE_OP_CLASS_ID
+
+    SamplePathTessellatorOp(const SkRect& drawBounds, const SkPath& path, const SkMatrix& m,
+                            GrPipeline::InputFlags pipelineFlags, Mode mode)
+            : GrDrawOp(ClassID())
+            , fPath(path)
+            , fMatrix(m)
+            , fPipelineFlags(pipelineFlags)
+            , fMode(mode) {
+        this->setBounds(drawBounds, HasAABloat::kNo, IsHairline::kNo);
+    }
+    const char* name() const override { return "SamplePathTessellatorOp"; }
+    void visitProxies(const GrVisitProxyFunc&) const override {}
+    FixedFunctionFlags fixedFunctionFlags() const override {
+        return FixedFunctionFlags::kUsesHWAA;
+    }
+    GrProcessorSet::Analysis finalize(const GrCaps& caps, const GrAppliedClip* clip,
+                                      GrClampType clampType) override {
+        SkPMColor4f color;
+        return fProcessors.finalize(SK_PMColor4fWHITE, GrProcessorAnalysisCoverage::kNone, clip,
+                                    nullptr, caps, clampType, &color);
+    }
+    void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*,
+                      const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override {}
+    void onPrepare(GrOpFlushState* flushState) override {
+        constexpr static SkPMColor4f kCyan = {0,1,1,1};
+        auto alloc = flushState->allocator();
+        const SkMatrix& shaderMatrix = SkMatrix::I();
+        const SkMatrix& pathMatrix = fMatrix;
+        const GrCaps& caps = flushState->caps();
+        const GrShaderCaps& shaderCaps = *caps.shaderCaps();
+        int numVerbsToGetMiddleOut = 0;
+        int numVerbsToGetTessellation = caps.minPathVerbsForHwTessellation();
+        auto pipeline = GrSimpleMeshDrawOpHelper::CreatePipeline(flushState, std::move(fProcessors),
+                                                                 fPipelineFlags);
+        int numVerbs;
+        bool needsInnerFan;
+        switch (fMode) {
+            case Mode::kWedgeMiddleOut:
+                fTessellator = PathWedgeTessellator::Make(alloc, shaderCaps.infinitySupport());
+                numVerbs = numVerbsToGetMiddleOut;
+                needsInnerFan = false;
+                break;
+            case Mode::kCurveMiddleOut:
+                fTessellator = PathCurveTessellator::Make(alloc,
+                                                          shaderCaps.infinitySupport());
+                numVerbs = numVerbsToGetMiddleOut;
+                needsInnerFan = true;
+                break;
+            case Mode::kWedgeTessellate:
+                fTessellator = PathWedgeTessellator::Make(alloc, shaderCaps.infinitySupport());
+                numVerbs = numVerbsToGetTessellation;
+                needsInnerFan = false;
+                break;
+            case Mode::kCurveTessellate:
+                fTessellator = PathCurveTessellator::Make(alloc,
+                                                          shaderCaps.infinitySupport());
+                numVerbs = numVerbsToGetTessellation;
+                needsInnerFan = true;
+                break;
+        }
+        auto* tessShader = GrPathTessellationShader::Make(alloc,
+                                                          shaderMatrix,
+                                                          kCyan,
+                                                          numVerbs,
+                                                          *pipeline,
+                                                          fTessellator->patchAttribs(),
+                                                          caps);
+        fProgram = GrTessellationShader::MakeProgram({alloc, flushState->writeView(),
+                                                     flushState->usesMSAASurface(),
+                                                     &flushState->dstProxyView(),
+                                                     flushState->renderPassBarriers(),
+                                                     GrLoadOp::kClear, &flushState->caps()},
+                                                     tessShader,
+                                                     pipeline,
+                                                     &GrUserStencilSettings::kUnused);
+
+
+        int patchPreallocCount = fTessellator->patchPreallocCount(fPath.countVerbs());
+        if (needsInnerFan) {
+            patchPreallocCount += fPath.countVerbs() - 1;
+        }
+        PatchWriter patchWriter(flushState,
+                                fTessellator,
+                                tessShader->maxTessellationSegments(*caps.shaderCaps()),
+                                patchPreallocCount);
+
+        if (needsInnerFan) {
+            // Write out inner fan triangles.
+            AffineMatrix m(pathMatrix);
+            for (PathMiddleOutFanIter it(fPath); !it.done();) {
+                for (auto [p0, p1, p2] : it.nextStack()) {
+                    auto [mp0, mp1] = m.map2Points(p0, p1);
+                    auto mp2 = m.map1Point(&p2);
+                    patchWriter.writeTriangle(mp0, mp1, mp2);
+                }
+            }
+        }
+
+        // Write out the curves.
+        fTessellator->writePatches(patchWriter, shaderMatrix, {pathMatrix, fPath, kCyan});
+
+        if (!tessShader->willUseTessellationShaders()) {
+            fTessellator->prepareFixedCountBuffers(flushState);
+        }
+
+    }
+    void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
+        flushState->bindPipeline(*fProgram, chainBounds);
+        fTessellator->draw(flushState, fProgram->geomProc().willUseTessellationShaders());
+    }
+
+    const SkPath fPath;
+    const SkMatrix fMatrix;
+    const GrPipeline::InputFlags fPipelineFlags;
+    const Mode fMode;
+    PathTessellator* fTessellator = nullptr;
+    GrProgramInfo* fProgram;
+    GrProcessorSet fProcessors{SkBlendMode::kSrcOver};
+
+    friend class GrOp;  // For ctor.
+};
+
+}  // namespace
+
+// This sample enables wireframe and visualizes the triangles generated by path tessellators.
+class SamplePathTessellators : public Sample {
+public:
+    SamplePathTessellators() {
+#if 0
+        // For viewing middle-out triangulations of the inner fan.
+        fPath.moveTo(1, 0);
+        int numSides = 32 * 3;
+        for (int i = 1; i < numSides; ++i) {
+            float theta = 2*3.1415926535897932384626433832785 * i / numSides;
+            fPath.lineTo(std::cos(theta), std::sin(theta));
+        }
+        fPath.transform(SkMatrix::Scale(200, 200));
+        fPath.transform(SkMatrix::Translate(300, 300));
+#else
+        fPath.moveTo(100, 500);
+        fPath.cubicTo(300, 400, -100, 300, 100, 200);
+        fPath.quadTo(250, 0, 400, 200);
+        fPath.conicTo(600, 350, 400, 500, fConicWeight);
+        fPath.close();
+#endif
+    }
+
+private:
+    void onDrawContent(SkCanvas*) override;
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override;
+    bool onClick(Sample::Click*) override;
+    bool onChar(SkUnichar) override;
+
+    SkString name() override { return SkString("PathTessellators"); }
+
+    SkPath fPath;
+    GrPipeline::InputFlags fPipelineFlags = GrPipeline::InputFlags::kWireframe;
+    Mode fMode = Mode::kWedgeMiddleOut;
+
+    float fConicWeight = .5;
+
+    class Click;
+};
+
+void SamplePathTessellators::onDrawContent(SkCanvas* canvas) {
+    canvas->clear(SK_ColorBLACK);
+
+    auto ctx = canvas->recordingContext();
+    auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(canvas);
+
+    SkString error;
+    if (!sdc || !ctx) {
+        error = "GPU Only.";
+    } else if (!skgpu::v1::TessellationPathRenderer::IsSupported(*ctx->priv().caps())) {
+        error = "TessellationPathRenderer not supported.";
+    } else if (fMode >= Mode::kWedgeTessellate &&
+               !ctx->priv().caps()->shaderCaps()->tessellationSupport()) {
+        error.printf("%s requires hardware tessellation support.", ModeName(fMode));
+    }
+    if (!error.isEmpty()) {
+        canvas->clear(SK_ColorRED);
+        SkFont font(nullptr, 20);
+        SkPaint captionPaint;
+        captionPaint.setColor(SK_ColorWHITE);
+        canvas->drawString(error.c_str(), 10, 30, font, captionPaint);
+        return;
+    }
+
+    sdc->addDrawOp(GrOp::Make<SamplePathTessellatorOp>(ctx,
+                                                       sdc->asRenderTargetProxy()->getBoundsRect(),
+                                                       fPath, canvas->getTotalMatrix(),
+                                                       fPipelineFlags, fMode));
+
+    // Draw the path points.
+    SkPaint pointsPaint;
+    pointsPaint.setColor(SK_ColorBLUE);
+    pointsPaint.setStrokeWidth(8);
+    SkPath devPath = fPath;
+    devPath.transform(canvas->getTotalMatrix());
+    {
+        SkAutoCanvasRestore acr(canvas, true);
+        canvas->setMatrix(SkMatrix::I());
+        SkString caption(ModeName(fMode));
+        caption.appendf(" (w=%g)", fConicWeight);
+        SkFont font(nullptr, 20);
+        SkPaint captionPaint;
+        captionPaint.setColor(SK_ColorWHITE);
+        canvas->drawString(caption, 10, 30, font, captionPaint);
+        canvas->drawPoints(SkCanvas::kPoints_PointMode, devPath.countPoints(),
+                           SkPathPriv::PointData(devPath), pointsPaint);
+    }
+}
+
+class SamplePathTessellators::Click : public Sample::Click {
+public:
+    Click(int ptIdx) : fPtIdx(ptIdx) {}
+
+    void doClick(SkPath* path) {
+        SkPoint pt = path->getPoint(fPtIdx);
+        SkPathPriv::UpdatePathPoint(path, fPtIdx, pt + fCurr - fPrev);
+    }
+
+private:
+    int fPtIdx;
+};
+
+Sample::Click* SamplePathTessellators::onFindClickHandler(SkScalar x, SkScalar y,
+                                                          skui::ModifierKey) {
+    const SkPoint* pts = SkPathPriv::PointData(fPath);
+    float fuzz = 30;
+    for (int i = 0; i < fPath.countPoints(); ++i) {
+        if (fabs(x - pts[i].x()) < fuzz && fabsf(y - pts[i].y()) < fuzz) {
+            return new Click(i);
+        }
+    }
+    return nullptr;
+}
+
+bool SamplePathTessellators::onClick(Sample::Click* click) {
+    Click* myClick = (Click*)click;
+    myClick->doClick(&fPath);
+    return true;
+}
+
+static SkPath update_weight(const SkPath& path, float w) {
+    SkPath path_;
+    for (auto [verb, pts, _] : SkPathPriv::Iterate(path)) {
+        switch (verb) {
+            case SkPathVerb::kMove:
+                path_.moveTo(pts[0]);
+                break;
+            case SkPathVerb::kLine:
+                path_.lineTo(pts[1]);
+                break;
+            case SkPathVerb::kQuad:
+                path_.quadTo(pts[1], pts[2]);
+                break;
+            case SkPathVerb::kCubic:
+                path_.cubicTo(pts[1], pts[2], pts[3]);
+                break;
+            case SkPathVerb::kConic:
+                path_.conicTo(pts[1], pts[2], (w != 1) ? w : .99f);
+                break;
+            case SkPathVerb::kClose:
+                break;
+        }
+    }
+    return path_;
+}
+
+bool SamplePathTessellators::onChar(SkUnichar unichar) {
+    switch (unichar) {
+        case 'w':
+            fPipelineFlags = (GrPipeline::InputFlags)(
+                    (int)fPipelineFlags ^ (int)GrPipeline::InputFlags::kWireframe);
+            return true;
+        case 'D': {
+            fPath.dump();
+            return true;
+        }
+        case '+':
+            fConicWeight *= 2;
+            fPath = update_weight(fPath, fConicWeight);
+            return true;
+        case '=':
+            fConicWeight *= 5/4.f;
+            fPath = update_weight(fPath, fConicWeight);
+            return true;
+        case '_':
+            fConicWeight *= .5f;
+            fPath = update_weight(fPath, fConicWeight);
+            return true;
+        case '-':
+            fConicWeight *= 4/5.f;
+            fPath = update_weight(fPath, fConicWeight);
+            return true;
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+            fMode = (Mode)(unichar - '1');
+            return true;
+    }
+    return false;
+}
+
+Sample* MakeTessellatedPathSample() { return new SamplePathTessellators; }
+static SampleRegistry gTessellatedPathSample(MakeTessellatedPathSample);
+
+}  // namespace skgpu
+
+#endif  // SK_SUPPORT_GPU
diff --git a/third_party/skia/samplecode/SamplePathText.cpp b/third_party/skia/samplecode/SamplePathText.cpp
index 0b8ef02..1f5cd82 100644
--- a/third_party/skia/samplecode/SamplePathText.cpp
+++ b/third_party/skia/samplecode/SamplePathText.cpp
@@ -10,7 +10,8 @@
 #include "include/core/SkPath.h"
 #include "include/utils/SkRandom.h"
 #include "samplecode/Sample.h"
-#include "src/core/SkStrike.h"
+#include "src/core/SkPathPriv.h"
+#include "src/core/SkScalerCache.h"
 #include "src/core/SkStrikeCache.h"
 #include "src/core/SkStrikeSpec.h"
 #include "src/core/SkTaskGroup.h"
@@ -29,18 +30,24 @@
         for (Glyph& glyph : fGlyphs) {
             glyph.reset(fRand, this->width(), this->height());
         }
+        fGlyphAnimator->reset(&fRand, this->width(), this->height());
     }
 
     void onOnceBeforeDraw() final {
         SkFont defaultFont;
         SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(defaultFont);
-        auto cache = strikeSpec.findOrCreateExclusiveStrike();
+        auto strike = strikeSpec.findOrCreateStrike();
+        SkArenaAlloc alloc(1 << 12); // This is a mock SkStrikeCache.
         SkPath glyphPaths[52];
         for (int i = 0; i < 52; ++i) {
             // I and l are rects on OS X ...
             char c = "aQCDEFGH7JKLMNOPBRZTUVWXYSAbcdefghijk1mnopqrstuvwxyz"[i];
             SkPackedGlyphID id(defaultFont.unicharToGlyph(c));
-            sk_ignore_unused_variable(cache->getScalerContext()->getPath(id, &glyphPaths[i]));
+            SkGlyph glyph = strike->getScalerContext()->makeGlyph(id, &alloc);
+            strike->getScalerContext()->getPath(glyph, &alloc);
+            if (glyph.path()) {
+                glyphPaths[i] = *glyph.path();
+            }
         }
 
         for (int i = 0; i < kNumPaths; ++i) {
@@ -48,43 +55,30 @@
             fGlyphs[i].init(fRand, p);
         }
 
-        this->INHERITED::onOnceBeforeDraw();
+        this->Sample::onOnceBeforeDraw();
         this->reset();
     }
-    void onSizeChange() final { this->INHERITED::onSizeChange(); this->reset(); }
+    void onSizeChange() final { this->Sample::onSizeChange(); this->reset(); }
 
     SkString name() override { return SkString(this->getName()); }
 
-    bool onChar(SkUnichar unichar) override {
-            if (unichar == 'X') {
-                fDoClip = !fDoClip;
-                return true;
-            }
-            return false;
+    bool onChar(SkUnichar) override;
+
+    bool onAnimate(double nanos) final {
+        return fGlyphAnimator->animate(nanos, this->width(), this->height());
     }
 
     void onDrawContent(SkCanvas* canvas) override {
         if (fDoClip) {
             SkPath deviceSpaceClipPath = fClipPath;
-            deviceSpaceClipPath.transform(SkMatrix::MakeScale(this->width(), this->height()));
+            deviceSpaceClipPath.transform(SkMatrix::Scale(this->width(), this->height()));
             canvas->save();
             canvas->clipPath(deviceSpaceClipPath, SkClipOp::kDifference, true);
             canvas->clear(SK_ColorBLACK);
             canvas->restore();
             canvas->clipPath(deviceSpaceClipPath, SkClipOp::kIntersect, true);
         }
-        this->drawGlyphs(canvas);
-    }
-
-    virtual void drawGlyphs(SkCanvas* canvas) {
-        for (Glyph& glyph : fGlyphs) {
-            SkAutoCanvasRestore acr(canvas, true);
-            canvas->translate(glyph.fPosition.x(), glyph.fPosition.y());
-            canvas->scale(glyph.fZoom, glyph.fZoom);
-            canvas->rotate(glyph.fSpin);
-            canvas->translate(-glyph.fMidpt.x(), -glyph.fMidpt.y());
-            canvas->drawPath(glyph.fPath, glyph.fPaint);
-        }
+        fGlyphAnimator->draw(canvas);
     }
 
 protected:
@@ -100,12 +94,36 @@
         SkPoint    fMidpt;
     };
 
-    Glyph      fGlyphs[kNumPaths];
-    SkRandom   fRand{25};
-    SkPath     fClipPath = ToolUtils::make_star(SkRect{0, 0, 1, 1}, 11, 3);
-    bool       fDoClip = false;
+    class GlyphAnimator {
+    public:
+        GlyphAnimator(Glyph* glyphs) : fGlyphs(glyphs) {}
+        virtual void reset(SkRandom*, int screenWidth, int screenHeight) {}
+        virtual bool animate(double nanos, int screenWidth, int screenHeight) { return false; }
+        virtual void draw(SkCanvas* canvas) {
+            for (int i = 0; i < kNumPaths; ++i) {
+                Glyph& glyph = fGlyphs[i];
+                SkAutoCanvasRestore acr(canvas, true);
+                canvas->translate(glyph.fPosition.x(), glyph.fPosition.y());
+                canvas->scale(glyph.fZoom, glyph.fZoom);
+                canvas->rotate(glyph.fSpin);
+                canvas->translate(-glyph.fMidpt.x(), -glyph.fMidpt.y());
+                canvas->drawPath(glyph.fPath, glyph.fPaint);
+            }
+        }
+        virtual ~GlyphAnimator() {}
 
-    typedef Sample INHERITED;
+    protected:
+        Glyph* const fGlyphs;
+    };
+
+    class MovingGlyphAnimator;
+    class WavyGlyphAnimator;
+
+    Glyph fGlyphs[kNumPaths];
+    SkRandom fRand{25};
+    SkPath fClipPath = ToolUtils::make_star(SkRect{0, 0, 1, 1}, 11, 3);
+    bool fDoClip = false;
+    std::unique_ptr<GlyphAnimator> fGlyphAnimator = std::make_unique<GlyphAnimator>(fGlyphs);
 };
 
 void PathText::Glyph::init(SkRandom& rand, const SkPath& path) {
@@ -115,62 +133,60 @@
 }
 
 void PathText::Glyph::reset(SkRandom& rand, int w, int h) {
-    int screensize = SkTMax(w, h);
+    int screensize = std::max(w, h);
     const SkRect& bounds = fPath.getBounds();
     SkScalar t;
 
     fPosition = {rand.nextF() * w, rand.nextF() * h};
     t = pow(rand.nextF(), 100);
     fZoom = ((1 - t) * screensize / 50 + t * screensize / 3) /
-            SkTMax(bounds.width(), bounds.height());
+            std::max(bounds.width(), bounds.height());
     fSpin = rand.nextF() * 360;
     fMidpt = {bounds.centerX(), bounds.centerY()};
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Text from paths with animated transformation matrices.
-class MovingPathText : public PathText {
+class PathText::MovingGlyphAnimator : public PathText::GlyphAnimator {
 public:
-    const char* getName() const override { return "MovingPathText"; }
-
-    MovingPathText()
-        : fFrontMatrices(kNumPaths)
-        , fBackMatrices(kNumPaths) {
+    MovingGlyphAnimator(Glyph* glyphs)
+            : GlyphAnimator(glyphs)
+            , fFrontMatrices(kNumPaths)
+            , fBackMatrices(kNumPaths) {
     }
 
-    ~MovingPathText() override {
+    ~MovingGlyphAnimator() override {
         fBackgroundAnimationTask.wait();
     }
 
-    void reset() override {
-        const SkScalar screensize = static_cast<SkScalar>(SkTMax(this->width(), this->height()));
-        this->INHERITED::reset();
+    void reset(SkRandom* rand, int screenWidth, int screenHeight) override {
+        const SkScalar screensize = static_cast<SkScalar>(std::max(screenWidth, screenHeight));
 
         for (auto& v : fVelocities) {
             for (SkScalar* d : {&v.fDx, &v.fDy}) {
-                SkScalar t = pow(fRand.nextF(), 3);
-                *d = ((1 - t) / 60 + t / 10) * (fRand.nextBool() ? screensize : -screensize);
+                SkScalar t = pow(rand->nextF(), 3);
+                *d = ((1 - t) / 60 + t / 10) * (rand->nextBool() ? screensize : -screensize);
             }
 
-            SkScalar t = pow(fRand.nextF(), 25);
-            v.fDSpin = ((1 - t) * 360 / 7.5 + t * 360 / 1.5) * (fRand.nextBool() ? 1 : -1);
+            SkScalar t = pow(rand->nextF(), 25);
+            v.fDSpin = ((1 - t) * 360 / 7.5 + t * 360 / 1.5) * (rand->nextBool() ? 1 : -1);
         }
 
         // Get valid front data.
         fBackgroundAnimationTask.wait();
-        this->runAnimationTask(0, 0, this->width(), this->height());
-        memcpy(fFrontMatrices, fBackMatrices, kNumPaths * sizeof(SkMatrix));
+        this->runAnimationTask(0, 0, screenWidth, screenHeight);
+        std::copy_n(fBackMatrices.get(), kNumPaths, fFrontMatrices.get());
         fLastTick = 0;
     }
 
-    bool onAnimate(double nanos) final {
+    bool animate(double nanos, int screenWidth, int screenHeight) final {
         fBackgroundAnimationTask.wait();
         this->swapAnimationBuffers();
 
         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()));
+        fBackgroundAnimationTask.add(std::bind(&MovingGlyphAnimator::runAnimationTask, this, tsec,
+                                               dt, screenWidth, screenHeight));
         fLastTick = 1e-9 * nanos;
         return true;
     }
@@ -215,7 +231,7 @@
         std::swap(fFrontMatrices, fBackMatrices);
     }
 
-    void drawGlyphs(SkCanvas* canvas) override {
+    void draw(SkCanvas* canvas) override {
         for (int i = 0; i < kNumPaths; ++i) {
             SkAutoCanvasRestore acr(canvas, true);
             canvas->concat(fFrontMatrices[i]);
@@ -229,42 +245,40 @@
         SkScalar fDSpin;
     };
 
-    Velocity                  fVelocities[kNumPaths];
-    SkAutoTMalloc<SkMatrix>   fFrontMatrices;
-    SkAutoTMalloc<SkMatrix>   fBackMatrices;
-    SkTaskGroup               fBackgroundAnimationTask;
-    double                    fLastTick;
-
-    typedef PathText INHERITED;
+    Velocity fVelocities[kNumPaths];
+    SkAutoTArray<SkMatrix> fFrontMatrices;
+    SkAutoTArray<SkMatrix> fBackMatrices;
+    SkTaskGroup fBackgroundAnimationTask;
+    double fLastTick;
 };
 
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Text from paths with animated control points.
-class WavyPathText : public MovingPathText {
+class PathText::WavyGlyphAnimator : public PathText::MovingGlyphAnimator {
 public:
-    const char* getName() const override { return "WavyPathText"; }
+    WavyGlyphAnimator(Glyph* glyphs)
+            : MovingGlyphAnimator(glyphs)
+            , fFrontPaths(kNumPaths)
+            , fBackPaths(kNumPaths) {
+    }
 
-    WavyPathText()
-        : fFrontPaths(kNumPaths)
-        , fBackPaths(kNumPaths) {}
-
-    ~WavyPathText() override {
+    ~WavyGlyphAnimator() override {
         fBackgroundAnimationTask.wait();
     }
 
-    void reset() override {
-        fWaves.reset(fRand, this->width(), this->height());
-        this->INHERITED::reset();
+    void reset(SkRandom* rand, int screenWidth, int screenHeight) override {
+        fWaves.reset(*rand, screenWidth, screenHeight);
+        this->MovingGlyphAnimator::reset(rand, screenWidth, screenHeight);
         std::copy(fBackPaths.get(), fBackPaths.get() + kNumPaths, fFrontPaths.get());
     }
 
     /**
      * Called on a background thread. Here we can only modify fBackPaths.
      */
-    void runAnimationTask(double t, double dt, int w, int h) override {
+    void runAnimationTask(double t, double dt, int width, int height) override {
         const float tsec = static_cast<float>(t);
-        this->INHERITED::runAnimationTask(t, 0.5 * dt, w, h);
+        this->MovingGlyphAnimator::runAnimationTask(t, 0.5 * dt, width, height);
 
         for (int i = 0; i < kNumPaths; ++i) {
             const Glyph& glyph = fGlyphs[i];
@@ -280,35 +294,30 @@
             backpath->reset();
             backpath->setFillType(SkPathFillType::kEvenOdd);
 
-            SkPath::RawIter iter(glyph.fPath);
-            SkPath::Verb verb;
-            SkPoint pts[4];
-
-            while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+            for (auto [verb, pts, w] : SkPathPriv::Iterate(glyph.fPath)) {
                 switch (verb) {
-                    case SkPath::kMove_Verb: {
+                    case SkPathVerb::kMove: {
                         SkPoint pt = fWaves.apply(tsec, matrix, pts[0]);
                         backpath->moveTo(pt.x(), pt.y());
                         break;
                     }
-                    case SkPath::kLine_Verb: {
+                    case SkPathVerb::kLine: {
                         SkPoint endpt = fWaves.apply(tsec, matrix, pts[1]);
                         backpath->lineTo(endpt.x(), endpt.y());
                         break;
                     }
-                    case SkPath::kQuad_Verb: {
+                    case SkPathVerb::kQuad: {
                         SkPoint controlPt = fWaves.apply(tsec, matrix, pts[1]);
                         SkPoint endpt = fWaves.apply(tsec, matrix, pts[2]);
                         backpath->quadTo(controlPt.x(), controlPt.y(), endpt.x(), endpt.y());
                         break;
                     }
-                    case SkPath::kClose_Verb: {
+                    case SkPathVerb::kClose: {
                         backpath->close();
                         break;
                     }
-                    case SkPath::kCubic_Verb:
-                    case SkPath::kConic_Verb:
-                    case SkPath::kDone_Verb:
+                    case SkPathVerb::kCubic:
+                    case SkPathVerb::kConic:
                         SK_ABORT("Unexpected path verb");
                         break;
                 }
@@ -317,11 +326,11 @@
     }
 
     void swapAnimationBuffers() override {
-        this->INHERITED::swapAnimationBuffers();
+        this->MovingGlyphAnimator::swapAnimationBuffers();
         std::swap(fFrontPaths, fBackPaths);
     }
 
-    void drawGlyphs(SkCanvas* canvas) override {
+    void draw(SkCanvas* canvas) override {
         for (int i = 0; i < kNumPaths; ++i) {
             canvas->drawPath(fFrontPaths[i], fGlyphs[i].fPaint);
         }
@@ -348,15 +357,13 @@
         float fOffsets[4];
     };
 
-    SkAutoTArray<SkPath>   fFrontPaths;
-    SkAutoTArray<SkPath>   fBackPaths;
-    Waves                  fWaves;
-
-    typedef MovingPathText INHERITED;
+    SkAutoTArray<SkPath> fFrontPaths;
+    SkAutoTArray<SkPath> fBackPaths;
+    Waves fWaves;
 };
 
-void WavyPathText::Waves::reset(SkRandom& rand, int w, int h) {
-    const double pixelsPerMeter = 0.06 * SkTMax(w, h);
+void PathText::WavyGlyphAnimator::Waves::reset(SkRandom& rand, int w, int h) {
+    const double pixelsPerMeter = 0.06 * std::max(w, h);
     const double medianWavelength = 8 * pixelsPerMeter;
     const double medianWaveAmplitude = 0.05 * 4 * pixelsPerMeter;
     const double gravity = 9.8 * pixelsPerMeter;
@@ -375,7 +382,8 @@
     }
 }
 
-SkPoint WavyPathText::Waves::apply(float tsec, const Sk2f matrix[3], const SkPoint& pt) const {
+SkPoint PathText::WavyGlyphAnimator::Waves::apply(float tsec, const Sk2f matrix[3],
+                                                  const SkPoint& pt) const {
     constexpr static int kTablePeriod = 1 << 12;
     static float sin2table[kTablePeriod + 1];
     static SkOnce initTable;
@@ -422,8 +430,28 @@
     return {devicePt[0] + offsetY[0] + offsetY[1], devicePt[1] - offsetX[0] - offsetX[1]};
 }
 
+bool PathText::onChar(SkUnichar unichar) {
+    switch (unichar) {
+        case 'X':
+            fDoClip = !fDoClip;
+            return true;
+        case 'S':
+            fGlyphAnimator = std::make_unique<GlyphAnimator>(fGlyphs);
+            fGlyphAnimator->reset(&fRand, this->width(), this->height());
+            return true;
+        case 'M':
+            fGlyphAnimator = std::make_unique<MovingGlyphAnimator>(fGlyphs);
+            fGlyphAnimator->reset(&fRand, this->width(), this->height());
+            return true;
+        case 'W':
+            fGlyphAnimator = std::make_unique<WavyGlyphAnimator>(fGlyphs);
+            fGlyphAnimator->reset(&fRand, this->width(), this->height());
+            return true;
+    }
+    return false;
+}
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
-DEF_SAMPLE( return new WavyPathText; )
-DEF_SAMPLE( return new MovingPathText; )
-DEF_SAMPLE( return new PathText; )
+Sample* MakePathTextSample() { return new PathText; }
+static SampleRegistry gPathTextSample(MakePathTextSample);
diff --git a/third_party/skia/samplecode/SamplePolyToPoly.cpp b/third_party/skia/samplecode/SamplePolyToPoly.cpp
index f8caf38..41af4a0 100644
--- a/third_party/skia/samplecode/SamplePolyToPoly.cpp
+++ b/third_party/skia/samplecode/SamplePolyToPoly.cpp
@@ -50,26 +50,24 @@
 
             (void) m2.setPolyToPoly((const SkPoint*)src1, (SkPoint*)dst1, 4);
 
-            {
-                const SkPoint src[] = {
-                    { SkIntToScalar(1), SkIntToScalar(0) },
-                    { SkIntToScalar(4), SkIntToScalar(7) },
-                    { SkIntToScalar(10), SkIntToScalar(2) }
-                };
-                const SkPoint dst[] = {
-                    { SkIntToScalar(4), SkIntToScalar(2) },
-                    { SkIntToScalar(45), SkIntToScalar(26) },
-                    { SkIntToScalar(32), SkIntToScalar(17) }
-                };
+            const SkPoint src2[] = {
+                { SkIntToScalar(1), SkIntToScalar(0) },
+                { SkIntToScalar(4), SkIntToScalar(7) },
+                { SkIntToScalar(10), SkIntToScalar(2) }
+            };
+            const SkPoint dst2[] = {
+                { SkIntToScalar(4), SkIntToScalar(2) },
+                { SkIntToScalar(45), SkIntToScalar(26) },
+                { SkIntToScalar(32), SkIntToScalar(17) }
+            };
 
-                SkMatrix m0;
-                m0.setPolyToPoly(src, dst, 3);
-            }
+            SkMatrix m0;
+            m0.setPolyToPoly(src2, dst2, 3);
         }
     }
 
 protected:
-    virtual SkString name() { return SkString("PolyToPolyView"); }
+    SkString name() override { return SkString("PolyToPolyView"); }
 
     static void doDraw(SkCanvas* canvas, SkPaint* paint, const SkFont& font, const int isrc[],
                        const int idst[], int count) {
@@ -105,7 +103,7 @@
         canvas->restore();
     }
 
-    virtual void onDrawContent(SkCanvas* canvas) {
+    void onDrawContent(SkCanvas* canvas) override {
         SkPaint paint;
         paint.setAntiAlias(true);
         paint.setStrokeWidth(SkIntToScalar(4));
@@ -147,7 +145,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleQuadStroker.cpp b/third_party/skia/samplecode/SampleQuadStroker.cpp
index 6b679e2..bd98ad7 100644
--- a/third_party/skia/samplecode/SampleQuadStroker.cpp
+++ b/third_party/skia/samplecode/SampleQuadStroker.cpp
@@ -28,6 +28,7 @@
 #include "include/utils/SkTextUtils.h"
 #include "samplecode/Sample.h"
 #include "src/core/SkGeometry.h"
+#include "src/core/SkPathPriv.h"
 #include "src/core/SkPointPriv.h"
 #include "src/core/SkStroke.h"
 #include "tools/ToolUtils.h"
@@ -42,18 +43,14 @@
 }
 
 static int getOnCurvePoints(const SkPath& path, SkPoint storage[]) {
-    SkPath::RawIter iter(path);
-    SkPoint pts[4];
-    SkPath::Verb verb;
-
     int count = 0;
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+    for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
         switch (verb) {
-            case SkPath::kMove_Verb:
-            case SkPath::kLine_Verb:
-            case SkPath::kQuad_Verb:
-            case SkPath::kConic_Verb:
-            case SkPath::kCubic_Verb:
+            case SkPathVerb::kMove:
+            case SkPathVerb::kLine:
+            case SkPathVerb::kQuad:
+            case SkPathVerb::kConic:
+            case SkPathVerb::kCubic:
                 storage[count++] = pts[0];
                 break;
             default:
@@ -64,25 +61,21 @@
 }
 
 static void getContourCounts(const SkPath& path, SkTArray<int>* contourCounts) {
-    SkPath::RawIter iter(path);
-    SkPoint pts[4];
-    SkPath::Verb verb;
-
     int count = 0;
-    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+    for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
         switch (verb) {
-            case SkPath::kMove_Verb:
-            case SkPath::kLine_Verb:
+            case SkPathVerb::kMove:
+            case SkPathVerb::kLine:
                 count += 1;
                 break;
-            case SkPath::kQuad_Verb:
-            case SkPath::kConic_Verb:
+            case SkPathVerb::kQuad:
+            case SkPathVerb::kConic:
                 count += 2;
                 break;
-            case SkPath::kCubic_Verb:
+            case SkPathVerb::kCubic:
                 count += 3;
                 break;
-            case SkPath::kClose_Verb:
+            case SkPathVerb::kClose:
                 contourCounts->push_back(count);
                 count = 0;
                 break;
@@ -218,7 +211,7 @@
                     fText = "";
                     break;
                 case '-':
-                    fTextSize = SkTMax(1.0f, fTextSize - 1);
+                    fTextSize = std::max(1.0f, fTextSize - 1);
                     break;
                 case '+':
                 case '=':
@@ -259,7 +252,7 @@
         SkCanvas* canvas = fMaxSurface->getCanvas();
         canvas->save();
         canvas->concat(fMatrix);
-        fMinSurface->draw(canvas, 0, 0, nullptr);
+        fMinSurface->draw(canvas, 0, 0);
         canvas->restore();
 
         SkPaint paint;
@@ -356,14 +349,14 @@
         for (SkScalar dist = 0; dist <= total; dist += delta) {
             ++ribs;
         }
-        SkPath::RawIter iter(path);
-        SkPoint pts[4];
-        if (SkPath::kMove_Verb != iter.next(pts)) {
+        const uint8_t* verbs = SkPathPriv::VerbData(path);
+        if (path.countVerbs() < 2 || SkPath::kMove_Verb != verbs[0]) {
             SkASSERT(0);
             return;
         }
-        SkPath::Verb verb = iter.next(pts);
+        auto verb = static_cast<SkPath::Verb>(verbs[1]);
         SkASSERT(SkPath::kLine_Verb <= verb && verb <= SkPath::kCubic_Verb);
+        const SkPoint* pts = SkPathPriv::PointData(path);
         SkPoint pos, tan;
         for (int index = 0; index < ribs; ++index) {
             SkScalar t = (SkScalar) index / ribs;
@@ -379,7 +372,7 @@
                     tan = SkEvalQuadTangentAt(pts, t);
                     break;
                 case SkPath::kConic_Verb: {
-                    SkConic conic(pts, iter.conicWeight());
+                    SkConic conic(pts, SkPathPriv::ConicWeightData(path)[0]);
                     pos = conic.evalAt(t);
                     tan = conic.evalTangentAt(t);
                     } break;
@@ -421,7 +414,7 @@
         if (drawText) {
             fMinSurface->getCanvas()->drawPath(path, paint);
             this->copyMinToMax();
-            fMaxSurface->draw(canvas, 0, 0, nullptr);
+            fMaxSurface->draw(canvas, 0, 0);
         }
         paint.setAntiAlias(true);
         paint.setStyle(SkPaint::kStroke_Style);
@@ -478,7 +471,7 @@
         paint.setStyle(SkPaint::kStroke_Style);
         paint.setStrokeWidth(width);
         SkPath path;
-        SkScalar maxSide = SkTMax(rect.width(), rect.height()) / 2;
+        SkScalar maxSide = std::max(rect.width(), rect.height()) / 2;
         SkPoint center = { rect.fLeft + maxSide, rect.fTop + maxSide };
         path.addCircle(center.fX, center.fY, maxSide);
         canvas->drawPath(path, paint);
@@ -721,8 +714,7 @@
         MyClick(int index) : fIndex(index) {}
     };
 
-    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
-                                              skui::ModifierKey modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
         for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); ++i) {
             if (hittest(fPts[i], x, y)) {
                 return new MyClick((int)i);
@@ -793,13 +785,13 @@
         }
 #ifdef SK_DEBUG
         else if (index == (int) SK_ARRAY_COUNT(fPts) + 3) {
-            gDebugStrokerError = SkTMax(FLT_EPSILON, MapScreenYtoValue(click->fCurr.fY,
+            gDebugStrokerError = std::max(FLT_EPSILON, MapScreenYtoValue(click->fCurr.fY,
                     fErrorControl, kStrokerErrorMin, kStrokerErrorMax));
             gDebugStrokerErrorSet = true;
         }
 #endif
         else if (index == (int) SK_ARRAY_COUNT(fPts) + 4) {
-            fWidth = SkTMax(FLT_EPSILON, MapScreenYtoValue(click->fCurr.fY, fWidthControl,
+            fWidth = std::max(FLT_EPSILON, MapScreenYtoValue(click->fCurr.fY, fWidthControl,
                     kWidthMin, kWidthMax));
             fAnimate = fWidth <= kWidthMin;
         }
@@ -807,7 +799,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleRectanizer.cpp b/third_party/skia/samplecode/SampleRectanizer.cpp
index c9faa78..2b81079 100644
--- a/third_party/skia/samplecode/SampleRectanizer.cpp
+++ b/third_party/skia/samplecode/SampleRectanizer.cpp
@@ -12,8 +12,8 @@
 #include "samplecode/Sample.h"
 #include "src/utils/SkUTF.h"
 #if SK_SUPPORT_GPU
-#include "src/gpu/GrRectanizer_pow2.h"
-#include "src/gpu/GrRectanizer_skyline.h"
+#include "src/gpu/GrRectanizerPow2.h"
+#include "src/gpu/GrRectanizerSkyline.h"
 
 // This slide visualizes the various GrRectanizer-derived classes behavior
 // for various input sets
@@ -180,7 +180,7 @@
         fCurRandRect = 0;
     }
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleRegion.cpp b/third_party/skia/samplecode/SampleRegion.cpp
deleted file mode 100644
index 7c16c01..0000000
--- a/third_party/skia/samplecode/SampleRegion.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkBitmap.h"
-#include "include/core/SkCanvas.h"
-#include "include/core/SkFont.h"
-#include "include/core/SkFontMetrics.h"
-#include "include/core/SkPath.h"
-#include "include/core/SkRegion.h"
-#include "include/core/SkShader.h"
-#include "include/effects/SkGradientShader.h"
-#include "samplecode/Sample.h"
-#include "src/utils/SkUTF.h"
-
-#include <math.h>
-
-static void test_strokerect(SkCanvas* canvas) {
-    int width = 100;
-    int height = 100;
-
-    SkBitmap bitmap;
-    bitmap.allocPixels(SkImageInfo::MakeA8(width*2, height*2));
-    bitmap.eraseColor(SK_ColorTRANSPARENT);
-
-    SkScalar dx = 20;
-    SkScalar dy = 20;
-
-    SkPath path;
-    path.addRect(0.0f, 0.0f,
-                 SkIntToScalar(width), SkIntToScalar(height),
-                 SkPathDirection::kCW);
-    SkRect r = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
-
-    SkCanvas c(bitmap);
-    c.translate(dx, dy);
-
-    SkPaint paint;
-    paint.setStyle(SkPaint::kStroke_Style);
-    paint.setStrokeWidth(1);
-
-    // use the rect
-    c.clear(SK_ColorTRANSPARENT);
-    c.drawRect(r, paint);
-    canvas->drawBitmap(bitmap, 0, 0, nullptr);
-
-    // use the path
-    c.clear(SK_ColorTRANSPARENT);
-    c.drawPath(path, paint);
-    canvas->drawBitmap(bitmap, SkIntToScalar(2*width), 0, nullptr);
-}
-
-static void drawFadingText(SkCanvas* canvas,
-                           const char* text, size_t len, SkScalar x, SkScalar y,
-                           const SkFont& font, const SkPaint& paint) {
-    // Need a bounds for the text
-    SkRect bounds;
-    SkFontMetrics fm;
-
-    font.getMetrics(&fm);
-    bounds.setLTRB(x, y + fm.fTop,
-                   x + font.measureText(text, len, SkTextEncoding::kUTF8), y + fm.fBottom);
-
-    // may need to outset bounds a little, to account for hinting and/or
-    // antialiasing
-    bounds.inset(-SkIntToScalar(2), -SkIntToScalar(2));
-
-    canvas->saveLayer(&bounds, nullptr);
-    canvas->drawSimpleText(text, len, SkTextEncoding::kUTF8, x, y, font, paint);
-
-    const SkPoint pts[] = {
-        { bounds.fLeft, y },
-        { bounds.fRight, y }
-    };
-    const SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, 0 };
-
-    // pos[1] value is where we start to fade, relative to the width
-    // of our pts[] array.
-    const SkScalar pos[] = { 0, 0.9f, SK_Scalar1 };
-
-    SkPaint p;
-    p.setShader(SkGradientShader::MakeLinear(pts, colors, pos, 3, SkTileMode::kClamp));
-    p.setBlendMode(SkBlendMode::kDstIn);
-    canvas->drawRect(bounds, p);
-
-    canvas->restore();
-}
-
-static void test_text(SkCanvas* canvas) {
-    SkPaint paint;
-    paint.setAntiAlias(true);
-
-    SkFont font;
-    font.setSize(20);
-
-    const char* str = "Hamburgefons";
-    size_t len = strlen(str);
-    SkScalar x = 20;
-    SkScalar y = 20;
-
-    canvas->drawSimpleText(str, len, SkTextEncoding::kUTF8, x, y, font, paint);
-
-    y += 20;
-
-    const SkPoint pts[] = { { x                                                    , y },
-                            { x + font.measureText(str, len, SkTextEncoding::kUTF8), y } };
-    const SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, 0 };
-    const SkScalar pos[] = { 0, 0.9f, 1 };
-    paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos,
-                                                 SK_ARRAY_COUNT(colors),
-                                                 SkTileMode::kClamp));
-    canvas->drawSimpleText(str, len, SkTextEncoding::kUTF8, x, y, font, paint);
-
-    y += 20;
-    paint.setShader(nullptr);
-    drawFadingText(canvas, str, len, x, y, font, paint);
-}
-
-static void scale_rect(SkIRect* dst, const SkIRect& src, float scale) {
-    dst->fLeft = (int)::roundf(src.fLeft * scale);
-    dst->fTop = (int)::roundf(src.fTop * scale);
-    dst->fRight = (int)::roundf(src.fRight * scale);
-    dst->fBottom = (int)::roundf(src.fBottom * scale);
-}
-
-static void scale_rgn(SkRegion* dst, const SkRegion& src, float scale) {
-    SkRegion tmp;
-    SkRegion::Iterator iter(src);
-
-    for (; !iter.done(); iter.next()) {
-        SkIRect r;
-        scale_rect(&r, iter.rect(), scale);
-        tmp.op(r, SkRegion::kUnion_Op);
-    }
-    dst->swap(tmp);
-}
-
-static void paint_rgn(SkCanvas* canvas, const SkRegion& rgn,
-                      const SkPaint& paint) {
-    SkRegion scaled;
-    scale_rgn(&scaled, rgn, 0.5f);
-
-    SkRegion::Iterator  iter(rgn);
-
-    for (; !iter.done(); iter.next())
-    {
-        SkRect    r;
-        r.set(iter.rect());
-        canvas->drawRect(r, paint);
-    }
-}
-
-class RegionView : public Sample {
-public:
-    RegionView() {
-        fBase.setLTRB(100, 100, 150, 150);
-        fRect = fBase;
-        fRect.inset(5, 5);
-        fRect.offset(25, 25);
-        this->setBGColor(0xFFDDDDDD);
-    }
-
-    void build_base_rgn(SkRegion* rgn) {
-        rgn->setRect(fBase);
-        SkIRect r = fBase;
-        r.offset(75, 20);
-        rgn->op(r, SkRegion::kUnion_Op);
-    }
-
-    void build_rgn(SkRegion* rgn, SkRegion::Op op) {
-        build_base_rgn(rgn);
-        rgn->op(fRect, op);
-    }
-
-
-protected:
-    SkString name() override { return SkString("Regions"); }
-
-    static void drawstr(SkCanvas* canvas, const char text[], const SkPoint& loc,
-                        bool hilite) {
-        SkPaint paint;
-        paint.setColor(hilite ? SK_ColorRED : 0x40FF0000);
-        SkFont font;
-        font.setSize(SkIntToScalar(20));
-        canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, loc.fX, loc.fY, font, paint);
-    }
-
-    void drawPredicates(SkCanvas* canvas, const SkPoint pts[]) {
-        SkRegion rgn;
-        build_base_rgn(&rgn);
-
-        drawstr(canvas, "Intersects", pts[0], rgn.intersects(fRect));
-        drawstr(canvas, "Contains", pts[1], rgn.contains(fRect));
-    }
-
-    void drawOrig(SkCanvas* canvas, bool bg) {
-        SkRect      r;
-        SkPaint     paint;
-
-        paint.setStyle(SkPaint::kStroke_Style);
-        if (bg)
-            paint.setColor(0xFFBBBBBB);
-
-        SkRegion rgn;
-        build_base_rgn(&rgn);
-        paint_rgn(canvas, rgn, paint);
-
-        r.set(fRect);
-        canvas->drawRect(r, paint);
-    }
-
-    void drawRgnOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
-        SkRegion    rgn;
-
-        this->build_rgn(&rgn, op);
-
-        {
-            SkRegion tmp, tmp2(rgn);
-
-            tmp = tmp2;
-            tmp.translate(5, -3);
-
-            {
-                char    buffer[1000];
-                SkDEBUGCODE(size_t  size = ) tmp.writeToMemory(nullptr);
-                SkASSERT(size <= sizeof(buffer));
-                SkDEBUGCODE(size_t  size2 = ) tmp.writeToMemory(buffer);
-                SkASSERT(size == size2);
-
-                SkRegion    tmp3;
-                SkDEBUGCODE(size2 = ) tmp3.readFromMemory(buffer, 1000);
-                SkASSERT(size == size2);
-
-                SkASSERT(tmp3 == tmp);
-            }
-
-            rgn.translate(20, 30, &tmp);
-            SkASSERT(rgn.isEmpty() || tmp != rgn);
-            tmp.translate(-20, -30);
-            SkASSERT(tmp == rgn);
-        }
-
-        this->drawOrig(canvas, true);
-
-        SkPaint paint;
-        paint.setColor((color & ~(0xFF << 24)) | (0x44 << 24));
-        paint_rgn(canvas, rgn, paint);
-
-        paint.setStyle(SkPaint::kStroke_Style);
-        paint.setColor(color);
-        paint_rgn(canvas, rgn, paint);
-    }
-
-    void drawPathOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
-        SkRegion    rgn;
-        SkPath      path;
-
-        this->build_rgn(&rgn, op);
-        rgn.getBoundaryPath(&path);
-
-        this->drawOrig(canvas, true);
-
-        SkPaint paint;
-
-        paint.setStyle(SkPaint::kFill_Style);
-        paint.setColor((color & ~(0xFF << 24)) | (0x44 << 24));
-        canvas->drawPath(path, paint);
-        paint.setColor(color);
-        paint.setStyle(SkPaint::kStroke_Style);
-        canvas->drawPath(path, paint);
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        if (false) { // avoid bit rot, suppress warning
-            test_strokerect(canvas);
-            return;
-        }
-        if (false) { // avoid bit rot, suppress warning
-            test_text(canvas);
-            return;
-        }
-
-        const SkPoint origins[] = {
-            { 30*SK_Scalar1, 50*SK_Scalar1 },
-            { 150*SK_Scalar1, 50*SK_Scalar1 },
-        };
-        this->drawPredicates(canvas, origins);
-
-        static const struct {
-            SkColor         fColor;
-            const char*     fName;
-            SkRegion::Op    fOp;
-        } gOps[] = {
-            { SK_ColorBLACK,    "Difference",   SkRegion::kDifference_Op    },
-            { SK_ColorRED,      "Intersect",    SkRegion::kIntersect_Op     },
-            { 0xFF008800,       "Union",        SkRegion::kUnion_Op         },
-            { SK_ColorBLUE,     "XOR",          SkRegion::kXOR_Op           }
-        };
-
-        SkFont font;
-        font.setSize(SK_Scalar1*24);
-
-        this->drawOrig(canvas, false);
-        canvas->save();
-            canvas->translate(SkIntToScalar(200), 0);
-            this->drawRgnOped(canvas, SkRegion::kUnion_Op, SK_ColorBLACK);
-        canvas->restore();
-
-        canvas->translate(0, SkIntToScalar(200));
-
-        for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) {
-            canvas->drawSimpleText(gOps[op].fName, strlen(gOps[op].fName), SkTextEncoding::kUTF8,
-                                   SkIntToScalar(75), SkIntToScalar(50), font, SkPaint());
-
-            this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor);
-
-            canvas->save();
-            canvas->translate(0, SkIntToScalar(200));
-            this->drawPathOped(canvas, gOps[op].fOp, gOps[op].fColor);
-            canvas->restore();
-
-            canvas->translate(SkIntToScalar(200), 0);
-        }
-    }
-
-    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
-                                              skui::ModifierKey modi) override {
-        return fRect.contains(SkScalarRoundToInt(x),
-                              SkScalarRoundToInt(y)) ? new Click() : nullptr;
-    }
-
-    bool onClick(Click* click) override {
-        fRect.offset(click->fCurr.fX - click->fPrev.fX,
-                     click->fCurr.fY - click->fPrev.fY);
-        return true;
-    }
-
-private:
-    SkIRect    fBase, fRect;
-
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new RegionView(); )
diff --git a/third_party/skia/samplecode/SampleRepeatTile.cpp b/third_party/skia/samplecode/SampleRepeatTile.cpp
index 3b7dea0..4022db6 100644
--- a/third_party/skia/samplecode/SampleRepeatTile.cpp
+++ b/third_party/skia/samplecode/SampleRepeatTile.cpp
@@ -35,7 +35,7 @@
     SkBitmap bm;
     make_bitmap(&bm);
 
-    paint->setShader(bm.makeShader(tm, tm));
+    paint->setShader(bm.makeShader(tm, tm, SkSamplingOptions()));
 }
 
 class RepeatTileView : public Sample {
@@ -57,7 +57,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleSG.cpp b/third_party/skia/samplecode/SampleSG.cpp
index bb2bf89..1fa8994 100644
--- a/third_party/skia/samplecode/SampleSG.cpp
+++ b/third_party/skia/samplecode/SampleSG.cpp
@@ -52,7 +52,7 @@
     SampleSG() {
         fGroup = sksg::Group::Make();
 
-        fScene = sksg::Scene::Make(fGroup, sksg::AnimatorList());
+        fScene = sksg::Scene::Make(fGroup);
 
         auto r = sksg::Rect::Make({20, 20, 400, 300});
         auto p = sksg::Color::Make(SK_ColorRED);
@@ -101,7 +101,7 @@
 
 private:
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleSVGFile.cpp b/third_party/skia/samplecode/SampleSVGFile.cpp
index 9fb62ed..b607d9a 100644
--- a/third_party/skia/samplecode/SampleSVGFile.cpp
+++ b/third_party/skia/samplecode/SampleSVGFile.cpp
@@ -7,11 +7,12 @@
 
 #include "include/core/SkTypes.h"
 
-#ifdef SK_XML
+#if defined(SK_ENABLE_SVG)
 
-#include "experimental/svg/model/SkSVGDOM.h"
 #include "include/core/SkCanvas.h"
 #include "include/core/SkStream.h"
+#include "modules/svg/include/SkSVGDOM.h"
+#include "modules/svg/include/SkSVGNode.h"
 #include "samplecode/Sample.h"
 #include "src/core/SkOSFile.h"
 #include "src/utils/SkOSPath.h"
@@ -29,17 +30,11 @@
     void onOnceBeforeDraw() override {
         SkFILEStream svgStream(fPath.c_str());
         if (!svgStream.isValid()) {
-            SkDebugf("file not found: \"path\"\n", fPath.c_str());
+            SkDebugf("file not found: \"%s\"\n", fPath.c_str());
             return;
         }
 
-        SkDOM xmlDom;
-        if (!xmlDom.build(svgStream)) {
-            SkDebugf("XML parsing failed: \"path\"\n", fPath.c_str());
-            return;
-        }
-
-        fDom = SkSVGDOM::MakeFromDOM(xmlDom);
+        fDom = SkSVGDOM::MakeFromStream(svgStream);
         if (fDom) {
             fDom->setContainerSize(SkSize::Make(this->width(), this->height()));
         }
@@ -66,7 +61,7 @@
     SkString        fPath;
     SkString        fLabel;
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 } // anonymous namespace
@@ -75,4 +70,4 @@
 Sample* CreateSampleSVGFileView(const SkString& filename) {
     return new SVGFileView(filename);
 }
-#endif  // SK_XML
+#endif  // defined(SK_ENABLE_SVG)
diff --git a/third_party/skia/samplecode/SampleShaders.cpp b/third_party/skia/samplecode/SampleShaders.cpp
deleted file mode 100644
index fb3fec9..0000000
--- a/third_party/skia/samplecode/SampleShaders.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkShader.h"
-#include "include/effects/SkGradientShader.h"
-#include "samplecode/DecodeFile.h"
-#include "samplecode/Sample.h"
-#include "tools/Resources.h"
-
-namespace {
-static sk_sp<SkShader> make_bitmapfade(const SkBitmap& bm) {
-    SkPoint pts[2] = {
-        {0, 0},
-        {0, (float)bm.height()},
-    };
-    SkColor colors[2] = {
-        SkColorSetARGB(255, 0, 0, 0),
-        SkColorSetARGB(0,   0, 0, 0),
-    };
-    return SkShaders::Blend(SkBlendMode::kDstIn,
-                            bm.makeShader(),
-                            SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
-                                                         SkTileMode::kClamp));
-}
-
-static sk_sp<SkShader> make_blend_shader() {
-    SkPoint pts[2];
-    SkColor colors[2];
-
-    pts[0].set(0, 0);
-    pts[1].set(SkIntToScalar(100), 0);
-    colors[0] = SK_ColorRED;
-    colors[1] = SK_ColorBLUE;
-    auto shaderA = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
-
-    pts[0].set(0, 0);
-    pts[1].set(0, SkIntToScalar(100));
-    colors[0] = SK_ColorBLACK;
-    colors[1] = SkColorSetARGB(0x80, 0, 0, 0);
-    auto shaderB = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
-
-    return SkShaders::Blend(SkBlendMode::kDstIn, std::move(shaderA), std::move(shaderB));
-}
-
-struct ShaderView : public Sample {
-    sk_sp<SkShader> fShader;
-    sk_sp<SkShader> fShaderFade;
-    SkBitmap        fBitmap;
-
-    void onOnceBeforeDraw() override {
-        decode_file(GetResourceAsData("images/dog.jpg"), &fBitmap);
-        fShader = make_blend_shader();
-        fShaderFade = make_bitmapfade(fBitmap);
-    }
-
-    SkString name() override { return SkString("Shaders"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        canvas->drawBitmap(fBitmap, 0, 0);
-        canvas->translate(20, 120);
-
-        SkPaint paint;
-        paint.setColor(SK_ColorGREEN);
-        canvas->drawRect(SkRect{0, 0, 100, 100}, paint);
-        paint.setShader(fShader);
-        canvas->drawRect(SkRect{0, 0, 100, 100}, paint);
-
-        canvas->translate(SkIntToScalar(110), 0);
-
-        paint.setShader(nullptr);
-        canvas->drawRect(SkRect{0, 0, 120, 80}, paint);
-        paint.setShader(fShaderFade);
-        canvas->drawRect(SkRect{0, 0, 120, 80}, paint);
-    }
-};
-}  // namespace
-DEF_SAMPLE( return new ShaderView(); )
diff --git a/third_party/skia/samplecode/SampleShadowColor.cpp b/third_party/skia/samplecode/SampleShadowColor.cpp
index e0dd7fe..7313bda 100644
--- a/third_party/skia/samplecode/SampleShadowColor.cpp
+++ b/third_party/skia/samplecode/SampleShadowColor.cpp
@@ -74,11 +74,11 @@
                     handled = true;
                     break;
                 case '>':
-                    fZIndex = SkTMin(9, fZIndex+1);
+                    fZIndex = std::min(9, fZIndex+1);
                     handled = true;
                     break;
                 case '<':
-                    fZIndex = SkTMax(0, fZIndex-1);
+                    fZIndex = std::max(0, fZIndex-1);
                     handled = true;
                     break;
                 default:
@@ -115,9 +115,9 @@
             if (paint.getColor() != SK_ColorBLACK) {
                 SkColor color = paint.getColor();
 
-                uint8_t max = SkTMax(SkTMax(SkColorGetR(color), SkColorGetG(color)),
+                uint8_t max = std::max(std::max(SkColorGetR(color), SkColorGetG(color)),
                                      SkColorGetB(color));
-                uint8_t min = SkTMin(SkTMin(SkColorGetR(color), SkColorGetG(color)),
+                uint8_t min = std::min(std::min(SkColorGetR(color), SkColorGetG(color)),
                                      SkColorGetB(color));
                 SkScalar luminance = 0.5f*(max + min) / 255.f;
                 SkScalar alpha = (.6 - .4*luminance)*luminance*luminance + 0.3f;
@@ -221,7 +221,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleShadowReference.cpp b/third_party/skia/samplecode/SampleShadowReference.cpp
index db8e9db..76439fb 100644
--- a/third_party/skia/samplecode/SampleShadowReference.cpp
+++ b/third_party/skia/samplecode/SampleShadowReference.cpp
@@ -191,7 +191,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleShadowUtils.cpp b/third_party/skia/samplecode/SampleShadowUtils.cpp
index 86151c1..e313875 100644
--- a/third_party/skia/samplecode/SampleShadowUtils.cpp
+++ b/third_party/skia/samplecode/SampleShadowUtils.cpp
@@ -9,7 +9,6 @@
 #include "include/core/SkColorFilter.h"
 #include "include/core/SkPath.h"
 #include "include/core/SkPoint3.h"
-#include "include/effects/SkBlurMaskFilter.h"
 #include "include/pathops/SkPathOps.h"
 #include "include/utils/SkCamera.h"
 #include "include/utils/SkShadowUtils.h"
@@ -172,13 +171,11 @@
         SkScalar dy = 0;
         SkTDArray<SkMatrix> matrices;
         matrices.push()->reset();
-        SkMatrix* m = matrices.push();
-        m->setRotate(33.f, 25.f, 25.f);
-        m->postScale(1.2f, 0.8f, 25.f, 25.f);
-        SkPaint paint;
-        paint.setColor(SK_ColorGREEN);
-        paint.setAntiAlias(true);
-        SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, SkTMax(1.0f, kHeight + fZDelta));
+        matrices.push()->setRotate(33.f, 25.f, 25.f).postScale(1.2f, 0.8f, 25.f, 25.f);
+        SkPaint greenPaint;
+        greenPaint.setColor(SK_ColorGREEN);
+        greenPaint.setAntiAlias(true);
+        SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, std::max(1.0f, kHeight + fZDelta));
 
         // convex paths
         for (auto& m : matrices) {
@@ -198,13 +195,13 @@
 
                     canvas->save();
                     canvas->concat(m);
-                    this->drawShadowedPath(canvas, path, zPlaneParams, paint, kAmbientAlpha,
+                    this->drawShadowedPath(canvas, path, zPlaneParams, greenPaint, kAmbientAlpha,
                                            lightPos, kLightR, kSpotAlpha, flags);
                     canvas->restore();
 
                     canvas->translate(dx, 0);
                     x += dx;
-                    dy = SkTMax(dy, postMBounds.height() + kPad + kHeight);
+                    dy = std::max(dy, postMBounds.height() + kPad + kHeight);
                 }
             }
         }
@@ -224,13 +221,13 @@
 
                 canvas->save();
                 canvas->concat(m);
-                this->drawShadowedPath(canvas, path, zPlaneParams, paint, kAmbientAlpha, lightPos,
-                                       kLightR, kSpotAlpha, kNone_ShadowFlag);
+                this->drawShadowedPath(canvas, path, zPlaneParams, greenPaint, kAmbientAlpha,
+                                       lightPos, kLightR, kSpotAlpha, kNone_ShadowFlag);
                 canvas->restore();
 
                 canvas->translate(dx, 0);
                 x += dx;
-                dy = SkTMax(dy, postMBounds.height() + kPad + kHeight);
+                dy = std::max(dy, postMBounds.height() + kPad + kHeight);
             }
         }
 
@@ -239,16 +236,16 @@
         if (invCanvasM.invert(&invCanvasM)) {
             canvas->save();
             canvas->concat(invCanvasM);
-            SkPaint paint;
-            paint.setColor(SK_ColorBLACK);
-            paint.setAntiAlias(true);
-            canvas->drawCircle(lightPos.fX, lightPos.fY, kLightR / 10.f, paint);
+            SkPaint blackPaint;
+            blackPaint.setColor(SK_ColorBLACK);
+            blackPaint.setAntiAlias(true);
+            canvas->drawCircle(lightPos.fX, lightPos.fY, kLightR / 10.f, blackPaint);
             canvas->restore();
         }
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleShip.cpp b/third_party/skia/samplecode/SampleShip.cpp
index 8fdc9eb..a20f8b2 100644
--- a/third_party/skia/samplecode/SampleShip.cpp
+++ b/third_party/skia/samplecode/SampleShip.cpp
@@ -10,6 +10,7 @@
 #include "include/core/SkRSXform.h"
 #include "include/core/SkSurface.h"
 #include "samplecode/Sample.h"
+#include "src/core/SkPaintPriv.h"
 #include "tools/Resources.h"
 #include "tools/timer/Timer.h"
 
@@ -20,25 +21,26 @@
 static const int kHeight = 640;
 
 typedef void (*DrawAtlasProc)(SkCanvas*, SkImage*, const SkRSXform[], const SkRect[],
-const SkColor[], int, const SkRect*, const SkPaint*);
+const SkColor[], int, const SkRect*, const SkSamplingOptions&, const SkPaint*);
 
 static void draw_atlas(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
                        const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
-                       const SkPaint* paint) {
-    canvas->drawAtlas(atlas, xform, tex, colors, count, SkBlendMode::kModulate, cull, paint);
+                       const SkSamplingOptions& sampling, const SkPaint* paint) {
+    canvas->drawAtlas(atlas, xform, tex, colors, count, SkBlendMode::kModulate, sampling,
+                      cull, paint);
 }
 
 static void draw_atlas_sim(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
                            const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
-                           const SkPaint* paint) {
+                           const SkSamplingOptions& sampling, const SkPaint* paint) {
     for (int i = 0; i < count; ++i) {
         SkMatrix matrix;
         matrix.setRSXform(xform[i]);
 
         canvas->save();
         canvas->concat(matrix);
-        canvas->drawImageRect(atlas, tex[i], tex[i].makeOffset(-tex[i].x(), -tex[i].y()), paint,
-                              SkCanvas::kFast_SrcRectConstraint);
+        canvas->drawImageRect(atlas, tex[i], tex[i].makeOffset(-tex[i].x(), -tex[i].y()),
+                              sampling, paint, SkCanvas::kFast_SrcRectConstraint);
         canvas->restore();
     }
 }
@@ -96,7 +98,6 @@
         }
 
         SkPaint paint;
-        paint.setFilterQuality(kLow_SkFilterQuality);
         paint.setColor(SK_ColorWHITE);
 
         SkScalar anchorX = fAtlas->width()*0.5f;
@@ -117,7 +118,8 @@
             fXform[i].fTy += dy;
         }
 
-        fProc(canvas, fAtlas.get(), fXform, fTex, nullptr, kGrid*kGrid+1, nullptr, &paint);
+        fProc(canvas, fAtlas.get(), fXform, fTex, nullptr, kGrid*kGrid+1, nullptr,
+              SkSamplingOptions(SkFilterMode::kLinear), &paint);
     }
 
     bool onAnimate(double nanos) override {
@@ -135,7 +137,7 @@
     SkRSXform   fXform[kGrid*kGrid+1];
     SkRect      fTex[kGrid*kGrid+1];
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleSimpleStroker.cpp b/third_party/skia/samplecode/SampleSimpleStroker.cpp
new file mode 100644
index 0000000..651d2ed
--- /dev/null
+++ b/third_party/skia/samplecode/SampleSimpleStroker.cpp
@@ -0,0 +1,482 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/core/SkBitmap.h"
+#include "include/core/SkCanvas.h"
+#include "include/core/SkPath.h"
+#include "include/utils/SkParsePath.h"
+#include "samplecode/Sample.h"
+
+#include "src/core/SkGeometry.h"
+
+namespace {
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkPoint rotate90(const SkPoint& p) { return {p.fY, -p.fX}; }
+static SkPoint rotate180(const SkPoint& p) { return p * -1; }
+static SkPoint setLength(SkPoint p, float len) {
+    if (!p.setLength(len)) {
+        SkDebugf("Failed to set point length\n");
+    }
+    return p;
+}
+static bool isClockwise(const SkPoint& a, const SkPoint& b) { return a.cross(b) > 0; }
+
+//////////////////////////////////////////////////////////////////////////////
+// Testing ground for a new stroker implementation
+
+/** Helper class for constructing paths, with undo support */
+class PathRecorder {
+public:
+    SkPath getPath() const {
+        return SkPath::Make(fPoints.data(), fPoints.size(), fVerbs.data(), fVerbs.size(), nullptr,
+                            0, SkPathFillType::kWinding);
+    }
+
+    void moveTo(SkPoint p) {
+        fVerbs.push_back(SkPath::kMove_Verb);
+        fPoints.push_back(p);
+    }
+
+    void lineTo(SkPoint p) {
+        fVerbs.push_back(SkPath::kLine_Verb);
+        fPoints.push_back(p);
+    }
+
+    void close() { fVerbs.push_back(SkPath::kClose_Verb); }
+
+    void rewind() {
+        fVerbs.clear();
+        fPoints.clear();
+    }
+
+    int countPoints() const { return fPoints.size(); }
+
+    int countVerbs() const { return fVerbs.size(); }
+
+    bool getLastPt(SkPoint* lastPt) const {
+        if (fPoints.empty()) {
+            return false;
+        }
+        *lastPt = fPoints.back();
+        return true;
+    }
+
+    void setLastPt(SkPoint lastPt) {
+        if (fPoints.empty()) {
+            moveTo(lastPt);
+        } else {
+            fPoints.back().set(lastPt.fX, lastPt.fY);
+        }
+    }
+
+    const std::vector<uint8_t>& verbs() const { return fVerbs; }
+
+    const std::vector<SkPoint>& points() const { return fPoints; }
+
+private:
+    std::vector<uint8_t> fVerbs;
+    std::vector<SkPoint> fPoints;
+};
+
+class SkPathStroker2 {
+public:
+    // Returns the fill path
+    SkPath getFillPath(const SkPath& path, const SkPaint& paint);
+
+private:
+    struct PathSegment {
+        SkPath::Verb fVerb;
+        SkPoint fPoints[4];
+    };
+
+    float fRadius;
+    SkPaint::Cap fCap;
+    SkPaint::Join fJoin;
+    PathRecorder fInner, fOuter;
+
+    // Initialize stroker state
+    void initForPath(const SkPath& path, const SkPaint& paint);
+
+    // Strokes a line segment
+    void strokeLine(const PathSegment& line, bool needsMove);
+
+    // Adds an endcap to fOuter
+    enum class CapLocation { Start, End };
+    void endcap(CapLocation loc);
+
+    // Adds a join between the two segments
+    void join(const PathSegment& prev, const PathSegment& curr);
+
+    // Appends path in reverse to result
+    static void appendPathReversed(const PathRecorder& path, PathRecorder* result);
+
+    // Returns the segment unit normal
+    static SkPoint unitNormal(const PathSegment& seg, float t);
+
+    // Returns squared magnitude of line segments.
+    static float squaredLineLength(const PathSegment& lineSeg);
+};
+
+void SkPathStroker2::initForPath(const SkPath& path, const SkPaint& paint) {
+    fRadius = paint.getStrokeWidth() / 2;
+    fCap = paint.getStrokeCap();
+    fJoin = paint.getStrokeJoin();
+    fInner.rewind();
+    fOuter.rewind();
+}
+
+SkPath SkPathStroker2::getFillPath(const SkPath& path, const SkPaint& paint) {
+    initForPath(path, paint);
+
+    // Trace the inner and outer paths simultaneously. Inner will therefore be
+    // recorded in reverse from how we trace the outline.
+    SkPath::Iter it(path, false);
+    PathSegment segment, prevSegment;
+    bool firstSegment = true;
+    while ((segment.fVerb = it.next(segment.fPoints)) != SkPath::kDone_Verb) {
+        // Join to the previous segment
+        if (!firstSegment) {
+            join(prevSegment, segment);
+        }
+
+        // Stroke the current segment
+        switch (segment.fVerb) {
+            case SkPath::kLine_Verb:
+                strokeLine(segment, firstSegment);
+                break;
+            case SkPath::kMove_Verb:
+                // Don't care about multiple contours currently
+                continue;
+            default:
+                SkDebugf("Unhandled path verb %d\n", segment.fVerb);
+                break;
+        }
+
+        std::swap(segment, prevSegment);
+        firstSegment = false;
+    }
+
+    // Open contour => endcap at the end
+    const bool isClosed = path.isLastContourClosed();
+    if (isClosed) {
+        SkDebugf("Unhandled closed contour\n");
+    } else {
+        endcap(CapLocation::End);
+    }
+
+    // Walk inner path in reverse, appending to result
+    appendPathReversed(fInner, &fOuter);
+    endcap(CapLocation::Start);
+
+    return fOuter.getPath();
+}
+
+void SkPathStroker2::strokeLine(const PathSegment& line, bool needsMove) {
+    const SkPoint tangent = line.fPoints[1] - line.fPoints[0];
+    const SkPoint normal = rotate90(tangent);
+    const SkPoint offset = setLength(normal, fRadius);
+    if (needsMove) {
+        fOuter.moveTo(line.fPoints[0] + offset);
+        fInner.moveTo(line.fPoints[0] - offset);
+    }
+    fOuter.lineTo(line.fPoints[1] + offset);
+    fInner.lineTo(line.fPoints[1] - offset);
+}
+
+void SkPathStroker2::endcap(CapLocation loc) {
+    const auto buttCap = [this](CapLocation loc) {
+        if (loc == CapLocation::Start) {
+            // Back at the start of the path: just close the stroked outline
+            fOuter.close();
+        } else {
+            // Inner last pt == first pt when appending in reverse
+            SkPoint innerLastPt;
+            fInner.getLastPt(&innerLastPt);
+            fOuter.lineTo(innerLastPt);
+        }
+    };
+
+    switch (fCap) {
+        case SkPaint::kButt_Cap:
+            buttCap(loc);
+            break;
+        default:
+            SkDebugf("Unhandled endcap %d\n", fCap);
+            buttCap(loc);
+            break;
+    }
+}
+
+void SkPathStroker2::join(const PathSegment& prev, const PathSegment& curr) {
+    const auto miterJoin = [this](const PathSegment& prev, const PathSegment& curr) {
+        // Common path endpoint of the two segments is the midpoint of the miter line.
+        const SkPoint miterMidpt = curr.fPoints[0];
+
+        SkPoint before = unitNormal(prev, 1);
+        SkPoint after = unitNormal(curr, 0);
+
+        // Check who's inside and who's outside.
+        PathRecorder *outer = &fOuter, *inner = &fInner;
+        if (!isClockwise(before, after)) {
+            std::swap(inner, outer);
+            before = rotate180(before);
+            after = rotate180(after);
+        }
+
+        const float cosTheta = before.dot(after);
+        if (SkScalarNearlyZero(1 - cosTheta)) {
+            // Nearly identical normals: don't bother.
+            return;
+        }
+
+        // Before and after have the same origin and magnitude, so before+after is the diagonal of
+        // their rhombus. Origin of this vector is the midpoint of the miter line.
+        SkPoint miterVec = before + after;
+
+        // Note the relationship (draw a right triangle with the miter line as its hypoteneuse):
+        //     sin(theta/2) = strokeWidth / miterLength
+        // so miterLength = strokeWidth / sin(theta/2)
+        // where miterLength is the length of the miter from outer point to inner corner.
+        // miterVec's origin is the midpoint of the miter line, so we use strokeWidth/2.
+        // Sqrt is just an application of half-angle identities.
+        const float sinHalfTheta = sqrtf(0.5 * (1 + cosTheta));
+        const float halfMiterLength = fRadius / sinHalfTheta;
+        miterVec.setLength(halfMiterLength);  // TODO: miter length limit
+
+        // Outer: connect to the miter point, and then to t=0 (on outside stroke) of next segment.
+        const SkPoint dest = setLength(after, fRadius);
+        outer->lineTo(miterMidpt + miterVec);
+        outer->lineTo(miterMidpt + dest);
+
+        // Inner miter is more involved. We're already at t=1 (on inside stroke) of 'prev'.
+        // Check 2 cases to see we can directly connect to the inner miter point
+        // (midpoint - miterVec), or if we need to add extra "loop" geometry.
+        const SkPoint prevUnitTangent = rotate90(before);
+        const float radiusSquared = fRadius * fRadius;
+        // 'alpha' is angle between prev tangent and the curr inwards normal
+        const float cosAlpha = prevUnitTangent.dot(-after);
+        // Solve triangle for len^2:  radius^2 = len^2 + (radius * sin(alpha))^2
+        // This is the point at which the inside "corner" of curr at t=0 will lie on a
+        // line connecting the inner and outer corners of prev at t=0. If len is below
+        // this threshold, the inside corner of curr will "poke through" the start of prev,
+        // and we'll need the inner loop geometry.
+        const float threshold1 = radiusSquared * cosAlpha * cosAlpha;
+        // Solve triangle for len^2:  halfMiterLen^2 = radius^2 + len^2
+        // This is the point at which the inner miter point will lie on the inner stroke
+        // boundary of the curr segment. If len is below this threshold, the miter point
+        // moves 'inside' of the stroked outline, and we'll need the inner loop geometry.
+        const float threshold2 = halfMiterLength * halfMiterLength - radiusSquared;
+        // If a segment length is smaller than the larger of the two thresholds,
+        // we'll have to add the inner loop geometry.
+        const float maxLenSqd = std::max(threshold1, threshold2);
+        const bool needsInnerLoop =
+                squaredLineLength(prev) < maxLenSqd || squaredLineLength(curr) < maxLenSqd;
+        if (needsInnerLoop) {
+            // Connect to the miter midpoint (common path endpoint of the two segments),
+            // and then to t=0 (on inside) of the next segment. This adds an interior "loop" of
+            // geometry that handles edge cases where segment lengths are shorter than the
+            // stroke width.
+            inner->lineTo(miterMidpt);
+            inner->lineTo(miterMidpt - dest);
+        } else {
+            // Directly connect to inner miter point.
+            inner->setLastPt(miterMidpt - miterVec);
+        }
+    };
+
+    switch (fJoin) {
+        case SkPaint::kMiter_Join:
+            miterJoin(prev, curr);
+            break;
+        default:
+            SkDebugf("Unhandled join %d\n", fJoin);
+            miterJoin(prev, curr);
+            break;
+    }
+}
+
+void SkPathStroker2::appendPathReversed(const PathRecorder& path, PathRecorder* result) {
+    const int numVerbs = path.countVerbs();
+    const int numPoints = path.countPoints();
+    const std::vector<uint8_t>& verbs = path.verbs();
+    const std::vector<SkPoint>& points = path.points();
+
+    for (int i = numVerbs - 1, j = numPoints; i >= 0; i--) {
+        auto verb = static_cast<SkPath::Verb>(verbs[i]);
+        switch (verb) {
+            case SkPath::kLine_Verb: {
+                j -= 1;
+                SkASSERT(j >= 1);
+                result->lineTo(points[j - 1]);
+                break;
+            }
+            case SkPath::kMove_Verb:
+                // Ignore
+                break;
+            default:
+                SkASSERT(false);
+                break;
+        }
+    }
+}
+
+SkPoint SkPathStroker2::unitNormal(const PathSegment& seg, float t) {
+    if (seg.fVerb != SkPath::kLine_Verb) {
+        SkDebugf("Unhandled verb for unit normal %d\n", seg.fVerb);
+    }
+
+    (void)t;  // Not needed for lines
+    const SkPoint tangent = seg.fPoints[1] - seg.fPoints[0];
+    const SkPoint normal = rotate90(tangent);
+    return setLength(normal, 1);
+}
+
+float SkPathStroker2::squaredLineLength(const PathSegment& lineSeg) {
+    SkASSERT(lineSeg.fVerb == SkPath::kLine_Verb);
+    const SkPoint diff = lineSeg.fPoints[1] - lineSeg.fPoints[0];
+    return diff.dot(diff);
+}
+
+}  // namespace
+
+//////////////////////////////////////////////////////////////////////////////
+
+class SimpleStroker : public Sample {
+    bool fShowSkiaStroke, fShowHidden, fShowSkeleton;
+    float fWidth = 175;
+    SkPaint fPtsPaint, fStrokePaint, fMirrorStrokePaint, fNewFillPaint, fHiddenPaint,
+            fSkeletonPaint;
+    inline static constexpr int kN = 3;
+
+public:
+    SkPoint fPts[kN];
+
+    SimpleStroker() : fShowSkiaStroke(true), fShowHidden(true), fShowSkeleton(true) {
+        fPts[0] = {500, 200};
+        fPts[1] = {300, 200};
+        fPts[2] = {100, 100};
+
+        fPtsPaint.setAntiAlias(true);
+        fPtsPaint.setStrokeWidth(10);
+        fPtsPaint.setStrokeCap(SkPaint::kRound_Cap);
+
+        fStrokePaint.setAntiAlias(true);
+        fStrokePaint.setStyle(SkPaint::kStroke_Style);
+        fStrokePaint.setColor(0x80FF0000);
+
+        fMirrorStrokePaint.setAntiAlias(true);
+        fMirrorStrokePaint.setStyle(SkPaint::kStroke_Style);
+        fMirrorStrokePaint.setColor(0x80FFFF00);
+
+        fNewFillPaint.setAntiAlias(true);
+        fNewFillPaint.setColor(0x8000FF00);
+
+        fHiddenPaint.setAntiAlias(true);
+        fHiddenPaint.setStyle(SkPaint::kStroke_Style);
+        fHiddenPaint.setColor(0xFF0000FF);
+
+        fSkeletonPaint.setAntiAlias(true);
+        fSkeletonPaint.setStyle(SkPaint::kStroke_Style);
+        fSkeletonPaint.setColor(SK_ColorRED);
+    }
+
+    void toggle(bool& value) { value = !value; }
+
+protected:
+    SkString name() override { return SkString("SimpleStroker"); }
+
+    bool onChar(SkUnichar uni) override {
+        switch (uni) {
+            case '1':
+                this->toggle(fShowSkeleton);
+                return true;
+            case '2':
+                this->toggle(fShowSkiaStroke);
+                return true;
+            case '3':
+                this->toggle(fShowHidden);
+                return true;
+            case '-':
+                fWidth -= 5;
+                return true;
+            case '=':
+                fWidth += 5;
+                return true;
+            default:
+                break;
+        }
+        return false;
+    }
+
+    void makePath(SkPath* path) {
+        path->moveTo(fPts[0]);
+        for (int i = 1; i < kN; ++i) {
+            path->lineTo(fPts[i]);
+        }
+    }
+
+    void onDrawContent(SkCanvas* canvas) override {
+        canvas->drawColor(0xFFEEEEEE);
+
+        SkPath path;
+        this->makePath(&path);
+
+        fStrokePaint.setStrokeWidth(fWidth);
+
+        // The correct result
+        if (fShowSkiaStroke) {
+            canvas->drawPath(path, fStrokePaint);
+        }
+
+        // Simple stroker result
+        SkPathStroker2 stroker;
+        SkPath fillPath = stroker.getFillPath(path, fStrokePaint);
+        canvas->drawPath(fillPath, fNewFillPaint);
+
+        if (fShowHidden) {
+            canvas->drawPath(fillPath, fHiddenPaint);
+        }
+        if (fShowSkeleton) {
+            canvas->drawPath(path, fSkeletonPaint);
+        }
+        canvas->drawPoints(SkCanvas::kPoints_PointMode, kN, fPts, fPtsPaint);
+
+        // Draw a mirror but using Skia's stroker.
+        canvas->translate(0, 400);
+        fMirrorStrokePaint.setStrokeWidth(fWidth);
+        canvas->drawPath(path, fMirrorStrokePaint);
+        if (fShowHidden) {
+            SkPath hidden;
+            fStrokePaint.getFillPath(path, &hidden);
+            canvas->drawPath(hidden, fHiddenPaint);
+        }
+        if (fShowSkeleton) {
+            canvas->drawPath(path, fSkeletonPaint);
+        }
+    }
+
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
+        const SkScalar tol = 4;
+        const SkRect r = SkRect::MakeXYWH(x - tol, y - tol, tol * 2, tol * 2);
+        for (int i = 0; i < kN; ++i) {
+            if (r.intersects(SkRect::MakeXYWH(fPts[i].fX, fPts[i].fY, 1, 1))) {
+                return new Click([this, i](Click* c) {
+                    fPts[i] = c->fCurr;
+                    return true;
+                });
+            }
+        }
+        return nullptr;
+    }
+
+private:
+    using INHERITED = Sample;
+};
+
+DEF_SAMPLE(return new SimpleStroker;)
diff --git a/third_party/skia/samplecode/SampleSlides.cpp b/third_party/skia/samplecode/SampleSlides.cpp
index d58f4f1..a17a674 100644
--- a/third_party/skia/samplecode/SampleSlides.cpp
+++ b/third_party/skia/samplecode/SampleSlides.cpp
@@ -7,7 +7,6 @@
 #include "include/core/SkCanvas.h"
 #include "include/core/SkPaint.h"
 #include "include/core/SkVertices.h"
-#include "include/effects/SkBlurMaskFilter.h"
 #include "include/effects/SkGradientShader.h"
 #include "samplecode/Sample.h"
 #include "src/core/SkBlurMask.h"
@@ -246,7 +245,7 @@
 
     decode_file("/skimages/logo.gif", &bm);
     size->set(bm.width(), bm.height());
-    return bm.makeShader();
+    return bm.makeShader(SkSamplingOptions(SkFilterMode::kLinear));
 }
 
 static sk_sp<SkShader> make_shader1(const SkIPoint& size) {
@@ -363,7 +362,6 @@
 
     SkPaint paint;
     paint.setDither(true);
-    paint.setFilterQuality(kLow_SkFilterQuality);
 
     for (size_t i = 0; i < SK_ARRAY_COUNT(fRecs); i++) {
         auto verts = SkVertices::MakeCopy(fRecs[i].fMode, fRecs[i].fCount,
@@ -429,7 +427,7 @@
             gProc[i](&canvas);
             canvas.restore();
             SkString str;
-            str.printf("/skimages/slide_" SK_SIZE_T_SPECIFIER ".png", i);
+            str.printf("/skimages/slide_%zu.png", i);
             ToolUtils::EncodeImageToFile(str.c_str(), bm, SkEncodedImageFormat::kPNG, 100);
         }
         this->setBGColor(BG_COLOR);
@@ -450,7 +448,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleStringArt.cpp b/third_party/skia/samplecode/SampleStringArt.cpp
index bda466c..9f2b3b1 100644
--- a/third_party/skia/samplecode/SampleStringArt.cpp
+++ b/third_party/skia/samplecode/SampleStringArt.cpp
@@ -32,7 +32,7 @@
         SkPath path;
         path.moveTo(center);
 
-        while (length < (SkScalarHalf(SkMinScalar(this->width(), this->height())) - 10.f))
+        while (length < (SkScalarHalf(std::min(this->width(), this->height())) - 10.f))
         {
             SkPoint rp = SkPoint::Make(length*SkScalarCos(step) + center.fX,
                                        length*SkScalarSin(step) + center.fY);
@@ -57,7 +57,7 @@
 private:
 
     SkScalar fAngle;
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleStrokePath.cpp b/third_party/skia/samplecode/SampleStrokePath.cpp
index b22ba8d..5feb87c 100644
--- a/third_party/skia/samplecode/SampleStrokePath.cpp
+++ b/third_party/skia/samplecode/SampleStrokePath.cpp
@@ -35,9 +35,7 @@
     paint.setStrokeJoin(SkPaint::kRound_Join);
     paint.setStyle(SkPaint::kStroke_Style);
 
-    SkMatrix matrix;
-    matrix.setRectToRect(srcR, dstR, SkMatrix::kCenter_ScaleToFit);
-    canvas->concat(matrix);
+    canvas->concat(SkMatrix::RectToRect(srcR, dstR, SkMatrix::kCenter_ScaleToFit));
 
     canvas->drawPath(path, paint);
 }
@@ -140,7 +138,8 @@
     }
 
     void onDrawContent(SkCanvas* canvas) override {
-        test_huge_stroke(canvas); return;
+        test_huge_stroke(canvas);
+#if 0
         canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
 
         SkPaint paint;
@@ -198,10 +197,11 @@
         canvas->translate(0, fPath.getBounds().height() * 5 / 4);
         fPath.setFillType(SkPathFillType::kEvenOdd);
         drawSet(canvas, &paint);
+#endif
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleStrokeRect.cpp b/third_party/skia/samplecode/SampleStrokeRect.cpp
index 669a357..d4cc4ae 100644
--- a/third_party/skia/samplecode/SampleStrokeRect.cpp
+++ b/third_party/skia/samplecode/SampleStrokeRect.cpp
@@ -13,9 +13,9 @@
     StrokeRectSample() {}
 
 protected:
-    virtual SkString name() { return SkString("Stroke Rects"); }
+    SkString name() override { return SkString("Stroke Rects"); }
 
-    virtual void onDrawContent(SkCanvas* canvas) {
+    void onDrawContent(SkCanvas* canvas) override {
         SkPaint paint;
         paint.setAntiAlias(true);
         paint.setStyle(SkPaint::kStroke_Style);
@@ -56,7 +56,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleStrokeVerb.cpp b/third_party/skia/samplecode/SampleStrokeVerb.cpp
new file mode 100644
index 0000000..bb90ee3
--- /dev/null
+++ b/third_party/skia/samplecode/SampleStrokeVerb.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/core/SkTypes.h"
+
+#if SK_SUPPORT_GPU
+
+#include "include/core/SkCanvas.h"
+#include "include/core/SkFont.h"
+#include "include/core/SkPaint.h"
+#include "include/core/SkPath.h"
+#include "samplecode/Sample.h"
+#include "src/core/SkGeometry.h"
+
+enum class VerbType {
+    kTriangles,
+    kQuadratics,
+    kCubics,
+    kConics
+};
+
+static const char* verb_type_name(VerbType verbType) {
+    switch (verbType) {
+        case VerbType::kTriangles: return "kTriangles";
+        case VerbType::kQuadratics: return "kQuadratics";
+        case VerbType::kCubics: return "kCubics";
+        case VerbType::kConics: return "kConics";
+    }
+    SkUNREACHABLE;
+};
+
+/**
+ * This sample visualizes simple strokes.
+ */
+class StrokeVerbView : public Sample {
+    void onOnceBeforeDraw() override { this->updatePath(); }
+    void onDrawContent(SkCanvas*) override;
+
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override;
+    bool onClick(Sample::Click*) override;
+    bool onChar(SkUnichar) override;
+    SkString name() override { return SkString("StrokeVerb"); }
+
+    class Click;
+
+    void updateAndInval() { this->updatePath(); }
+
+    void updatePath();
+
+    VerbType fVerbType = VerbType::kCubics;
+
+    SkPoint fPoints[4] = {
+            {100.05f, 100.05f}, {400.75f, 100.05f}, {400.75f, 300.95f}, {100.05f, 300.95f}};
+
+    float fConicWeight = .5;
+    float fStrokeWidth = 40;
+    SkPaint::Join fStrokeJoin = SkPaint::kMiter_Join;
+    SkPaint::Cap fStrokeCap = SkPaint::kButt_Cap;
+
+    SkPath fPath;
+};
+
+void StrokeVerbView::onDrawContent(SkCanvas* canvas) {
+    canvas->clear(SK_ColorBLACK);
+
+    SkPaint outlinePaint;
+    outlinePaint.setColor(0xff808080);
+    outlinePaint.setStyle(SkPaint::kStroke_Style);
+    outlinePaint.setStrokeWidth(fStrokeWidth);
+    outlinePaint.setStrokeJoin(fStrokeJoin);
+    outlinePaint.setStrokeCap(fStrokeCap);
+    outlinePaint.setAntiAlias(true);
+    canvas->drawPath(fPath, outlinePaint);
+
+    SkString caption;
+    caption.appendf("VerbType_%s", verb_type_name(fVerbType));
+    if (VerbType::kCubics == fVerbType) {
+        caption.appendf(" (%s)", SkCubicTypeName(SkClassifyCubic(fPoints)));
+    } else if (VerbType::kConics == fVerbType) {
+        caption.appendf(" (w=%f)", fConicWeight);
+    }
+
+    caption.appendf(" (stroke_width=%f)", fStrokeWidth);
+
+    SkPaint pointsPaint;
+    pointsPaint.setColor(SK_ColorBLUE);
+    pointsPaint.setStrokeWidth(8);
+    pointsPaint.setAntiAlias(true);
+
+    if (VerbType::kCubics == fVerbType) {
+        canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, fPoints, pointsPaint);
+    } else {
+        canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, fPoints, pointsPaint);
+        canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, fPoints + 3, pointsPaint);
+    }
+
+    SkFont font(nullptr, 20);
+    SkPaint captionPaint;
+    captionPaint.setColor(SK_ColorWHITE);
+    canvas->drawString(caption, 10, 30, font, captionPaint);
+}
+
+void StrokeVerbView::updatePath() {
+    fPath.reset();
+    fPath.moveTo(fPoints[0]);
+    switch (fVerbType) {
+        case VerbType::kCubics:
+            fPath.cubicTo(fPoints[1], fPoints[2], fPoints[3]);
+            break;
+        case VerbType::kQuadratics:
+            fPath.quadTo(fPoints[1], fPoints[3]);
+            break;
+        case VerbType::kConics:
+            fPath.conicTo(fPoints[1], fPoints[3], fConicWeight);
+            break;
+        case VerbType::kTriangles:
+            fPath.lineTo(fPoints[1]);
+            fPath.lineTo(fPoints[3]);
+            fPath.close();
+            break;
+    }
+}
+
+class StrokeVerbView::Click : public Sample::Click {
+public:
+    Click(int ptIdx) : fPtIdx(ptIdx) {}
+
+    void doClick(SkPoint points[]) {
+        if (fPtIdx >= 0) {
+            points[fPtIdx] += fCurr - fPrev;
+        } else {
+            for (int i = 0; i < 4; ++i) {
+                points[i] += fCurr - fPrev;
+            }
+        }
+    }
+
+private:
+    int fPtIdx;
+};
+
+Sample::Click* StrokeVerbView::onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) {
+    for (int i = 0; i < 4; ++i) {
+        if (VerbType::kCubics != fVerbType && 2 == i) {
+            continue;
+        }
+        if (fabs(x - fPoints[i].x()) < 20 && fabsf(y - fPoints[i].y()) < 20) {
+            return new Click(i);
+        }
+    }
+    return new Click(-1);
+}
+
+bool StrokeVerbView::onClick(Sample::Click* click) {
+    Click* myClick = (Click*)click;
+    myClick->doClick(fPoints);
+    this->updateAndInval();
+    return true;
+}
+
+bool StrokeVerbView::onChar(SkUnichar unichar) {
+        if (unichar >= '1' && unichar <= '4') {
+            fVerbType = VerbType(unichar - '1');
+            this->updateAndInval();
+            return true;
+        }
+        float* valueToScale = nullptr;
+        if (VerbType::kConics == fVerbType) {
+            valueToScale = &fConicWeight;
+        } else {
+            valueToScale = &fStrokeWidth;
+        }
+        if (valueToScale) {
+            if (unichar == '+') {
+                *valueToScale *= 2;
+                this->updateAndInval();
+                return true;
+            }
+            if (unichar == '+' || unichar == '=') {
+                *valueToScale *= 5/4.f;
+                this->updateAndInval();
+                return true;
+            }
+            if (unichar == '-') {
+                *valueToScale *= 4/5.f;
+                this->updateAndInval();
+                return true;
+            }
+            if (unichar == '_') {
+                *valueToScale *= .5f;
+                this->updateAndInval();
+                return true;
+            }
+        }
+        if (unichar == 'D') {
+            SkDebugf("    SkPoint fPoints[4] = {\n");
+            SkDebugf("        {%ff, %ff},\n", fPoints[0].x(), fPoints[0].y());
+            SkDebugf("        {%ff, %ff},\n", fPoints[1].x(), fPoints[1].y());
+            SkDebugf("        {%ff, %ff},\n", fPoints[2].x(), fPoints[2].y());
+            SkDebugf("        {%ff, %ff}\n", fPoints[3].x(), fPoints[3].y());
+            SkDebugf("    };\n");
+            return true;
+        }
+        if (unichar == 'J') {
+            fStrokeJoin = (SkPaint::Join)((fStrokeJoin + 1) % 3);
+            this->updateAndInval();
+            return true;
+        }
+        if (unichar == 'C') {
+            fStrokeCap = (SkPaint::Cap)((fStrokeCap + 1) % 3);
+            this->updateAndInval();
+            return true;
+        }
+        return false;
+}
+
+DEF_SAMPLE(return new StrokeVerbView;)
+
+#endif  // SK_SUPPORT_GPU
diff --git a/third_party/skia/samplecode/SampleSubpixelTranslate.cpp b/third_party/skia/samplecode/SampleSubpixelTranslate.cpp
deleted file mode 100644
index b658bc3..0000000
--- a/third_party/skia/samplecode/SampleSubpixelTranslate.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "samplecode/Sample.h"
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkColorPriv.h"
-#include "include/core/SkFont.h"
-#include "include/core/SkStream.h"
-#include "include/effects/SkBlurMaskFilter.h"
-#include "include/utils/SkRandom.h"
-#include "samplecode/DecodeFile.h"
-#include "tools/Resources.h"
-
-// Intended to exercise pixel snapping observed with scaled images (and
-// with non-scaled images, but for a different reason):  Bug 1145
-
-class SubpixelTranslateView : public Sample {
-public:
-    SubpixelTranslateView(const char imageFilename[],
-                          float horizontalVelocity,
-                          float verticalVelocity)
-        : fHorizontalVelocity(horizontalVelocity)
-        , fVerticalVelocity(verticalVelocity)
-    {
-        if (!DecodeDataToBitmap(GetResourceAsData(imageFilename), &fBM)) {
-            fBM.allocN32Pixels(1, 1);
-            *(fBM.getAddr32(0,0)) = 0xFF0000FF; // red == bad
-        }
-        fCurPos = SkPoint::Make(0,0);
-        fSize = 200;
-    }
-
-protected:
-    SkBitmap fBM;
-    SkScalar fSize;
-    float fHorizontalVelocity, fVerticalVelocity;
-
-    SkPoint fCurPos;
-
-    SkString name() override { return SkString("SubpixelTranslate"); }
-
-    void onDrawContent(SkCanvas* canvas) override {
-
-        static const SkFilterQuality gQualitys[] = {
-            kNone_SkFilterQuality,
-            kLow_SkFilterQuality,
-            kMedium_SkFilterQuality,
-            kHigh_SkFilterQuality
-        };
-
-        SkPaint paint;
-        SkFont font(nullptr, 48);
-        font.setSubpixel(true);
-
-        paint.setAntiAlias(true);
-        for (size_t i = 0; i < SK_ARRAY_COUNT(gQualitys); ++i) {
-            paint.setFilterQuality(gQualitys[i]);
-            SkRect r = SkRect::MakeXYWH( fCurPos.fX + i * (fSize + 10), fCurPos.fY, fSize, fSize );
-            canvas->drawBitmapRect( fBM, r, &paint );
-        }
-
-        canvas->drawString("AA Scaled", fCurPos.fX + SK_ARRAY_COUNT(gQualitys) * (fSize + 10),
-                           fCurPos.fY + fSize/2, font, paint);
-
-        paint.setAntiAlias(false);
-        font.setEdging(SkFont::Edging::kAlias);
-        for (size_t i = 0; i < SK_ARRAY_COUNT(gQualitys); ++i) {
-            paint.setFilterQuality(gQualitys[i]);
-            SkRect r = SkRect::MakeXYWH( fCurPos.fX + i * (fSize + 10), fCurPos.fY + fSize + 10, fSize, fSize );
-            canvas->drawBitmapRect( fBM, r, &paint );
-        }
-        canvas->drawString("Scaled", fCurPos.fX + SK_ARRAY_COUNT(gQualitys) * (fSize + 10),
-                           fCurPos.fY + fSize + 10 + fSize/2, font, paint);
-
-        paint.setAntiAlias(true);
-        font.setEdging(SkFont::Edging::kAntiAlias);
-        for (size_t i = 0; i < SK_ARRAY_COUNT(gQualitys); ++i) {
-            paint.setFilterQuality(gQualitys[i]);
-            canvas->drawBitmap( fBM, fCurPos.fX + i * (fBM.width() + 10), fCurPos.fY + 2*(fSize + 10), &paint );
-        }
-
-        canvas->drawString("AA No Scale",
-                           fCurPos.fX + SK_ARRAY_COUNT(gQualitys) * (fBM.width() + 10),
-                           fCurPos.fY + 2*(fSize + 10) + fSize/2, font, paint);
-
-        paint.setAntiAlias(false);
-        font.setEdging(SkFont::Edging::kAlias);
-        for (size_t i = 0; i < SK_ARRAY_COUNT(gQualitys); ++i) {
-            paint.setFilterQuality(gQualitys[i]);
-            canvas->drawBitmap( fBM, fCurPos.fX + i * (fBM.width() + 10), fCurPos.fY + 2*(fSize + 10) + fBM.height() + 10, &paint );
-        }
-
-        canvas->drawString("No Scale", fCurPos.fX + SK_ARRAY_COUNT(gQualitys) * (fBM.width() + 10),
-                           fCurPos.fY + 2*(fSize + 10) + fBM.height() + 10 + fSize/2, font, paint);
-
-
-        fCurPos.fX += fHorizontalVelocity;
-        fCurPos.fY += fVerticalVelocity;
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new SubpixelTranslateView("images/mandrill_256.png", .05f, .05f); )
diff --git a/third_party/skia/samplecode/SampleTextBox.cpp b/third_party/skia/samplecode/SampleTextBox.cpp
index 7aa1598..d929cad 100644
--- a/third_party/skia/samplecode/SampleTextBox.cpp
+++ b/third_party/skia/samplecode/SampleTextBox.cpp
@@ -17,7 +17,6 @@
 #include "include/core/SkTextBlob.h"
 #include "include/core/SkTime.h"
 #include "include/core/SkTypeface.h"
-#include "include/effects/SkBlurMaskFilter.h"
 #include "include/effects/SkGradientShader.h"
 #include "include/utils/SkRandom.h"
 #include "modules/skshaper/include/SkShaper.h"
@@ -25,6 +24,8 @@
 #include "src/shaders/SkColorShader.h"
 #include "src/utils/SkUTF.h"
 
+typedef std::unique_ptr<SkShaper> (*ShaperFactory)();
+
 static const char gText[] =
     "When in the Course of human events it becomes necessary for one people "
     "to dissolve the political bands which have connected them with another "
@@ -34,11 +35,14 @@
     "declare the causes which impel them to the separation.";
 
 class TextBoxView : public Sample {
+    SkString fName;
 public:
-    TextBoxView() : fShaper(SkShaper::Make()) {}
+    TextBoxView(ShaperFactory fact, const char suffix[]) : fShaper(fact()) {
+        fName.printf("TextBox_%s", suffix);
+    }
 
 protected:
-    SkString name() override { return SkString("TextBox"); }
+    SkString name() override { return fName; }
 
     void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) {
         SkAutoCanvasRestore acr(canvas, true);
@@ -52,9 +56,11 @@
         paint.setColor(fg);
 
         for (int i = 9; i < 24; i += 2) {
+            SkShaper::PurgeCaches();
             SkTextBlobBuilderRunHandler builder(gText, { margin, margin });
             SkFont srcFont(nullptr, SkIntToScalar(i));
             srcFont.setEdging(SkFont::Edging::kSubpixelAntiAlias);
+            srcFont.setSubpixel(true);
 
             const char* utf8 = gText;
             size_t utf8Bytes = sizeof(gText) - 1;
@@ -105,9 +111,80 @@
 
 private:
     std::unique_ptr<SkShaper> fShaper;
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
-//////////////////////////////////////////////////////////////////////////////
+DEF_SAMPLE( return new TextBoxView([](){ return SkShaper::Make(); }, "default"); );
+#ifdef SK_SHAPER_CORETEXT_AVAILABLE
+DEF_SAMPLE( return new TextBoxView(SkShaper::MakeCoreText, "coretext"); );
+#endif
 
-DEF_SAMPLE( return new TextBoxView(); )
+class SampleShaper : public Sample {
+public:
+    SampleShaper() {}
+
+protected:
+    SkString name() override { return SkString("shaper"); }
+
+    void drawTest(SkCanvas* canvas, const char str[], SkScalar size,
+                  std::unique_ptr<SkShaper> shaper) {
+        if (!shaper) return;
+
+        SkTextBlobBuilderRunHandler builder(str, {0, 0});
+        SkFont srcFont;
+        srcFont.setSize(size);
+        srcFont.setEdging(SkFont::Edging::kSubpixelAntiAlias);
+        srcFont.setSubpixel(true);
+
+        size_t len = strlen(str);
+
+        std::unique_ptr<SkShaper::BiDiRunIterator> bidi(
+            SkShaper::MakeBiDiRunIterator(str, len, 0xfe));
+        if (!bidi) {
+            return;
+        }
+
+        std::unique_ptr<SkShaper::LanguageRunIterator> language(
+            SkShaper::MakeStdLanguageRunIterator(str, len));
+        if (!language) {
+            return;
+        }
+
+        SkFourByteTag undeterminedScript = SkSetFourByteTag('Z','y','y','y');
+        std::unique_ptr<SkShaper::ScriptRunIterator> script(
+            SkShaper::MakeScriptRunIterator(str, len, undeterminedScript));
+        if (!script) {
+            return;
+        }
+
+        std::unique_ptr<SkShaper::FontRunIterator> font(
+            SkShaper::MakeFontMgrRunIterator(str, len, srcFont, SkFontMgr::RefDefault(),
+                                             "Arial", SkFontStyle::Bold(), &*language));
+        if (!font) {
+            return;
+        }
+
+        shaper->shape(str, len, *font, *bidi, *script, *language, 2000, &builder);
+
+        canvas->drawTextBlob(builder.makeBlob(), 0, 0, SkPaint());
+    }
+
+    void onDrawContent(SkCanvas* canvas) override {
+        canvas->translate(10, 30);
+
+        const char text[] = "world";
+
+        for (SkScalar size = 30; size <= 30; size += 10) {
+            this->drawTest(canvas, text, size, SkShaper::Make());
+            canvas->translate(0, size + 5);
+            #ifdef SK_SHAPER_CORETEXT_AVAILABLE
+            this->drawTest(canvas, text, size, SkShaper::MakeCoreText());
+            #endif
+            canvas->translate(0, size*2);
+        }
+    }
+
+private:
+    using INHERITED = Sample;
+};
+DEF_SAMPLE( return new SampleShaper; );
diff --git a/third_party/skia/samplecode/SampleTextEffects.cpp b/third_party/skia/samplecode/SampleTextEffects.cpp
deleted file mode 100644
index 8e57750..0000000
--- a/third_party/skia/samplecode/SampleTextEffects.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "include/core/SkCanvas.h"
-#include "include/core/SkColorFilter.h"
-#include "include/core/SkColorPriv.h"
-#include "include/core/SkPath.h"
-#include "include/core/SkRegion.h"
-#include "include/core/SkShader.h"
-#include "include/core/SkStrokeRec.h"
-#include "include/core/SkTypeface.h"
-#include "include/effects/SkGradientShader.h"
-#include "include/utils/SkTextUtils.h"
-#include "samplecode/Sample.h"
-#include "src/core/SkReadBuffer.h"
-#include "src/core/SkWriteBuffer.h"
-#include "src/utils/SkUTF.h"
-
-#include "include/effects/SkBlurMaskFilter.h"
-#include "include/effects/SkGradientShader.h"
-
-#include "include/effects/Sk2DPathEffect.h"
-
-class Dot2DPathEffect : public Sk2DPathEffect {
-public:
-    Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix,
-                    SkTDArray<SkPoint>* pts)
-    : Sk2DPathEffect(matrix), fRadius(radius), fPts(pts) {}
-
-    SK_FLATTENABLE_HOOKS(Dot2DPathEffect)
-protected:
-    void begin(const SkIRect& uvBounds, SkPath* dst) const override {
-        if (fPts) {
-            fPts->reset();
-        }
-        this->INHERITED::begin(uvBounds, dst);
-    }
-
-    virtual void next(const SkPoint& loc, int u, int v,
-                      SkPath* dst) const override {
-        if (fPts) {
-            *fPts->append() = loc;
-        }
-        dst->addCircle(loc.fX, loc.fY, fRadius);
-    }
-
-    void flatten(SkWriteBuffer& buffer) const override {
-        buffer.writeMatrix(this->getMatrix());
-        buffer.writeScalar(fRadius);
-    }
-
-private:
-
-    SkScalar fRadius;
-    SkTDArray<SkPoint>* fPts;
-
-    typedef Sk2DPathEffect INHERITED;
-};
-
-// Register this path effect as deserializable before main().
-namespace {
-    static struct Initializer {
-        Initializer() {
-            SK_REGISTER_FLATTENABLE(Dot2DPathEffect);
-        }
-    } initializer;
-}
-
-
-sk_sp<SkFlattenable> Dot2DPathEffect::CreateProc(SkReadBuffer& buffer) {
-    SkMatrix matrix;
-    buffer.readMatrix(&matrix);
-    return sk_make_sp<Dot2DPathEffect>(buffer.readScalar(), matrix, nullptr);
-}
-
-class InverseFillPE : public SkPathEffect {
-public:
-    InverseFillPE() {}
-    virtual bool onFilterPath(SkPath* dst, const SkPath& src,
-                              SkStrokeRec*, const SkRect*) const override {
-        *dst = src;
-        dst->setFillType(SkPathFillType::kInverseWinding);
-        return true;
-    }
-
-private:
-    SK_FLATTENABLE_HOOKS(InverseFillPE)
-
-    typedef SkPathEffect INHERITED;
-};
-
-sk_sp<SkFlattenable> InverseFillPE::CreateProc(SkReadBuffer& buffer) {
-    return sk_make_sp<InverseFillPE>();
-}
-
-static sk_sp<SkPathEffect> makepe(float interp, SkTDArray<SkPoint>* pts) {
-    SkMatrix    lattice;
-    SkScalar    rad = 3 + SkIntToScalar(4) * (1 - interp);
-    lattice.setScale(rad*2, rad*2, 0, 0);
-    lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
-    return sk_make_sp<Dot2DPathEffect>(rad, lattice, pts);
-}
-
-class TextEffectsView : public Sample {
-    sk_sp<SkTypeface> fFace;
-    SkScalar fInterp;
-    SkScalar fDx;
-
-public:
-    TextEffectsView() {
-        fFace = SkTypeface::MakeFromFile("/Users/reed/Downloads/p052024l.pfb");
-        fInterp = 0;
-        fDx = SK_Scalar1/64;
-    }
-
-protected:
-    SkString name() override { return SkString("Text Effects"); }
-
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
-    }
-
-    void drawdots(SkCanvas* canvas, SkString s, SkScalar x, SkScalar y, const SkFont& font) {
-        SkTDArray<SkPoint> pts;
-        auto pe = makepe(fInterp, &pts);
-
-        SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
-        SkPath path, dstPath;
-        SkTextUtils::GetPath(s.c_str(), s.size(), SkTextEncoding::kUTF8, x, y, font, &path);
-        pe->filterPath(&dstPath, path, &rec, nullptr);
-
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setStrokeWidth(10);
-        paint.setColor(SK_ColorRED);
-        canvas->drawPoints(SkCanvas::kPoints_PointMode, pts.count(), pts.begin(), paint);
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        this->drawBG(canvas);
-
-        SkScalar x = SkIntToScalar(20);
-        SkScalar y = SkIntToScalar(300);
-
-        SkFont font(SkTypeface::MakeFromName("sans-serif", SkFontStyle::Bold()), 240);
-
-        SkString str("9");
-
-        canvas->drawString(str, x, y, font, SkPaint());
-        drawdots(canvas, str, x, y, font);
-
-        if (false) {
-            fInterp += fDx;
-            if (fInterp > 1) {
-                fInterp = 1;
-                fDx = -fDx;
-            } else if (fInterp < 0) {
-                fInterp = 0;
-                fDx = -fDx;
-            }
-        }
-    }
-
-private:
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new TextEffectsView(); )
diff --git a/third_party/skia/samplecode/SampleTextureDomain.cpp b/third_party/skia/samplecode/SampleTextureDomain.cpp
deleted file mode 100644
index 3bac799..0000000
--- a/third_party/skia/samplecode/SampleTextureDomain.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkSurface.h"
-#include "include/effects/SkBlurMaskFilter.h"
-#include "samplecode/Sample.h"
-#include "src/core/SkBlurMask.h"
-
-static SkBitmap make_bitmap() {
-    SkBitmap bm;
-    bm.allocN32Pixels(5, 5);
-
-    for (int y = 0; y < bm.height(); y++) {
-        uint32_t* p = bm.getAddr32(0, y);
-        for (int x = 0; x < bm.width(); x++) {
-            p[x] = ((x + y) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
-        }
-    }
-    return bm;
-}
-
-class TextureDomainView : public Sample {
-    SkBitmap    fBM;
-
-public:
-    TextureDomainView(){
-        fBM = make_bitmap();
-    }
-
-protected:
-    virtual SkString name() { return SkString("Texture Domain"); }
-
-    virtual void onDrawContent(SkCanvas* canvas) {
-        SkRect srcRect;
-        SkRect dstRect;
-        SkPaint paint;
-        paint.setFilterQuality(kLow_SkFilterQuality);
-
-        // Test that bitmap draws from malloc-backed bitmaps respect
-        // the constrained texture domain.
-        srcRect.setXYWH(1, 1, 3, 3);
-        dstRect.setXYWH(5, 5, 305, 305);
-        canvas->drawBitmapRect(fBM, srcRect, dstRect, &paint, SkCanvas::kStrict_SrcRectConstraint);
-
-        // Test that bitmap draws across separate devices also respect
-        // the constrainted texture domain.
-        // Note:  GPU-backed bitmaps follow a different rendering path
-        // when copying from one GPU device to another.
-        SkImageInfo info = SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType);
-        auto surface(canvas->makeSurface(info));
-
-        srcRect.setXYWH(1, 1, 3, 3);
-        dstRect.setXYWH(1, 1, 3, 3);
-        surface->getCanvas()->drawBitmapRect(fBM, srcRect, dstRect, &paint,
-                                             SkCanvas::kStrict_SrcRectConstraint);
-
-        sk_sp<SkImage> image(surface->makeImageSnapshot());
-
-        srcRect.setXYWH(1, 1, 3, 3);
-        dstRect.setXYWH(405, 5, 305, 305);
-        canvas->drawImageRect(image, srcRect, dstRect, &paint);
-
-        // Test that bitmap blurring using a subrect
-        // renders correctly
-        srcRect.setXYWH(1, 1, 3, 3);
-        dstRect.setXYWH(5, 405, 305, 305);
-        paint.setMaskFilter(SkMaskFilter::MakeBlur(
-            kNormal_SkBlurStyle, SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)), false));
-        canvas->drawImageRect(image, srcRect, dstRect, &paint);
-
-        // Blur and a rotation + nullptr src rect
-        // This should not trigger the texture domain code
-        // but it will test a code path in SkGpuDevice::drawBitmap
-        // that handles blurs with rects transformed to non-
-        // orthogonal rects. It also tests the nullptr src rect handling
-        paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle,
-                                                   SkBlurMask::ConvertRadiusToSigma(5)));
-
-        dstRect.setXYWH(-150, -150, 300, 300);
-        canvas->translate(550, 550);
-        canvas->rotate(45);
-        canvas->drawBitmapRect(fBM, dstRect, &paint);
-    }
-private:
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new TextureDomainView(); )
diff --git a/third_party/skia/samplecode/SampleTextureUpload.cpp b/third_party/skia/samplecode/SampleTextureUpload.cpp
index a33d1d9..933748c 100644
--- a/third_party/skia/samplecode/SampleTextureUpload.cpp
+++ b/third_party/skia/samplecode/SampleTextureUpload.cpp
@@ -9,7 +9,7 @@
 #include "include/core/SkPaint.h"
 #include "include/core/SkSurface.h"
 #include "include/core/SkTypes.h"
-#include "include/gpu/GrContext.h"
+#include "include/gpu/GrDirectContext.h"
 #include "samplecode/Sample.h"
 #include "tools/timer/TimeUtils.h"
 
@@ -17,9 +17,9 @@
  * This sample exercises heavy texture updates and uploads.
  */
 class TextureUploadSample : public Sample {
-    static constexpr int kMinTileSize = 128;
-    static constexpr int kMaxTileSize = 2048;
-    static constexpr float kGridScale = 0.25f;
+    inline static constexpr int kMinTileSize = 128;
+    inline static constexpr int kMaxTileSize = 2048;
+    inline static constexpr float kGridScale = 0.25f;
 
     bool fDrawTexturesToScreen = true;
     int fTileSize = 256;
@@ -31,11 +31,11 @@
 
     class RenderTargetTexture : public SkRefCnt {
     public:
-        RenderTargetTexture(GrContext* context, int size) {
-            SkSurfaceProps surfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
+        RenderTargetTexture(GrDirectContext* direct, int size) {
+            SkSurfaceProps surfaceProps(0, kRGB_H_SkPixelGeometry);
             SkImageInfo imageInfo = SkImageInfo::Make(size, size, kRGBA_8888_SkColorType,
                                                       kPremul_SkAlphaType);
-            fSurface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, imageInfo, 0,
+            fSurface = SkSurface::MakeRenderTarget(direct, SkBudgeted::kNo, imageInfo, 0,
                                                    &surfaceProps);
         }
 
@@ -55,7 +55,7 @@
     };
 
     SkTArray<sk_sp<RenderTargetTexture>> fTextures;
-    GrContext* fCachedContext = nullptr;
+    GrDirectContext* fCachedContext = nullptr;
     SkScalar fActiveTileIndex = 0;
 
     SkString name() override {
@@ -67,12 +67,12 @@
             fDrawTexturesToScreen = !fDrawTexturesToScreen;
             return true;
         } else if ('>' == uni) {
-            fTileSize = SkTMin(kMaxTileSize, 2*fTileSize);
+            fTileSize = std::min(kMaxTileSize, 2*fTileSize);
             fTileRows = kMaxTileSize/fTileSize;
             fTileCols = kMaxTileSize/fTileSize;
             fCachedContext = nullptr;
         } else if ('<' == uni) {
-            fTileSize = SkTMax(kMinTileSize, fTileSize/2);
+            fTileSize = std::max(kMinTileSize, fTileSize/2);
             fTileRows = kMaxTileSize/fTileSize;
             fTileCols = kMaxTileSize/fTileSize;
             fCachedContext = nullptr;
@@ -92,11 +92,11 @@
         this->setSize(1024, 1024);
     }
 
-    void initializeTextures(GrContext* context) {
+    void initializeTextures(GrDirectContext* direct) {
         fTextures.reset();
         int textureCount = fTileRows * fTileCols;
         for (int i = 0; i < textureCount; i++) {
-            fTextures.emplace_back(new RenderTargetTexture(context, fTileSize));
+            fTextures.emplace_back(new RenderTargetTexture(direct, fTileSize));
         }
 
         // Construct two simple rasters of differing colors to serve
@@ -107,14 +107,12 @@
 
     void onDrawContent(SkCanvas* canvas) override {
 #if SK_SUPPORT_GPU
-        SkPaint paint;
-
-        GrContext* context = canvas->getGrContext();
-        if (context) {
+        auto direct = GrAsDirectContext(canvas->recordingContext());
+        if (direct) {
             // One-time context-specific setup.
-            if (context != fCachedContext) {
-                fCachedContext = context;
-                this->initializeTextures(context);
+            if (direct != fCachedContext) {
+                fCachedContext = direct;
+                this->initializeTextures(direct);
             }
 
             // Upload new texture data for all textures, simulating a full page of tiles
@@ -133,7 +131,7 @@
                     for (int x = 0; x < fTileCols; x++) {
                         int currentIndex = y * fTileCols + x;
                         canvas->drawImage(fTextures[currentIndex]->getImage(),
-                                          x * fTileSize, y * fTileSize, &paint);
+                                          x * fTileSize, y * fTileSize);
                     }
                 }
             }
@@ -150,8 +148,6 @@
     }
 };
 
-const int TextureUploadSample::kMinTileSize;
-const int TextureUploadSample::kMaxTileSize;
 
 DEF_SAMPLE( return new TextureUploadSample(); )
 
diff --git a/third_party/skia/samplecode/SampleThinAA.cpp b/third_party/skia/samplecode/SampleThinAA.cpp
index 92aa202..5989deb 100644
--- a/third_party/skia/samplecode/SampleThinAA.cpp
+++ b/third_party/skia/samplecode/SampleThinAA.cpp
@@ -18,10 +18,8 @@
 
 class ShapeRenderer : public SkRefCntBase {
 public:
-    static constexpr SkScalar kTileWidth = 20.f;
-    static constexpr SkScalar kTileHeight = 20.f;
-
-    virtual ~ShapeRenderer() {}
+    inline static constexpr SkScalar kTileWidth = 20.f;
+    inline static constexpr SkScalar kTileHeight = 20.f;
 
     // Draw the shape, limited to kTileWidth x kTileHeight. It must apply the local subpixel (tx,
     // ty) translation and rotation by angle. Prior to these transform adjustments, the SkCanvas
@@ -66,7 +64,7 @@
 private:
     RectRenderer() {}
 
-    typedef ShapeRenderer INHERITED;
+    using INHERITED = ShapeRenderer;
 };
 
 class PathRenderer : public ShapeRenderer {
@@ -133,7 +131,7 @@
 
         // Adding round caps forces Ganesh to use the path renderer for lines instead of converting
         // them to rectangles (which are already explicitly tested). However, when not curved, the
-        // GrShape will still find a way to turn it into a rrect draw so it doesn't hit the
+        // GrStyledShape will still find a way to turn it into a rrect draw so it doesn't hit the
         // path renderer in that condition.
         paint->setStrokeCap(SkPaint::kRound_Cap);
         paint->setStrokeJoin(SkPaint::kMiter_Join);
@@ -151,7 +149,7 @@
             : fDepth(depth)
             , fHairline(hairline) {}
 
-    typedef ShapeRenderer INHERITED;
+    using INHERITED = ShapeRenderer;
 };
 
 class OffscreenShapeRenderer : public ShapeRenderer {
@@ -210,7 +208,6 @@
         // Use medium quality filter to get mipmaps when drawing smaller, or use nearest filtering
         // when upscaling
         SkPaint blit;
-        blit.setFilterQuality(scale > 1.f ? kNone_SkFilterQuality : kMedium_SkFilterQuality);
         if (debugMode) {
             // Makes anything that's > 1/255 alpha fully opaque and sets color to medium green.
             static constexpr float kFilter[] = {
@@ -223,8 +220,15 @@
             blit.setColorFilter(SkColorFilters::Matrix(kFilter));
         }
 
+        auto sampling = scale > 1 ? SkSamplingOptions(SkFilterMode::kNearest)
+                                  : SkSamplingOptions(SkFilterMode::kLinear,
+                                                      SkMipmapMode::kLinear);
+
         canvas->scale(scale, scale);
-        canvas->drawImageRect(fLastRendered, SkRect::MakeWH(kTileWidth, kTileHeight), &blit);
+        canvas->drawImageRect(fLastRendered.get(),
+                              SkRect::MakeWH(kTileWidth, kTileHeight),
+                              SkRect::MakeWH(kTileWidth, kTileHeight),
+                              sampling, &blit, SkCanvas::kFast_SrcRectConstraint);
     }
 
 private:
@@ -239,7 +243,7 @@
             , fRenderer(std::move(renderer))
             , fSupersampleFactor(supersample) { }
 
-    typedef ShapeRenderer INHERITED;
+    using INHERITED = ShapeRenderer;
 };
 
 class ThinAASample : public Sample {
@@ -403,8 +407,8 @@
                 case 'u': fAngle = 0.f; return true;
                 case 'y': fAngle = 90.f; return true;
                 case ' ': fAngle = SkScalarMod(fAngle + 15.f, 360.f); return true;
-                case '-': fStrokeWidth = SkMaxScalar(0.1f, fStrokeWidth - 0.05f); return true;
-                case '=': fStrokeWidth = SkMinScalar(1.f, fStrokeWidth + 0.05f); return true;
+                case '-': fStrokeWidth = std::max(0.1f, fStrokeWidth - 0.05f); return true;
+                case '=': fStrokeWidth = std::min(1.f, fStrokeWidth + 0.05f); return true;
             }
             return false;
     }
@@ -480,8 +484,7 @@
         SkFont font(nullptr, 12);
 
         if (gridX == 0) {
-            SkString name = shape->name();
-            SkScalar centering = name.size() * 4.f; // ad-hoc
+            SkScalar centering = shape->name().size() * 4.f; // ad-hoc
 
             canvas->save();
             canvas->translate(-10.f, 4 * ShapeRenderer::kTileHeight + centering);
@@ -537,11 +540,11 @@
         canvas->translate(0.f, 8.f * ShapeRenderer::kTileHeight + 20.f);
     }
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
 DEF_SAMPLE( return new ThinAASample; )
 
-}
+}  // namespace skiagm
diff --git a/third_party/skia/samplecode/SampleTiming.cpp b/third_party/skia/samplecode/SampleTiming.cpp
new file mode 100644
index 0000000..d8e3216
--- /dev/null
+++ b/third_party/skia/samplecode/SampleTiming.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/core/SkCanvas.h"
+#include "include/core/SkFont.h"
+#include "include/core/SkSurface.h"
+#include "samplecode/Sample.h"
+#include <chrono>
+
+struct TimingSample : public Sample {
+    inline static constexpr int W = 24,
+                                H = 16;
+    sk_sp<SkImage> fImg;
+
+    SkString name() override { return SkString("Timing"); }
+
+    void onOnceBeforeDraw() override {
+        sk_sp<SkSurface> surf = SkSurface::MakeRasterN32Premul(W,H);
+        surf->getCanvas()->drawString("abc", 2,H-4, SkFont{}, SkPaint{});
+        fImg = surf->makeImageSnapshot();
+    }
+
+    void onDrawContent(SkCanvas* canvas) override {
+        canvas->scale(8,8);
+
+        // Draw normally.
+        canvas->drawImage(fImg, 0,0);
+
+        canvas->translate(0,H);
+
+        // Draw one pixel at a time with drawImageRect(),
+        // timing how long each drawImageRect() call takes.
+        double cost[H][W];
+        double min = +INFINITY,
+               max = -INFINITY;
+        for (int y = 0; y < H; y++)
+        for (int x = 0; x < W; x++) {
+            auto start = std::chrono::steady_clock::now();
+            canvas->drawImageRect(fImg.get(),
+                                  SkRect::MakeXYWH(x,y,1,1), SkRect::MakeXYWH(x,y,1,1),
+                                  SkSamplingOptions(), /*paint=*/nullptr,
+                                  SkCanvas::kStrict_SrcRectConstraint);
+            auto elapsed = std::chrono::steady_clock::now() - start;
+
+            cost[y][x] = elapsed.count();
+            min = std::min(min, cost[y][x]);
+            max = std::max(max, cost[y][x]);
+        }
+
+        canvas->translate(0,H);
+
+        // Draw using those per-pixel timings,
+        // with the slowest pixel scaled to alpha=1, the fastest to alpha=0.
+        for (int y = 0; y < H; y++)
+        for (int x = 0; x < W; x++) {
+            SkPaint p;
+            p.setAlphaf( (cost[y][x] - min) / (max - min) );
+            canvas->drawRect(SkRect::MakeXYWH(x,y,1,1), p);
+        }
+
+        canvas->translate(0,H);
+
+        // Draw each pixel into offscreen, timing each draw.
+        SkImageInfo info = canvas->imageInfo().makeWH(1024,1024);
+        if (sk_sp<SkSurface> offscreen = canvas->makeSurface(info)) {
+            min = +INFINITY;
+            max = -INFINITY;
+            for (int y = 0; y < H; y++)
+            for (int x = 0; x < W; x++) {
+                auto start = std::chrono::steady_clock::now();
+                offscreen->getCanvas()->drawImageRect(fImg,
+                                                      SkRect::MakeXYWH(x,y,1,1),
+                                                      SkRect::MakeXYWH(0,0,1024,1024),
+                                                      SkSamplingOptions(),
+                                                      /*paint=*/nullptr,
+                                                      SkCanvas::kStrict_SrcRectConstraint);
+                auto elapsed = std::chrono::steady_clock::now() - start;
+
+                cost[y][x] = elapsed.count();
+                min = std::min(min, cost[y][x]);
+                max = std::max(max, cost[y][x]);
+            }
+            for (int y = 0; y < H; y++)
+            for (int x = 0; x < W; x++) {
+                SkPaint p;
+                p.setAlphaf( (cost[y][x] - min) / (max - min) );
+                canvas->drawRect(SkRect::MakeXYWH(x,y,1,1), p);
+            }
+        }
+    }
+};
+DEF_SAMPLE( return new TimingSample; )
diff --git a/third_party/skia/samplecode/SampleUnpremul.cpp b/third_party/skia/samplecode/SampleUnpremul.cpp
deleted file mode 100644
index 9c606bd..0000000
--- a/third_party/skia/samplecode/SampleUnpremul.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkColorPriv.h"
-#include "include/core/SkStream.h"
-#include "include/core/SkString.h"
-#include "include/core/SkTypes.h"
-#include "samplecode/DecodeFile.h"
-#include "samplecode/Sample.h"
-#include "src/core/SkBlurMask.h"
-#include "src/core/SkOSFile.h"
-#include "src/utils/SkOSPath.h"
-#include "src/utils/SkUTF.h"
-#include "tools/Resources.h"
-#include "tools/ToolUtils.h"
-
-/**
- *  Interprets c as an unpremultiplied color, and returns the
- *  premultiplied equivalent.
- */
-static SkPMColor premultiply_unpmcolor(SkPMColor c) {
-    U8CPU a = SkGetPackedA32(c);
-    U8CPU r = SkGetPackedR32(c);
-    U8CPU g = SkGetPackedG32(c);
-    U8CPU b = SkGetPackedB32(c);
-    return SkPreMultiplyARGB(a, r, g, b);
-}
-
-class UnpremulView : public Sample {
-public:
-    UnpremulView(SkString res)
-    : fResPath(res)
-    , fPremul(true)
-    , fDecodeSucceeded(false) {
-        this->nextImage();
-    }
-
-protected:
-    SkString name() override { return SkString("unpremul"); }
-
-    bool onChar(SkUnichar uni) override {
-            char utf8[SkUTF::kMaxBytesInUTF8Sequence];
-            size_t size = SkUTF::ToUTF8(uni, utf8);
-            // Only consider events for single char keys
-            if (1 == size) {
-                switch (utf8[0]) {
-                    case fNextImageChar:
-                        this->nextImage();
-                        return true;
-                    case fTogglePremulChar:
-                        this->togglePremul();
-                        return true;
-                    default:
-                        break;
-                }
-            }
-            return false;
-    }
-
-    void onDrawBackground(SkCanvas* canvas) override {
-        ToolUtils::draw_checkerboard(canvas, 0xFFCCCCCC, 0xFFFFFFFF, 12);
-    }
-
-    void onDrawContent(SkCanvas* canvas) override {
-        SkPaint paint;
-        paint.setAntiAlias(true);
-
-        SkFont font;
-        font.setSize(24);
-        SkScalar height = font.getMetrics(nullptr);
-        if (!fDecodeSucceeded) {
-            SkString failure;
-            if (fResPath.size() == 0) {
-                failure.printf("resource path is required!");
-            } else {
-                failure.printf("Failed to decode %s", fCurrFile.c_str());
-            }
-            canvas->drawString(failure, 0, height, font, paint);
-            return;
-        }
-
-        // Name, size of the file, and whether or not it is premultiplied.
-        SkString header(SkOSPath::Basename(fCurrFile.c_str()));
-        header.appendf("     [%dx%d]     %s", fBitmap.width(), fBitmap.height(),
-                       (fPremul ? "premultiplied" : "unpremultiplied"));
-        canvas->drawString(header, 0, height, font, paint);
-        canvas->translate(0, height);
-
-        // Help messages
-        header.printf("Press '%c' to move to the next image.'", fNextImageChar);
-        canvas->drawString(header, 0, height, font, paint);
-        canvas->translate(0, height);
-
-        header.printf("Press '%c' to toggle premultiplied decode.", fTogglePremulChar);
-        canvas->drawString(header, 0, height, font, paint);
-
-        // Now draw the image itself.
-        canvas->translate(height * 2, height * 2);
-        if (!fPremul) {
-            // A premultiplied bitmap cannot currently be drawn.
-            // Copy it to a bitmap which can be drawn, converting
-            // to premultiplied:
-            SkBitmap bm;
-            bm.allocN32Pixels(fBitmap.width(), fBitmap.height());
-            for (int i = 0; i < fBitmap.width(); ++i) {
-                for (int j = 0; j < fBitmap.height(); ++j) {
-                    *bm.getAddr32(i, j) = premultiply_unpmcolor(*fBitmap.getAddr32(i, j));
-                }
-            }
-            canvas->drawBitmap(bm, 0, 0);
-        } else {
-            canvas->drawBitmap(fBitmap, 0, 0);
-        }
-    }
-
-private:
-    const SkString  fResPath;
-    SkString        fCurrFile;
-    bool            fPremul;
-    bool            fDecodeSucceeded;
-    SkBitmap        fBitmap;
-    SkOSFile::Iter  fFileIter;
-
-    static const char   fNextImageChar      = 'j';
-    static const char   fTogglePremulChar   = 'h';
-
-    void nextImage() {
-        if (fResPath.size() == 0) {
-            return;
-        }
-        SkString basename;
-        if (!fFileIter.next(&basename)) {
-            fFileIter.reset(fResPath.c_str());
-            if (!fFileIter.next(&basename)) {
-                // Perhaps this should draw some error message?
-                return;
-            }
-        }
-        fCurrFile = SkOSPath::Join(fResPath.c_str(), basename.c_str());
-        this->decodeCurrFile();
-    }
-
-    void decodeCurrFile() {
-        if (fCurrFile.size() == 0) {
-            fDecodeSucceeded = false;
-            return;
-        }
-        fDecodeSucceeded = decode_file(fCurrFile.c_str(), &fBitmap, kN32_SkColorType, !fPremul);
-    }
-
-    void togglePremul() {
-        fPremul = !fPremul;
-        this->decodeCurrFile();
-    }
-
-    typedef Sample INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_SAMPLE( return new UnpremulView(GetResourcePath("images")); )
diff --git a/third_party/skia/samplecode/SampleVariableWidthStroker.cpp b/third_party/skia/samplecode/SampleVariableWidthStroker.cpp
new file mode 100644
index 0000000..65efa11
--- /dev/null
+++ b/third_party/skia/samplecode/SampleVariableWidthStroker.cpp
@@ -0,0 +1,1391 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "imgui.h"
+#include "include/core/SkBitmap.h"
+#include "include/core/SkCanvas.h"
+#include "include/core/SkPath.h"
+#include "include/core/SkPathMeasure.h"
+#include "include/utils/SkParsePath.h"
+#include "samplecode/Sample.h"
+
+#include "src/core/SkGeometry.h"
+
+#include <stack>
+
+namespace {
+
+//////////////////////////////////////////////////////////////////////////////
+
+constexpr inline SkPoint rotate90(const SkPoint& p) { return {p.fY, -p.fX}; }
+inline SkPoint rotate180(const SkPoint& p) { return p * -1; }
+inline bool isClockwise(const SkPoint& a, const SkPoint& b) { return a.cross(b) > 0; }
+
+static SkPoint checkSetLength(SkPoint p, float len, const char* file, int line) {
+    if (!p.setLength(len)) {
+        SkDebugf("%s:%d: Failed to set point length\n", file, line);
+    }
+    return p;
+}
+
+/** Version of setLength that prints debug msg on failure to help catch edge cases */
+#define setLength(p, len) checkSetLength(p, len, __FILE__, __LINE__)
+
+constexpr uint64_t choose(uint64_t n, uint64_t k) {
+    SkASSERT(n >= k);
+    uint64_t result = 1;
+    for (uint64_t i = 1; i <= k; i++) {
+        result *= (n + 1 - i);
+        result /= i;
+    }
+    return result;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A scalar (float-valued weights) Bezier curve of arbitrary degree.
+ */
+class ScalarBezCurve {
+public:
+    inline static constexpr int kDegreeInvalid = -1;
+
+    /** Creates an empty curve with invalid degree. */
+    ScalarBezCurve() : fDegree(kDegreeInvalid) {}
+
+    /** Creates a curve of the specified degree with weights initialized to 0. */
+    explicit ScalarBezCurve(int degree) : fDegree(degree) {
+        SkASSERT(degree >= 0);
+        fWeights.resize(degree + 1, {0});
+    }
+
+    /** Creates a curve of specified degree with the given weights. */
+    ScalarBezCurve(int degree, const std::vector<float>& weights) : ScalarBezCurve(degree) {
+        SkASSERT(degree >= 0);
+        SkASSERT(weights.size() == (size_t)degree + 1);
+        fWeights.insert(fWeights.begin(), weights.begin(), weights.end());
+    }
+
+    /** Returns the extreme-valued weight */
+    float extremumWeight() const {
+        float f = 0;
+        int sign = 1;
+        for (float w : fWeights) {
+            if (std::abs(w) > f) {
+                f = std::abs(w);
+                sign = w >= 0 ? 1 : -1;
+            }
+        }
+        return sign * f;
+    }
+
+    /** Evaluates the curve at t */
+    float eval(float t) const { return Eval(*this, t); }
+
+    /** Evaluates the curve at t */
+    static float Eval(const ScalarBezCurve& curve, float t) {
+        // Set up starting point of recursion (k=0)
+        ScalarBezCurve result = curve;
+
+        for (int k = 1; k <= curve.fDegree; k++) {
+            // k is level of recursion, k-1 has previous level's values.
+            for (int i = curve.fDegree; i >= k; i--) {
+                result.fWeights[i] = result.fWeights[i - 1] * (1 - t) + result.fWeights[i] * t;
+            }
+        }
+
+        return result.fWeights[curve.fDegree];
+    }
+
+    /** Splits this curve at t into two halves (of the same degree) */
+    void split(float t, ScalarBezCurve* left, ScalarBezCurve* right) const {
+        Split(*this, t, left, right);
+    }
+
+    /** Splits this curve into the subinterval [tmin,tmax]. */
+    void split(float tmin, float tmax, ScalarBezCurve* result) const {
+        // TODO: I believe there's a more efficient algorithm for this
+        const float tRel = tmin / tmax;
+        ScalarBezCurve ll, rl, rr;
+        this->split(tmax, &rl, &rr);
+        rl.split(tRel, &ll, result);
+    }
+
+    /** Splits the curve at t into two halves (of the same degree) */
+    static void Split(const ScalarBezCurve& curve,
+                      float t,
+                      ScalarBezCurve* left,
+                      ScalarBezCurve* right) {
+        // Set up starting point of recursion (k=0)
+        const int degree = curve.fDegree;
+        ScalarBezCurve result = curve;
+        *left = ScalarBezCurve(degree);
+        *right = ScalarBezCurve(degree);
+        left->fWeights[0] = curve.fWeights[0];
+        right->fWeights[degree] = curve.fWeights[degree];
+
+        for (int k = 1; k <= degree; k++) {
+            // k is level of recursion, k-1 has previous level's values.
+            for (int i = degree; i >= k; i--) {
+                result.fWeights[i] = result.fWeights[i - 1] * (1 - t) + result.fWeights[i] * t;
+            }
+
+            left->fWeights[k] = result.fWeights[k];
+            right->fWeights[degree - k] = result.fWeights[degree];
+        }
+    }
+
+    /**
+     * Increases the degree of the curve to the given degree. Has no effect if the
+     * degree is already equal to the given degree.
+     *
+     * This process is always exact (NB the reverse, degree reduction, is not exact).
+     */
+    void elevateDegree(int newDegree) {
+        if (newDegree == fDegree) {
+            return;
+        }
+
+        fWeights = ElevateDegree(*this, newDegree).fWeights;
+        fDegree = newDegree;
+    }
+
+    /**
+     * Increases the degree of the curve to the given degree. Has no effect if the
+     * degree is already equal to the given degree.
+     *
+     * This process is always exact (NB the reverse, degree reduction, is not exact).
+     */
+    static ScalarBezCurve ElevateDegree(const ScalarBezCurve& curve, int newDegree) {
+        SkASSERT(newDegree >= curve.degree());
+        if (newDegree == curve.degree()) {
+            return curve;
+        }
+
+        // From Farouki, Rajan, "Algorithms for polynomials in Bernstein form" 1988.
+        ScalarBezCurve elevated(newDegree);
+        const int r = newDegree - curve.fDegree;
+        const int n = curve.fDegree;
+
+        for (int i = 0; i <= n + r; i++) {
+            elevated.fWeights[i] = 0;
+            for (int j = std::max(0, i - r); j <= std::min(n, i); j++) {
+                const float f =
+                        (choose(n, j) * choose(r, i - j)) / static_cast<float>(choose(n + r, i));
+                elevated.fWeights[i] += curve.fWeights[j] * f;
+            }
+        }
+
+        return elevated;
+    }
+
+    /**
+     * Returns the zero-set of this curve, which is a list of t values where the curve crosses 0.
+     */
+    std::vector<float> zeroSet() const { return ZeroSet(*this); }
+
+    /**
+     * Returns the zero-set of the curve, which is a list of t values where the curve crosses 0.
+     */
+    static std::vector<float> ZeroSet(const ScalarBezCurve& curve) {
+        constexpr float kTol = 0.001f;
+        std::vector<float> result;
+        ZeroSetRec(curve, 0, 1, kTol, &result);
+        return result;
+    }
+
+    /** Multiplies the curve's weights by a constant value */
+    static ScalarBezCurve Mul(const ScalarBezCurve& curve, float f) {
+        ScalarBezCurve result = curve;
+        for (int k = 0; k <= curve.fDegree; k++) {
+            result.fWeights[k] *= f;
+        }
+        return result;
+    }
+
+    /**
+     * Multiplies the two curves and returns the result.
+     *
+     * Degree of resulting curve is the sum of the degrees of the input curves.
+     */
+    static ScalarBezCurve Mul(const ScalarBezCurve& a, const ScalarBezCurve& b) {
+        // From G. Elber, "Free form surface analysis using a hybrid of symbolic and numeric
+        // computation". PhD thesis, 1992. p.11.
+        const int n = a.degree(), m = b.degree();
+        const int newDegree = n + m;
+        ScalarBezCurve result(newDegree);
+
+        for (int k = 0; k <= newDegree; k++) {
+            result.fWeights[k] = 0;
+            for (int i = std::max(0, k - n); i <= std::min(k, m); i++) {
+                const float f =
+                        (choose(m, i) * choose(n, k - i)) / static_cast<float>(choose(m + n, k));
+                result.fWeights[k] += a.fWeights[i] * b.fWeights[k - i] * f;
+            }
+        }
+
+        return result;
+    }
+
+    /** Returns a^2 + b^2. This is a specialized method because the loops are easily fused. */
+    static ScalarBezCurve AddSquares(const ScalarBezCurve& a, const ScalarBezCurve& b) {
+        const int n = a.degree(), m = b.degree();
+        const int newDegree = n + m;
+        ScalarBezCurve result(newDegree);
+
+        for (int k = 0; k <= newDegree; k++) {
+            float aSq = 0, bSq = 0;
+            for (int i = std::max(0, k - n); i <= std::min(k, m); i++) {
+                const float f =
+                        (choose(m, i) * choose(n, k - i)) / static_cast<float>(choose(m + n, k));
+                aSq += a.fWeights[i] * a.fWeights[k - i] * f;
+                bSq += b.fWeights[i] * b.fWeights[k - i] * f;
+            }
+            result.fWeights[k] = aSq + bSq;
+        }
+
+        return result;
+    }
+
+    /** Returns a - b. */
+    static ScalarBezCurve Sub(const ScalarBezCurve& a, const ScalarBezCurve& b) {
+        ScalarBezCurve result = a;
+        result.sub(b);
+        return result;
+    }
+
+    /** Subtracts the other curve from this curve */
+    void sub(const ScalarBezCurve& other) {
+        SkASSERT(other.fDegree == fDegree);
+        for (int k = 0; k <= fDegree; k++) {
+            fWeights[k] -= other.fWeights[k];
+        }
+    }
+
+    /** Subtracts a constant from this curve */
+    void sub(float f) {
+        for (int k = 0; k <= fDegree; k++) {
+            fWeights[k] -= f;
+        }
+    }
+
+    /** Returns the curve degree */
+    int degree() const { return fDegree; }
+
+    /** Returns the curve weights */
+    const std::vector<float>& weights() const { return fWeights; }
+
+    float operator[](size_t i) const { return fWeights[i]; }
+    float& operator[](size_t i) { return fWeights[i]; }
+
+private:
+    /** Recursive helper for ZeroSet */
+    static void ZeroSetRec(const ScalarBezCurve& curve,
+                           float tmin,
+                           float tmax,
+                           float tol,
+                           std::vector<float>* result) {
+        float lenP = 0;
+        bool allPos = curve.fWeights[0] >= 0, allNeg = curve.fWeights[0] < 0;
+        for (int i = 1; i <= curve.fDegree; i++) {
+            lenP += std::abs(curve.fWeights[i] - curve.fWeights[i - 1]);
+            allPos &= curve.fWeights[i] >= 0;
+            allNeg &= curve.fWeights[i] < 0;
+        }
+        if (lenP <= tol) {
+            result->push_back((tmin + tmax) * 0.5);
+            return;
+        } else if (allPos || allNeg) {
+            // No zero crossings possible if the coefficients don't change sign (convex hull
+            // property)
+            return;
+        } else if (SkScalarNearlyZero(tmax - tmin)) {
+            return;
+        } else {
+            ScalarBezCurve left(curve.fDegree), right(curve.fDegree);
+            Split(curve, 0.5f, &left, &right);
+
+            const float tmid = (tmin + tmax) * 0.5;
+            ZeroSetRec(left, tmin, tmid, tol, result);
+            ZeroSetRec(right, tmid, tmax, tol, result);
+        }
+    }
+
+    int fDegree;
+    std::vector<float> fWeights;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+/** Helper class that measures per-verb path lengths. */
+class PathVerbMeasure {
+public:
+    explicit PathVerbMeasure(const SkPath& path) : fPath(path), fIter(path, false) { nextVerb(); }
+
+    SkScalar totalLength() const;
+
+    SkScalar currentVerbLength() { return fMeas.getLength(); }
+
+    void nextVerb();
+
+private:
+    const SkPath& fPath;
+    SkPoint fFirstPointInContour;
+    SkPoint fPreviousPoint;
+    SkPath fCurrVerb;
+    SkPath::Iter fIter;
+    SkPathMeasure fMeas;
+};
+
+SkScalar PathVerbMeasure::totalLength() const {
+    SkPathMeasure meas(fPath, false);
+    return meas.getLength();
+}
+
+void PathVerbMeasure::nextVerb() {
+    SkPoint pts[4];
+    SkPath::Verb verb = fIter.next(pts);
+
+    while (verb == SkPath::kMove_Verb || verb == SkPath::kClose_Verb) {
+        if (verb == SkPath::kMove_Verb) {
+            fFirstPointInContour = pts[0];
+            fPreviousPoint = fFirstPointInContour;
+        }
+        verb = fIter.next(pts);
+    }
+
+    fCurrVerb.rewind();
+    fCurrVerb.moveTo(fPreviousPoint);
+    switch (verb) {
+        case SkPath::kLine_Verb:
+            fCurrVerb.lineTo(pts[1]);
+            break;
+        case SkPath::kQuad_Verb:
+            fCurrVerb.quadTo(pts[1], pts[2]);
+            break;
+        case SkPath::kCubic_Verb:
+            fCurrVerb.cubicTo(pts[1], pts[2], pts[3]);
+            break;
+        case SkPath::kConic_Verb:
+            fCurrVerb.conicTo(pts[1], pts[2], fIter.conicWeight());
+            break;
+        case SkPath::kDone_Verb:
+            break;
+        case SkPath::kClose_Verb:
+        case SkPath::kMove_Verb:
+            SkASSERT(false);
+            break;
+    }
+
+    fCurrVerb.getLastPt(&fPreviousPoint);
+    fMeas.setPath(&fCurrVerb, false);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+// Several debug-only visualization helpers
+namespace viz {
+std::unique_ptr<ScalarBezCurve> outerErr;
+SkPath outerFirstApprox;
+}  // namespace viz
+
+/**
+ * Prototype variable-width path stroker.
+ *
+ * Takes as input a path to be stroked, and two distance functions (inside and outside).
+ * Produces a fill path with the stroked path geometry.
+ *
+ * The algorithms in use here are from:
+ *
+ * G. Elber, E. Cohen. "Error bounded variable distance offset operator for free form curves and
+ * surfaces." International Journal of Computational Geometry & Applications 1, no. 01 (1991)
+ *
+ * G. Elber. "Free form surface analysis using a hybrid of symbolic and numeric computation."
+ * PhD diss., Dept. of Computer Science, University of Utah, 1992.
+ */
+class SkVarWidthStroker {
+public:
+    /** Metric to use for interpolation of distance function across path segments. */
+    enum class LengthMetric {
+        /** Each path segment gets an equal interval of t in [0,1] */
+        kNumSegments,
+        /** Each path segment gets t interval equal to its percent of the total path length */
+        kPathLength,
+    };
+
+    /**
+     * Strokes the path with a fixed-width distance function. This produces a traditional stroked
+     * path.
+     */
+    SkPath getFillPath(const SkPath& path, const SkPaint& paint) {
+        return getFillPath(path, paint, identityVarWidth(paint.getStrokeWidth()),
+                           identityVarWidth(paint.getStrokeWidth()));
+    }
+
+    /**
+     * Strokes the given path using the two given distance functions for inner and outer offsets.
+     */
+    SkPath getFillPath(const SkPath& path,
+                       const SkPaint& paint,
+                       const ScalarBezCurve& varWidth,
+                       const ScalarBezCurve& varWidthInner,
+                       LengthMetric lengthMetric = LengthMetric::kNumSegments);
+
+private:
+    /** Helper struct referring to a single segment of an SkPath */
+    struct PathSegment {
+        SkPath::Verb fVerb;
+        std::array<SkPoint, 4> fPoints;
+    };
+
+    struct OffsetSegments {
+        std::vector<PathSegment> fInner;
+        std::vector<PathSegment> fOuter;
+    };
+
+    /** Initialize stroker state */
+    void initForPath(const SkPath& path, const SkPaint& paint);
+
+    /** Strokes a path segment */
+    OffsetSegments strokeSegment(const PathSegment& segment,
+                                 const ScalarBezCurve& varWidth,
+                                 const ScalarBezCurve& varWidthInner,
+                                 bool needsMove);
+
+    /**
+     * Strokes the given segment using the given distance function.
+     *
+     * Returns a list of quad segments that approximate the offset curve.
+     * TODO: no reason this needs to return a vector of quads, can just append to the path
+     */
+    std::vector<PathSegment> strokeSegment(const PathSegment& seg,
+                                           const ScalarBezCurve& distanceFunc) const;
+
+    /** Adds an endcap to fOuter */
+    enum class CapLocation { Start, End };
+    void endcap(CapLocation loc);
+
+    /** Adds a join between the two segments */
+    void join(const SkPoint& common,
+              float innerRadius,
+              float outerRadius,
+              const OffsetSegments& prev,
+              const OffsetSegments& curr);
+
+    /** Appends path in reverse to result */
+    static void appendPathReversed(const SkPath& path, SkPath* result);
+
+    /** Returns the segment unit normal and unit tangent if not nullptr */
+    static SkPoint unitNormal(const PathSegment& seg, float t, SkPoint* tangentOut);
+
+    /** Returns the degree of a segment curve */
+    static int segmentDegree(const PathSegment& seg);
+
+    /** Splits a path segment at t */
+    static void splitSegment(const PathSegment& seg, float t, PathSegment* segA, PathSegment* segB);
+
+    /**
+     * Returns a quadratic segment that approximates the given segment using the given distance
+     * function.
+     */
+    static void approximateSegment(const PathSegment& seg,
+                                   const ScalarBezCurve& distFnc,
+                                   PathSegment* approxQuad);
+
+    /** Returns a constant (deg 0) distance function for the given stroke width */
+    static ScalarBezCurve identityVarWidth(float strokeWidth) {
+        return ScalarBezCurve(0, {strokeWidth / 2.0f});
+    }
+
+    float fRadius;
+    SkPaint::Cap fCap;
+    SkPaint::Join fJoin;
+    SkPath fInner, fOuter;
+    ScalarBezCurve fVarWidth, fVarWidthInner;
+    float fCurrT;
+};
+
+void SkVarWidthStroker::initForPath(const SkPath& path, const SkPaint& paint) {
+    fRadius = paint.getStrokeWidth() / 2;
+    fCap = paint.getStrokeCap();
+    fJoin = paint.getStrokeJoin();
+    fInner.rewind();
+    fOuter.rewind();
+    fCurrT = 0;
+}
+
+SkPath SkVarWidthStroker::getFillPath(const SkPath& path,
+                                      const SkPaint& paint,
+                                      const ScalarBezCurve& varWidth,
+                                      const ScalarBezCurve& varWidthInner,
+                                      LengthMetric lengthMetric) {
+    const auto appendStrokes = [this](const OffsetSegments& strokes, bool needsMove) {
+        if (needsMove) {
+            fOuter.moveTo(strokes.fOuter.front().fPoints[0]);
+            fInner.moveTo(strokes.fInner.front().fPoints[0]);
+        }
+
+        for (const PathSegment& seg : strokes.fOuter) {
+            fOuter.quadTo(seg.fPoints[1], seg.fPoints[2]);
+        }
+
+        for (const PathSegment& seg : strokes.fInner) {
+            fInner.quadTo(seg.fPoints[1], seg.fPoints[2]);
+        }
+    };
+
+    initForPath(path, paint);
+    fVarWidth = varWidth;
+    fVarWidthInner = varWidthInner;
+
+    // TODO: this assumes one contour:
+    PathVerbMeasure meas(path);
+    const float totalPathLength = lengthMetric == LengthMetric::kPathLength
+                                          ? meas.totalLength()
+                                          : (path.countVerbs() - 1);
+
+    // Trace the inner and outer paths simultaneously. Inner will therefore be
+    // recorded in reverse from how we trace the outline.
+    SkPath::Iter it(path, false);
+    PathSegment segment, prevSegment;
+    OffsetSegments offsetSegs, prevOffsetSegs;
+    bool firstSegment = true, prevWasFirst = false;
+
+    float lenTraveled = 0;
+    while ((segment.fVerb = it.next(&segment.fPoints[0])) != SkPath::kDone_Verb) {
+        const float verbLength = lengthMetric == LengthMetric::kPathLength
+                                         ? (meas.currentVerbLength() / totalPathLength)
+                                         : (1.0f / totalPathLength);
+        const float tmin = lenTraveled;
+        const float tmax = lenTraveled + verbLength;
+
+        // Subset the distance function for the current interval.
+        ScalarBezCurve partVarWidth, partVarWidthInner;
+        fVarWidth.split(tmin, tmax, &partVarWidth);
+        fVarWidthInner.split(tmin, tmax, &partVarWidthInner);
+        partVarWidthInner = ScalarBezCurve::Mul(partVarWidthInner, -1);
+
+        // Stroke the current segment
+        switch (segment.fVerb) {
+            case SkPath::kLine_Verb:
+            case SkPath::kQuad_Verb:
+            case SkPath::kCubic_Verb:
+                offsetSegs = strokeSegment(segment, partVarWidth, partVarWidthInner, firstSegment);
+                break;
+            case SkPath::kMove_Verb:
+                // Don't care about multiple contours currently
+                continue;
+            default:
+                SkDebugf("Unhandled path verb %d\n", segment.fVerb);
+                SkASSERT(false);
+                break;
+        }
+
+        // Join to the previous segment
+        if (!firstSegment) {
+            // Append prev inner and outer strokes
+            appendStrokes(prevOffsetSegs, prevWasFirst);
+
+            // Append the join
+            const float innerRadius = varWidthInner.eval(tmin);
+            const float outerRadius = varWidth.eval(tmin);
+            join(segment.fPoints[0], innerRadius, outerRadius, prevOffsetSegs, offsetSegs);
+        }
+
+        std::swap(segment, prevSegment);
+        std::swap(offsetSegs, prevOffsetSegs);
+        prevWasFirst = firstSegment;
+        firstSegment = false;
+        lenTraveled += verbLength;
+        meas.nextVerb();
+    }
+
+    // Finish appending final offset segments
+    appendStrokes(prevOffsetSegs, prevWasFirst);
+
+    // Open contour => endcap at the end
+    const bool isClosed = path.isLastContourClosed();
+    if (isClosed) {
+        SkDebugf("Unhandled closed contour\n");
+        SkASSERT(false);
+    } else {
+        endcap(CapLocation::End);
+    }
+
+    // Walk inner path in reverse, appending to result
+    appendPathReversed(fInner, &fOuter);
+    endcap(CapLocation::Start);
+
+    return fOuter;
+}
+
+SkVarWidthStroker::OffsetSegments SkVarWidthStroker::strokeSegment(
+        const PathSegment& segment,
+        const ScalarBezCurve& varWidth,
+        const ScalarBezCurve& varWidthInner,
+        bool needsMove) {
+    viz::outerErr.reset(nullptr);
+
+    std::vector<PathSegment> outer = strokeSegment(segment, varWidth);
+    std::vector<PathSegment> inner = strokeSegment(segment, varWidthInner);
+    return {inner, outer};
+}
+
+std::vector<SkVarWidthStroker::PathSegment> SkVarWidthStroker::strokeSegment(
+        const PathSegment& seg, const ScalarBezCurve& distanceFunc) const {
+    // Work item for the recursive splitting stack.
+    struct Item {
+        PathSegment fSeg;
+        ScalarBezCurve fDistFnc, fDistFncSqd;
+        ScalarBezCurve fSegX, fSegY;
+
+        Item(const PathSegment& seg,
+             const ScalarBezCurve& distFnc,
+             const ScalarBezCurve& distFncSqd)
+                : fSeg(seg), fDistFnc(distFnc), fDistFncSqd(distFncSqd) {
+            const int segDegree = segmentDegree(seg);
+            fSegX = ScalarBezCurve(segDegree);
+            fSegY = ScalarBezCurve(segDegree);
+            for (int i = 0; i <= segDegree; i++) {
+                fSegX[i] = seg.fPoints[i].fX;
+                fSegY[i] = seg.fPoints[i].fY;
+            }
+        }
+    };
+
+    // Push the initial segment and distance function
+    std::stack<Item> stack;
+    stack.push(Item(seg, distanceFunc, ScalarBezCurve::Mul(distanceFunc, distanceFunc)));
+
+    std::vector<PathSegment> result;
+    constexpr int kMaxIters = 5000; /** TODO: this is completely arbitrary */
+    int iter = 0;
+    while (!stack.empty()) {
+        if (iter++ >= kMaxIters) break;
+        const Item item = stack.top();
+        stack.pop();
+
+        const ScalarBezCurve& distFnc = item.fDistFnc;
+        ScalarBezCurve distFncSqd = item.fDistFncSqd;
+        const float kTol = std::abs(0.5f * distFnc.extremumWeight());
+
+        // Compute a quad that approximates stroke outline
+        PathSegment quadApprox;
+        approximateSegment(item.fSeg, distFnc, &quadApprox);
+        ScalarBezCurve quadApproxX(2), quadApproxY(2);
+        for (int i = 0; i < 3; i++) {
+            quadApproxX[i] = quadApprox.fPoints[i].fX;
+            quadApproxY[i] = quadApprox.fPoints[i].fY;
+        }
+
+        // Compute control polygon for the delta(t) curve. First must elevate to a common degree.
+        const int deltaDegree = std::max(quadApproxX.degree(), item.fSegX.degree());
+        ScalarBezCurve segX = item.fSegX, segY = item.fSegY;
+        segX.elevateDegree(deltaDegree);
+        segY.elevateDegree(deltaDegree);
+        quadApproxX.elevateDegree(deltaDegree);
+        quadApproxY.elevateDegree(deltaDegree);
+
+        ScalarBezCurve deltaX = ScalarBezCurve::Sub(quadApproxX, segX);
+        ScalarBezCurve deltaY = ScalarBezCurve::Sub(quadApproxY, segY);
+
+        // Compute psi(t) = delta_x(t)^2 + delta_y(t)^2.
+        ScalarBezCurve E = ScalarBezCurve::AddSquares(deltaX, deltaY);
+
+        // Promote E and d(t)^2 to a common degree.
+        const int commonDeg = std::max(distFncSqd.degree(), E.degree());
+        distFncSqd.elevateDegree(commonDeg);
+        E.elevateDegree(commonDeg);
+
+        // Subtract dist squared curve from E, resulting in:
+        //   eps(t) = delta_x(t)^2 + delta_y(t)^2 - d(t)^2
+        E.sub(distFncSqd);
+
+        // Purely for debugging/testing, save the first approximation and error function:
+        if (viz::outerErr == nullptr) {
+            using namespace viz;
+            outerErr = std::make_unique<ScalarBezCurve>(E);
+            outerFirstApprox.rewind();
+            outerFirstApprox.moveTo(quadApprox.fPoints[0]);
+            outerFirstApprox.quadTo(quadApprox.fPoints[1], quadApprox.fPoints[2]);
+        }
+
+        // Compute maxErr, which is just the max coefficient of eps (using convex hull property
+        // of bez curves)
+        float maxAbsErr = std::abs(E.extremumWeight());
+
+        if (maxAbsErr > kTol) {
+            PathSegment left, right;
+            splitSegment(item.fSeg, 0.5f, &left, &right);
+
+            ScalarBezCurve distFncL, distFncR;
+            distFnc.split(0.5f, &distFncL, &distFncR);
+
+            ScalarBezCurve distFncSqdL, distFncSqdR;
+            distFncSqd.split(0.5f, &distFncSqdL, &distFncSqdR);
+
+            stack.push(Item(right, distFncR, distFncSqdR));
+            stack.push(Item(left, distFncL, distFncSqdL));
+        } else {
+            // Approximation is good enough.
+            quadApprox.fVerb = SkPath::kQuad_Verb;
+            result.push_back(quadApprox);
+        }
+    }
+    SkASSERT(!result.empty());
+    return result;
+}
+
+void SkVarWidthStroker::endcap(CapLocation loc) {
+    const auto buttCap = [this](CapLocation loc) {
+        if (loc == CapLocation::Start) {
+            // Back at the start of the path: just close the stroked outline
+            fOuter.close();
+        } else {
+            // Inner last pt == first pt when appending in reverse
+            SkPoint innerLastPt;
+            fInner.getLastPt(&innerLastPt);
+            fOuter.lineTo(innerLastPt);
+        }
+    };
+
+    switch (fCap) {
+        case SkPaint::kButt_Cap:
+            buttCap(loc);
+            break;
+        default:
+            SkDebugf("Unhandled endcap %d\n", fCap);
+            buttCap(loc);
+            break;
+    }
+}
+
+void SkVarWidthStroker::join(const SkPoint& common,
+                             float innerRadius,
+                             float outerRadius,
+                             const OffsetSegments& prev,
+                             const OffsetSegments& curr) {
+    const auto miterJoin = [this](const SkPoint& common,
+                                  float leftRadius,
+                                  float rightRadius,
+                                  const OffsetSegments& prev,
+                                  const OffsetSegments& curr) {
+        // With variable-width stroke you can actually have a situation where both sides
+        // need an "inner" or an "outer" join. So we call the two sides "left" and
+        // "right" and they can each independently get an inner or outer join.
+        const auto makeJoin = [this, &common, &prev, &curr](bool left, float radius) {
+            SkPath* path = left ? &fOuter : &fInner;
+            const auto& prevSegs = left ? prev.fOuter : prev.fInner;
+            const auto& currSegs = left ? curr.fOuter : curr.fInner;
+            SkASSERT(!prevSegs.empty());
+            SkASSERT(!currSegs.empty());
+            const SkPoint afterEndpt = currSegs.front().fPoints[0];
+            SkPoint before = unitNormal(prevSegs.back(), 1, nullptr);
+            SkPoint after = unitNormal(currSegs.front(), 0, nullptr);
+
+            // Don't create any join geometry if the normals are nearly identical.
+            const float cosTheta = before.dot(after);
+            if (!SkScalarNearlyZero(1 - cosTheta)) {
+                bool outerJoin;
+                if (left) {
+                    outerJoin = isClockwise(before, after);
+                } else {
+                    before = rotate180(before);
+                    after = rotate180(after);
+                    outerJoin = !isClockwise(before, after);
+                }
+
+                if (outerJoin) {
+                    // Before and after have the same origin and magnitude, so before+after is the
+                    // diagonal of their rhombus. Origin of this vector is the midpoint of the miter
+                    // line.
+                    SkPoint miterVec = before + after;
+
+                    // Note the relationship (draw a right triangle with the miter line as its
+                    // hypoteneuse):
+                    //     sin(theta/2) = strokeWidth / miterLength
+                    // so miterLength = strokeWidth / sin(theta/2)
+                    // where miterLength is the length of the miter from outer point to inner
+                    // corner. miterVec's origin is the midpoint of the miter line, so we use
+                    // strokeWidth/2. Sqrt is just an application of half-angle identities.
+                    const float sinHalfTheta = sqrtf(0.5 * (1 + cosTheta));
+                    const float halfMiterLength = radius / sinHalfTheta;
+                    // TODO: miter length limit
+                    miterVec = setLength(miterVec, halfMiterLength);
+
+                    // Outer join: connect to the miter point, and then to t=0 of next segment.
+                    path->lineTo(common + miterVec);
+                    path->lineTo(afterEndpt);
+                } else {
+                    // Connect to the miter midpoint (common path endpoint of the two segments),
+                    // and then to t=0 of the next segment. This adds an interior "loop"
+                    // of geometry that handles edge cases where segment lengths are shorter than
+                    // the stroke width.
+                    path->lineTo(common);
+                    path->lineTo(afterEndpt);
+                }
+            }
+        };
+
+        makeJoin(true, leftRadius);
+        makeJoin(false, rightRadius);
+    };
+
+    switch (fJoin) {
+        case SkPaint::kMiter_Join:
+            miterJoin(common, innerRadius, outerRadius, prev, curr);
+            break;
+        default:
+            SkDebugf("Unhandled join %d\n", fJoin);
+            miterJoin(common, innerRadius, outerRadius, prev, curr);
+            break;
+    }
+}
+
+void SkVarWidthStroker::appendPathReversed(const SkPath& path, SkPath* result) {
+    const int numVerbs = path.countVerbs();
+    const int numPoints = path.countPoints();
+    std::vector<uint8_t> verbs;
+    std::vector<SkPoint> points;
+    verbs.resize(numVerbs);
+    points.resize(numPoints);
+    path.getVerbs(verbs.data(), numVerbs);
+    path.getPoints(points.data(), numPoints);
+
+    for (int i = numVerbs - 1, j = numPoints; i >= 0; i--) {
+        auto verb = static_cast<SkPath::Verb>(verbs[i]);
+        switch (verb) {
+            case SkPath::kLine_Verb: {
+                j -= 1;
+                SkASSERT(j >= 1);
+                result->lineTo(points[j - 1]);
+                break;
+            }
+            case SkPath::kQuad_Verb: {
+                j -= 1;
+                SkASSERT(j >= 2);
+                result->quadTo(points[j - 1], points[j - 2]);
+                j -= 1;
+                break;
+            }
+            case SkPath::kMove_Verb:
+                // Ignore
+                break;
+            default:
+                SkASSERT(false);
+                break;
+        }
+    }
+}
+
+int SkVarWidthStroker::segmentDegree(const PathSegment& seg) {
+    static constexpr int lut[] = {
+            -1,  // move,
+            1,   // line
+            2,   // quad
+            -1,  // conic
+            3,   // cubic
+            -1   // done
+    };
+    const int deg = lut[static_cast<uint8_t>(seg.fVerb)];
+    SkASSERT(deg > 0);
+    return deg;
+}
+
+void SkVarWidthStroker::splitSegment(const PathSegment& seg,
+                                     float t,
+                                     PathSegment* segA,
+                                     PathSegment* segB) {
+    // TODO: although general, this is a pretty slow way to do this
+    const int degree = segmentDegree(seg);
+    ScalarBezCurve x(degree), y(degree);
+    for (int i = 0; i <= degree; i++) {
+        x[i] = seg.fPoints[i].fX;
+        y[i] = seg.fPoints[i].fY;
+    }
+
+    ScalarBezCurve leftX(degree), rightX(degree), leftY(degree), rightY(degree);
+    x.split(t, &leftX, &rightX);
+    y.split(t, &leftY, &rightY);
+
+    segA->fVerb = segB->fVerb = seg.fVerb;
+    for (int i = 0; i <= degree; i++) {
+        segA->fPoints[i] = {leftX[i], leftY[i]};
+        segB->fPoints[i] = {rightX[i], rightY[i]};
+    }
+}
+
+void SkVarWidthStroker::approximateSegment(const PathSegment& seg,
+                                           const ScalarBezCurve& distFnc,
+                                           PathSegment* approxQuad) {
+    // This is a simple control polygon transformation.
+    // From F. Yzerman. "Precise offsetting of quadratic Bezier curves". 2019.
+    // TODO: detect and handle more degenerate cases (e.g. linear)
+    // TODO: Tiller-Hanson works better in many cases but does not generalize well
+    SkPoint tangentStart, tangentEnd;
+    SkPoint offsetStart = unitNormal(seg, 0, &tangentStart);
+    SkPoint offsetEnd = unitNormal(seg, 1, &tangentEnd);
+    SkPoint offsetMid = offsetStart + offsetEnd;
+
+    const float radiusStart = distFnc.eval(0);
+    const float radiusMid = distFnc.eval(0.5f);
+    const float radiusEnd = distFnc.eval(1);
+
+    offsetStart = radiusStart == 0 ? SkPoint::Make(0, 0) : setLength(offsetStart, radiusStart);
+    offsetMid = radiusMid == 0 ? SkPoint::Make(0, 0) : setLength(offsetMid, radiusMid);
+    offsetEnd = radiusEnd == 0 ? SkPoint::Make(0, 0) : setLength(offsetEnd, radiusEnd);
+
+    SkPoint start, mid, end;
+    switch (segmentDegree(seg)) {
+        case 1:
+            start = seg.fPoints[0];
+            end = seg.fPoints[1];
+            mid = (start + end) * 0.5f;
+            break;
+        case 2:
+            start = seg.fPoints[0];
+            mid = seg.fPoints[1];
+            end = seg.fPoints[2];
+            break;
+        case 3:
+            start = seg.fPoints[0];
+            mid = (seg.fPoints[1] + seg.fPoints[2]) * 0.5f;
+            end = seg.fPoints[3];
+            break;
+        default:
+            SkDebugf("Unhandled degree for segment approximation");
+            SkASSERT(false);
+            break;
+    }
+
+    approxQuad->fPoints[0] = start + offsetStart;
+    approxQuad->fPoints[1] = mid + offsetMid;
+    approxQuad->fPoints[2] = end + offsetEnd;
+}
+
+SkPoint SkVarWidthStroker::unitNormal(const PathSegment& seg, float t, SkPoint* tangentOut) {
+    switch (seg.fVerb) {
+        case SkPath::kLine_Verb: {
+            const SkPoint tangent = setLength(seg.fPoints[1] - seg.fPoints[0], 1);
+            const SkPoint normal = rotate90(tangent);
+            if (tangentOut) {
+                *tangentOut = tangent;
+            }
+            return normal;
+        }
+        case SkPath::kQuad_Verb: {
+            SkPoint tangent;
+            if (t == 0) {
+                tangent = seg.fPoints[1] - seg.fPoints[0];
+            } else if (t == 1) {
+                tangent = seg.fPoints[2] - seg.fPoints[1];
+            } else {
+                tangent = ((seg.fPoints[1] - seg.fPoints[0]) * (1 - t) +
+                           (seg.fPoints[2] - seg.fPoints[1]) * t) *
+                          2;
+            }
+            if (!tangent.normalize()) {
+                SkDebugf("Failed to normalize quad tangent\n");
+                SkASSERT(false);
+            }
+            if (tangentOut) {
+                *tangentOut = tangent;
+            }
+            return rotate90(tangent);
+        }
+        case SkPath::kCubic_Verb: {
+            SkPoint tangent;
+            SkEvalCubicAt(seg.fPoints.data(), t, nullptr, &tangent, nullptr);
+            if (!tangent.normalize()) {
+                SkDebugf("Failed to normalize cubic tangent\n");
+                SkASSERT(false);
+            }
+            if (tangentOut) {
+                *tangentOut = tangent;
+            }
+            return rotate90(tangent);
+        }
+        default:
+            SkDebugf("Unhandled verb for unit normal %d\n", seg.fVerb);
+            SkASSERT(false);
+            return {};
+    }
+}
+
+}  // namespace
+
+//////////////////////////////////////////////////////////////////////////////
+
+class VariableWidthStroker : public Sample {
+public:
+    VariableWidthStroker()
+            : fShowHidden(true)
+            , fShowSkeleton(true)
+            , fShowStrokePoints(false)
+            , fShowUI(false)
+            , fDifferentInnerFunc(false)
+            , fShowErrorCurve(false) {
+        resetToDefaults();
+
+        fPtsPaint.setAntiAlias(true);
+        fPtsPaint.setStrokeWidth(10);
+        fPtsPaint.setStrokeCap(SkPaint::kRound_Cap);
+
+        fStrokePointsPaint.setAntiAlias(true);
+        fStrokePointsPaint.setStrokeWidth(5);
+        fStrokePointsPaint.setStrokeCap(SkPaint::kRound_Cap);
+
+        fStrokePaint.setAntiAlias(true);
+        fStrokePaint.setStyle(SkPaint::kStroke_Style);
+        fStrokePaint.setColor(0x80FF0000);
+
+        fNewFillPaint.setAntiAlias(true);
+        fNewFillPaint.setColor(0x8000FF00);
+
+        fHiddenPaint.setAntiAlias(true);
+        fHiddenPaint.setStyle(SkPaint::kStroke_Style);
+        fHiddenPaint.setColor(0xFF0000FF);
+
+        fSkeletonPaint.setAntiAlias(true);
+        fSkeletonPaint.setStyle(SkPaint::kStroke_Style);
+        fSkeletonPaint.setColor(SK_ColorRED);
+    }
+
+private:
+    /** Selectable menu item for choosing distance functions */
+    struct DistFncMenuItem {
+        std::string fName;
+        int fDegree;
+        bool fSelected;
+        std::vector<float> fWeights;
+
+        DistFncMenuItem(const std::string& name, int degree, bool selected) {
+            fName = name;
+            fDegree = degree;
+            fSelected = selected;
+            fWeights.resize(degree + 1, 1.0f);
+        }
+    };
+
+    SkString name() override { return SkString("VariableWidthStroker"); }
+
+    void onSizeChange() override {
+        fWinSize = SkSize::Make(this->width(), this->height());
+        INHERITED::onSizeChange();
+    }
+
+    bool onChar(SkUnichar uni) override {
+        switch (uni) {
+            case '0':
+                this->toggle(fShowUI);
+                return true;
+            case '1':
+                this->toggle(fShowSkeleton);
+                return true;
+            case '2':
+                this->toggle(fShowHidden);
+                return true;
+            case '3':
+                this->toggle(fShowStrokePoints);
+                return true;
+            case '4':
+                this->toggle(fShowErrorCurve);
+                return true;
+            case '5':
+                this->toggle(fLengthMetric);
+                return true;
+            case 'x':
+                resetToDefaults();
+                return true;
+            case '-':
+                fWidth -= 5;
+                return true;
+            case '=':
+                fWidth += 5;
+                return true;
+            default:
+                break;
+        }
+        return false;
+    }
+
+    void toggle(bool& value) { value = !value; }
+    void toggle(SkVarWidthStroker::LengthMetric& value) {
+        value = value == SkVarWidthStroker::LengthMetric::kPathLength
+                        ? SkVarWidthStroker::LengthMetric::kNumSegments
+                        : SkVarWidthStroker::LengthMetric::kPathLength;
+    }
+
+    void resetToDefaults() {
+        fPathPts[0] = {300, 400};
+        fPathPts[1] = {500, 400};
+        fPathPts[2] = {700, 400};
+        fPathPts[3] = {900, 400};
+        fPathPts[4] = {1100, 400};
+
+        fWidth = 175;
+
+        fLengthMetric = SkVarWidthStroker::LengthMetric::kPathLength;
+        fDistFncs = fDefaultsDistFncs;
+        fDistFncsInner = fDefaultsDistFncs;
+    }
+
+    void makePath(SkPath* path) {
+        path->moveTo(fPathPts[0]);
+        path->quadTo(fPathPts[1], fPathPts[2]);
+        path->quadTo(fPathPts[3], fPathPts[4]);
+    }
+
+    static ScalarBezCurve makeDistFnc(const std::vector<DistFncMenuItem>& fncs, float strokeWidth) {
+        const float radius = strokeWidth / 2;
+        for (const auto& df : fncs) {
+            if (df.fSelected) {
+                return ScalarBezCurve::Mul(ScalarBezCurve(df.fDegree, df.fWeights), radius);
+            }
+        }
+        SkASSERT(false);
+        return ScalarBezCurve(0, {radius});
+    }
+
+    void onDrawContent(SkCanvas* canvas) override {
+        canvas->drawColor(0xFFEEEEEE);
+
+        SkPath path;
+        this->makePath(&path);
+
+        fStrokePaint.setStrokeWidth(fWidth);
+
+        // Elber-Cohen stroker result
+        ScalarBezCurve distFnc = makeDistFnc(fDistFncs, fWidth);
+        ScalarBezCurve distFncInner =
+                fDifferentInnerFunc ? makeDistFnc(fDistFncsInner, fWidth) : distFnc;
+        SkVarWidthStroker stroker;
+        SkPath fillPath =
+                stroker.getFillPath(path, fStrokePaint, distFnc, distFncInner, fLengthMetric);
+        fillPath.setFillType(SkPathFillType::kWinding);
+        canvas->drawPath(fillPath, fNewFillPaint);
+
+        if (fShowHidden) {
+            canvas->drawPath(fillPath, fHiddenPaint);
+        }
+
+        if (fShowSkeleton) {
+            canvas->drawPath(path, fSkeletonPaint);
+            canvas->drawPoints(SkCanvas::kPoints_PointMode, fPathPts.size(), fPathPts.data(),
+                               fPtsPaint);
+        }
+
+        if (fShowStrokePoints) {
+            drawStrokePoints(canvas, fillPath);
+        }
+
+        if (fShowUI) {
+            drawUI();
+        }
+
+        if (fShowErrorCurve && viz::outerErr != nullptr) {
+            SkPaint firstApproxPaint;
+            firstApproxPaint.setStrokeWidth(4);
+            firstApproxPaint.setStyle(SkPaint::kStroke_Style);
+            firstApproxPaint.setColor(SK_ColorRED);
+            canvas->drawPath(viz::outerFirstApprox, firstApproxPaint);
+            drawErrorCurve(canvas, *viz::outerErr);
+        }
+    }
+
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
+        const SkScalar tol = 4;
+        const SkRect r = SkRect::MakeXYWH(x - tol, y - tol, tol * 2, tol * 2);
+        for (size_t i = 0; i < fPathPts.size(); ++i) {
+            if (r.intersects(SkRect::MakeXYWH(fPathPts[i].fX, fPathPts[i].fY, 1, 1))) {
+                return new Click([this, i](Click* c) {
+                    fPathPts[i] = c->fCurr;
+                    return true;
+                });
+            }
+        }
+        return nullptr;
+    }
+
+    void drawStrokePoints(SkCanvas* canvas, const SkPath& fillPath) {
+        SkPath::Iter it(fillPath, false);
+        SkPoint points[4];
+        SkPath::Verb verb;
+        std::vector<SkPoint> pointsVec, ctrlPts;
+        while ((verb = it.next(&points[0])) != SkPath::kDone_Verb) {
+            switch (verb) {
+                case SkPath::kLine_Verb:
+                    pointsVec.push_back(points[1]);
+                    break;
+                case SkPath::kQuad_Verb:
+                    ctrlPts.push_back(points[1]);
+                    pointsVec.push_back(points[2]);
+                    break;
+                case SkPath::kMove_Verb:
+                    pointsVec.push_back(points[0]);
+                    break;
+                case SkPath::kClose_Verb:
+                    break;
+                default:
+                    SkDebugf("Unhandled path verb %d for stroke points\n", verb);
+                    SkASSERT(false);
+                    break;
+            }
+        }
+
+        canvas->drawPoints(SkCanvas::kPoints_PointMode, pointsVec.size(), pointsVec.data(),
+                           fStrokePointsPaint);
+        fStrokePointsPaint.setColor(SK_ColorBLUE);
+        fStrokePointsPaint.setStrokeWidth(3);
+        canvas->drawPoints(SkCanvas::kPoints_PointMode, ctrlPts.size(), ctrlPts.data(),
+                           fStrokePointsPaint);
+        fStrokePointsPaint.setColor(SK_ColorBLACK);
+        fStrokePointsPaint.setStrokeWidth(5);
+    }
+
+    void drawErrorCurve(SkCanvas* canvas, const ScalarBezCurve& E) {
+        const float winW = fWinSize.width() * 0.75f, winH = fWinSize.height() * 0.25f;
+        const float padding = 25;
+        const SkRect box = SkRect::MakeXYWH(padding, fWinSize.height() - winH - padding,
+                                            winW - 2 * padding, winH);
+        constexpr int nsegs = 100;
+        constexpr float dt = 1.0f / nsegs;
+        constexpr float dx = 10.0f;
+        const int deg = E.degree();
+        SkPath path;
+        for (int i = 0; i < nsegs; i++) {
+            const float tmin = i * dt, tmax = (i + 1) * dt;
+            ScalarBezCurve left(deg), right(deg);
+            E.split(tmax, &left, &right);
+            const float tRel = tmin / tmax;
+            ScalarBezCurve rl(deg), rr(deg);
+            left.split(tRel, &rl, &rr);
+
+            const float x = i * dx;
+            if (i == 0) {
+                path.moveTo(x, -rr[0]);
+            }
+            path.lineTo(x + dx, -rr[deg]);
+        }
+
+        SkPaint paint;
+        paint.setStyle(SkPaint::kStroke_Style);
+        paint.setAntiAlias(true);
+        paint.setStrokeWidth(0);
+        paint.setColor(SK_ColorRED);
+        const SkRect pathBounds = path.computeTightBounds();
+        constexpr float yAxisMax = 8000;
+        const float sx = box.width() / pathBounds.width();
+        const float sy = box.height() / (2 * yAxisMax);
+        canvas->save();
+        canvas->translate(box.left(), box.top() + box.height() / 2);
+        canvas->scale(sx, sy);
+        canvas->drawPath(path, paint);
+
+        SkPath axes;
+        axes.moveTo(0, 0);
+        axes.lineTo(pathBounds.width(), 0);
+        axes.moveTo(0, -yAxisMax);
+        axes.lineTo(0, yAxisMax);
+        paint.setColor(SK_ColorBLACK);
+        paint.setAntiAlias(false);
+        canvas->drawPath(axes, paint);
+
+        canvas->restore();
+    }
+
+    void drawUI() {
+        static constexpr auto kUIOpacity = 0.35f;
+        static constexpr float kUIWidth = 200.0f, kUIHeight = 400.0f;
+        ImGui::SetNextWindowBgAlpha(kUIOpacity);
+        if (ImGui::Begin("E-C Controls", nullptr,
+                         ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize |
+                                 ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings |
+                                 ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav)) {
+            const SkRect uiArea = SkRect::MakeXYWH(10, 10, kUIWidth, kUIHeight);
+            ImGui::SetWindowPos(ImVec2(uiArea.x(), uiArea.y()));
+            ImGui::SetWindowSize(ImVec2(uiArea.width(), uiArea.height()));
+
+            const auto drawControls = [](std::vector<DistFncMenuItem>& distFncs,
+                                         const std::string& menuPfx,
+                                         const std::string& ptPfx) {
+                std::string degreeMenuLabel = menuPfx + ": ";
+                for (const auto& df : distFncs) {
+                    if (df.fSelected) {
+                        degreeMenuLabel += df.fName;
+                        break;
+                    }
+                }
+                if (ImGui::BeginMenu(degreeMenuLabel.c_str())) {
+                    for (size_t i = 0; i < distFncs.size(); i++) {
+                        if (ImGui::MenuItem(distFncs[i].fName.c_str(), nullptr,
+                                            distFncs[i].fSelected)) {
+                            for (size_t j = 0; j < distFncs.size(); j++) {
+                                distFncs[j].fSelected = j == i;
+                            }
+                        }
+                    }
+                    ImGui::EndMenu();
+                }
+
+                for (auto& df : distFncs) {
+                    if (df.fSelected) {
+                        for (int i = 0; i <= df.fDegree; i++) {
+                            const std::string label = ptPfx + std::to_string(i);
+                            ImGui::SliderFloat(label.c_str(), &(df.fWeights[i]), 0, 1);
+                        }
+                    }
+                }
+            };
+
+            const std::array<std::pair<std::string, SkVarWidthStroker::LengthMetric>, 2> metrics = {
+                    std::make_pair("% path length", SkVarWidthStroker::LengthMetric::kPathLength),
+                    std::make_pair("% segment count",
+                                   SkVarWidthStroker::LengthMetric::kNumSegments),
+            };
+            if (ImGui::BeginMenu("Interpolation metric:")) {
+                for (const auto& metric : metrics) {
+                    if (ImGui::MenuItem(metric.first.c_str(), nullptr,
+                                        fLengthMetric == metric.second)) {
+                        fLengthMetric = metric.second;
+                    }
+                }
+                ImGui::EndMenu();
+            }
+
+            drawControls(fDistFncs, "Degree", "P");
+
+            if (ImGui::CollapsingHeader("Inner stroke", true)) {
+                fDifferentInnerFunc = true;
+                drawControls(fDistFncsInner, "Degree (inner)", "Q");
+            } else {
+                fDifferentInnerFunc = false;
+            }
+        }
+        ImGui::End();
+    }
+
+    bool fShowHidden, fShowSkeleton, fShowStrokePoints, fShowUI, fDifferentInnerFunc,
+            fShowErrorCurve;
+    float fWidth = 175;
+    SkPaint fPtsPaint, fStrokePaint, fNewFillPaint, fHiddenPaint, fSkeletonPaint,
+            fStrokePointsPaint;
+    inline static constexpr int kNPts = 5;
+    std::array<SkPoint, kNPts> fPathPts;
+    SkSize fWinSize;
+    SkVarWidthStroker::LengthMetric fLengthMetric;
+    const std::vector<DistFncMenuItem> fDefaultsDistFncs = {
+            DistFncMenuItem("Linear", 1, true), DistFncMenuItem("Quadratic", 2, false),
+            DistFncMenuItem("Cubic", 3, false), DistFncMenuItem("One Louder (11)", 11, false),
+            DistFncMenuItem("30?!", 30, false)};
+    std::vector<DistFncMenuItem> fDistFncs = fDefaultsDistFncs;
+    std::vector<DistFncMenuItem> fDistFncsInner = fDefaultsDistFncs;
+
+    using INHERITED = Sample;
+};
+
+DEF_SAMPLE(return new VariableWidthStroker;)
diff --git a/third_party/skia/samplecode/SampleVertices.cpp b/third_party/skia/samplecode/SampleVertices.cpp
index 25afd41..d2c7fea 100644
--- a/third_party/skia/samplecode/SampleVertices.cpp
+++ b/third_party/skia/samplecode/SampleVertices.cpp
@@ -34,7 +34,8 @@
     pixels[0] = pixels[2] = color0;
     pixels[1] = pixels[3] = color1;
 
-    return bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat);
+    return bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
+                         SkSamplingOptions(SkFilterMode::kLinear));
 }
 
 static sk_sp<SkShader> make_shader1(const SkIPoint& size) {
@@ -73,7 +74,6 @@
     void onDrawContent(SkCanvas* canvas) override {
         SkPaint paint;
         paint.setDither(true);
-        paint.setFilterQuality(kLow_SkFilterQuality);
 
         for (size_t i = 0; i < SK_ARRAY_COUNT(fRecs); i++) {
             auto verts = SkVertices::MakeCopy(fRecs[i].fMode, fRecs[i].fCount,
@@ -204,7 +204,7 @@
 
     Rec fRecs[3];
 
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleWritePixels.cpp b/third_party/skia/samplecode/SampleWritePixels.cpp
index f6d31e5..eeed376 100644
--- a/third_party/skia/samplecode/SampleWritePixels.cpp
+++ b/third_party/skia/samplecode/SampleWritePixels.cpp
@@ -32,9 +32,9 @@
     WritePixelsView() {}
 
 protected:
-    virtual SkString name() { return SkString("WritePixels"); }
+    SkString name() override { return SkString("WritePixels"); }
 
-    virtual void onDrawContent(SkCanvas* canvas) {
+    void onDrawContent(SkCanvas* canvas) override {
         SkBitmap bitmap;
         create_bitmap(&bitmap);
         int x = bitmap.width() / 2;
@@ -50,7 +50,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/third_party/skia/samplecode/SampleXfer.cpp b/third_party/skia/samplecode/SampleXfer.cpp
index ba0a939..68b179e 100644
--- a/third_party/skia/samplecode/SampleXfer.cpp
+++ b/third_party/skia/samplecode/SampleXfer.cpp
@@ -193,9 +193,114 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
+DEF_SAMPLE( return new XferDemo; )
 
 //////////////////////////////////////////////////////////////////////////////
 
-DEF_SAMPLE( return new XferDemo; )
+#include "tools/Resources.h"
+
+class CubicResamplerDemo : public Sample {
+    struct Rec {
+        sk_sp<SkImage>  fImage;
+        SkRect          fBounds;
+
+        void draw(SkCanvas* canvas, SkCubicResampler cubic) const {
+            SkRect r = fBounds;
+            SkPaint paint;
+
+            SkMatrix lm = SkMatrix::Translate(r.x(), r.y())
+                        * SkMatrix::Scale(10, 10);
+            paint.setShader(fImage->makeShader(SkSamplingOptions(), lm));
+            canvas->drawRect(r, paint);
+
+            r.offset(r.width() + 10, 0);
+            lm.postTranslate(r.width() + 10, 0);
+
+            paint.setShader(fImage->makeShader(SkSamplingOptions(SkFilterMode::kLinear), lm));
+            canvas->drawRect(r, paint);
+
+            r.offset(r.width() + 10, 0);
+            lm.postTranslate(r.width() + 10, 0);
+
+            paint.setShader(fImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp,
+                                               SkSamplingOptions(cubic), &lm));
+            canvas->drawRect(r, paint);
+        }
+    };
+    std::vector<Rec> fRecs;
+
+public:
+    CubicResamplerDemo() {
+        const char* names[] = {
+            "images/mandrill_128.png",
+            "images/rle.bmp",
+            "images/example_4.png",
+        };
+        SkRect r = {10, 10, 200, 200};
+        for (auto name : names) {
+            fRecs.push_back({GetResourceAsImage(name), r});
+            r.offset(0, r.height() + 10);
+        }
+
+        fDomain.setXYWH(r.fLeft + 3*r.width() + 40, 50, 200, 200);
+        fCubic = {.3f, .5f};
+    }
+
+protected:
+    SkString name() override { return SkString("CubicResampler"); }
+
+    void onDrawContent(SkCanvas* canvas) override {
+        for (const auto& rec : fRecs) {
+            rec.draw(canvas, fCubic);
+        }
+
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setStroke(true);
+        canvas->drawRect(fDomain, paint);
+
+        paint.setColor(SK_ColorRED);
+        paint.setStroke(false);
+        SkPoint loc = SkMatrix::RectToRect({0,0,1,1}, fDomain).mapXY(fCubic.B, fCubic.C);
+        canvas->drawCircle(loc.fX, loc.fY, 8, paint);
+
+        SkString str;
+        str.printf("B=%4.2f  C=%4.2f", fCubic.B, fCubic.C);
+        SkFont font;
+        font.setSize(25);
+        font.setEdging(SkFont::Edging::kAntiAlias);
+        paint.setColor(SK_ColorBLACK);
+        canvas->drawSimpleText(str.c_str(), str.size(), SkTextEncoding::kUTF8,
+                               fDomain.fLeft + 10, fDomain.fBottom + 40, font, paint);
+    }
+
+    static float pin_unitize(float min, float max, float value) {
+        return (std::min(std::max(value, min), max) - min) / (max - min);
+    }
+    static SkPoint pin_unitize(const SkRect& r, SkPoint p) {
+        return {
+            pin_unitize(r.fLeft, r.fRight,  p.fX),
+            pin_unitize(r.fTop,  r.fBottom, p.fY),
+        };
+    }
+
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override {
+        if (fDomain.contains(x, y)) {
+            return new Click([this](Click* click) {
+                auto [B, C] = pin_unitize(fDomain, click->fCurr);
+                fCubic = {B, C};
+                return true;
+            });
+        }
+        return nullptr;
+    }
+
+private:
+    SkRect                  fDomain;
+    SkImage::CubicResampler fCubic;
+
+    using INHERITED = Sample;
+};
+DEF_SAMPLE( return new CubicResamplerDemo; )
diff --git a/third_party/skia/samplecode/SampleXfermodesBlur.cpp b/third_party/skia/samplecode/SampleXfermodesBlur.cpp
index 9ec35dc..bd603d5 100644
--- a/third_party/skia/samplecode/SampleXfermodesBlur.cpp
+++ b/third_party/skia/samplecode/SampleXfermodesBlur.cpp
@@ -25,8 +25,8 @@
 #include "src/utils/SkUTF.h"
 
 #include "include/core/SkColorPriv.h"
+#include "include/core/SkMaskFilter.h"
 #include "include/core/SkStream.h"
-#include "include/effects/SkBlurMaskFilter.h"
 
 static void setNamedTypeface(SkFont* font, const char name[]) {
     font->setTypeface(SkTypeface::MakeFromName(name, SkFontStyle()));
@@ -73,9 +73,9 @@
     }
 
 protected:
-    virtual SkString name() { return SkString("XfermodesBlur"); }
+    SkString name() override { return SkString("XfermodesBlur"); }
 
-    virtual void onDrawContent(SkCanvas* canvas) {
+    void onDrawContent(SkCanvas* canvas) override {
         canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
 
         const SkBlendMode gModes[] = {
@@ -98,13 +98,13 @@
         const SkScalar h = SkIntToScalar(H);
         SkMatrix m;
         m.setScale(SkIntToScalar(6), SkIntToScalar(6));
-        auto s = fBG.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &m);
+        auto s = fBG.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, SkSamplingOptions(), m);
 
         SkFont font;
         font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
         setNamedTypeface(&font, "Menlo Regular");
 
-        const int W = 5;
+        const int kWrap = 5;
 
         SkScalar x0 = 0;
         for (int twice = 0; twice < 2; twice++) {
@@ -131,7 +131,7 @@
                 SkTextUtils::DrawString(canvas, label, x + w/2, y - font.getSize()/2, font, SkPaint(),
                                         SkTextUtils::kCenter_Align);
                 x += w + SkIntToScalar(10);
-                if ((i % W) == W - 1) {
+                if ((i % kWrap) == kWrap - 1) {
                     x = x0;
                     y += h + SkIntToScalar(30);
                 }
@@ -141,7 +141,7 @@
     }
 
 private:
-    typedef Sample INHERITED;
+    using INHERITED = Sample;
 };
 
 //////////////////////////////////////////////////////////////////////////////
