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
