Move Views into Sample and Viewer.

What is left of the SkView system is used only by samples or viewer.
As a result, move it out of the Skia source tree and re-organize so it
is a bit easier to understand and use more shared code.

Move samplecode/ClockFaceView.cpp to samplecode/SampleTextEffects.cpp,
sice that's what's actually in it.

Move SkAnimTimer.h to tools/timer, since it's actually shared between gm
and samples.

Change-Id: I55dafd94c64e4f930ddbd19168e0f812af86c455
Reviewed-on: https://skia-review.googlesource.com/146161
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/samplecode/PerlinPatch.cpp b/samplecode/PerlinPatch.cpp
index 9faf5ca..c962e19 100644
--- a/samplecode/PerlinPatch.cpp
+++ b/samplecode/PerlinPatch.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
@@ -59,7 +59,7 @@
 const SkScalar TexWidth = 100.0f;
 const SkScalar TexHeight = 100.0f;
 
-class PerlinPatchView : public SampleView {
+class PerlinPatchView : public Sample {
     sk_sp<SkShader> fShader0;
     sk_sp<SkShader> fShader1;
     sk_sp<SkShader> fShaderCompose;
@@ -110,14 +110,13 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt)  override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "PerlinPatch");
+    bool onQuery(Sample::Event* evt)  override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "PerlinPatch");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case 'g': fShowGrid = !fShowGrid; return true;
                 default: break;
@@ -167,14 +166,14 @@
     class PtClick : public Click {
     public:
         int fIndex;
-        PtClick(SkView* view, int index) : Click(view), fIndex(index) {}
+        PtClick(Sample* view, int index) : Click(view), fIndex(index) {}
     };
 
     static bool hittest(const SkPoint& pt, SkScalar x, SkScalar y) {
         return SkPoint::Length(pt.fX - x, pt.fY - y) < SkIntToScalar(5);
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
         // holding down shift
         if (1 == modi) {
             return new PtClick(this, -1);
@@ -211,7 +210,7 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 DEF_SAMPLE( return new PerlinPatchView(); )
diff --git a/samplecode/Sample.cpp b/samplecode/Sample.cpp
new file mode 100644
index 0000000..895cd83
--- /dev/null
+++ b/samplecode/Sample.cpp
@@ -0,0 +1,222 @@
+/*
+ * 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 "Sample.h"
+#include "SkCanvas.h"
+#include "SkString.h"
+
+#if SK_SUPPORT_GPU
+#   include "GrContext.h"
+#else
+class GrContext;
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+
+Sample::Event::Event() : Event("") {}
+
+Sample::Event::Event(const Event& that) {
+    *this = that;
+}
+
+Sample::Event::Event(const char type[]) : fType(type), f32(0) {
+    SkASSERT(type);
+}
+
+Sample::Event::~Event() {}
+
+bool Sample::Event::isType(const char type[]) const {
+    return fType.equals(type);
+}
+
+const char* Sample::kCharEvtName = "SampleCode_Char_Event";
+const char* Sample::kTitleEvtName = "SampleCode_Title_Event";
+
+bool Sample::CharQ(const Event& evt, SkUnichar* outUni) {
+    if (evt.isType(kCharEvtName)) {
+        if (outUni) {
+            *outUni = evt.getFast32();
+        }
+        return true;
+    }
+    return false;
+}
+
+bool Sample::TitleQ(const Event& evt) {
+    return evt.isType(kTitleEvtName);
+}
+
+void Sample::TitleR(Event* evt, const char title[]) {
+    SkASSERT(evt && TitleQ(*evt));
+    evt->setString(kTitleEvtName, title);
+}
+
+bool Sample::RequestTitle(Sample* view, SkString* title) {
+    Event evt(kTitleEvtName);
+    if (view->doQuery(&evt)) {
+        title->set(evt.findString(kTitleEvtName));
+        return true;
+    }
+    return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool Sample::doEvent(const Event& evt) {
+    return this->onEvent(evt);
+}
+
+bool Sample::onEvent(const Event&) {
+    return false;
+}
+
+bool Sample::doQuery(Event* evt) {
+    SkASSERT(evt);
+    return this->onQuery(evt);
+}
+
+bool Sample::onQuery(Sample::Event* evt) {
+    return false;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+
+void Sample::setSize(SkScalar width, SkScalar height) {
+    width = SkMaxScalar(0, width);
+    height = SkMaxScalar(0, height);
+
+    if (fWidth != width || fHeight != height)
+    {
+        fWidth = width;
+        fHeight = height;
+        this->onSizeChange();
+    }
+}
+
+void Sample::draw(SkCanvas* canvas) {
+    if (fWidth && fHeight) {
+        SkRect    r;
+        r.set(0, 0, fWidth, fHeight);
+        if (canvas->quickReject(r)) {
+            return;
+        }
+
+        SkAutoCanvasRestore    as(canvas, true);
+        int sc = canvas->save();
+
+        if (!fHaveCalledOnceBeforeDraw) {
+            fHaveCalledOnceBeforeDraw = true;
+            this->onOnceBeforeDraw();
+        }
+        this->onDrawBackground(canvas);
+
+        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();
+        }
+#endif
+
+        canvas->restoreToCount(sc);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+Sample::Click::Click(Sample* target) {
+    SkASSERT(target);
+    fTarget = sk_ref_sp(target);
+}
+
+Sample::Click::~Click() {}
+
+Sample::Click* Sample::findClickHandler(SkScalar x, SkScalar y, unsigned modi) {
+    if (x < 0 || y < 0 || x >= fWidth || y >= fHeight) {
+        return nullptr;
+    }
+
+    return this->onFindClickHandler(x, y, modi);
+}
+
+void Sample::DoClickDown(Click* click, int x, int y, unsigned modi) {
+    SkASSERT(click);
+
+    Sample* target = click->fTarget.get();
+    if (nullptr == target) {
+        return;
+    }
+
+    click->fIOrig.set(x, y);
+    click->fICurr = click->fIPrev = click->fIOrig;
+
+    click->fOrig.iset(x, y);
+    click->fPrev = click->fCurr = click->fOrig;
+
+    click->fState = Click::kDown_State;
+    click->fModifierKeys = modi;
+    target->onClick(click);
+}
+
+void Sample::DoClickMoved(Click* click, int x, int y, unsigned modi) {
+    SkASSERT(click);
+
+    Sample* target = click->fTarget.get();
+    if (nullptr == target) {
+        return;
+    }
+
+    click->fIPrev = click->fICurr;
+    click->fICurr.set(x, y);
+
+    click->fPrev = click->fCurr;
+    click->fCurr.iset(x, y);
+
+    click->fState = Click::kMoved_State;
+    click->fModifierKeys = modi;
+    target->onClick(click);
+}
+
+void Sample::DoClickUp(Click* click, int x, int y, unsigned modi) {
+    SkASSERT(click);
+
+    Sample* target = click->fTarget.get();
+    if (nullptr == target) {
+        return;
+    }
+
+    click->fIPrev = click->fICurr;
+    click->fICurr.set(x, y);
+
+    click->fPrev = click->fCurr;
+    click->fCurr.iset(x, y);
+
+    click->fState = Click::kUp_State;
+    click->fModifierKeys = modi;
+    target->onClick(click);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+void Sample::onSizeChange() {}
+
+Sample::Click* Sample::onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
+    return nullptr;
+}
+
+bool Sample::onClick(Click*) {
+    return false;
+}
+
+void Sample::onDrawBackground(SkCanvas* canvas) {
+    canvas->drawColor(fBGColor);
+}
+
+// need to explicitly declare this, or we get some weird infinite loop llist
+template SampleRegistry* SampleRegistry::gHead;
diff --git a/samplecode/Sample.h b/samplecode/Sample.h
new file mode 100644
index 0000000..e906e31
--- /dev/null
+++ b/samplecode/Sample.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SampleCode_DEFINED
+#define SampleCode_DEFINED
+
+#include "Registry.h"
+#include "SkColor.h"
+#include "SkMacros.h"
+#include "SkMetaData.h"
+#include "SkPoint.h"
+#include "SkRefCnt.h"
+#include "SkString.h"
+
+class SkAnimTimer;
+class SkCanvas;
+class Sample;
+
+using SampleFactory = Sample* (*)();
+using SampleRegistry = sk_tools::Registry<SampleFactory>;
+
+#define DEF_SAMPLE(code) \
+    static Sample*          SK_MACRO_APPEND_LINE(F_)() { code } \
+    static SampleRegistry   SK_MACRO_APPEND_LINE(R_)(SK_MACRO_APPEND_LINE(F_));
+
+///////////////////////////////////////////////////////////////////////////////
+
+class Sample : public SkRefCnt {
+public:
+    Sample()
+        : fBGColor(SK_ColorWHITE)
+        , fWidth(0), fHeight(0)
+        , fHaveCalledOnceBeforeDraw(false)
+    {}
+
+    SkScalar    width() const { return fWidth; }
+    SkScalar    height() const { return fHeight; }
+    void        setSize(SkScalar width, SkScalar height);
+    void        setSize(const SkPoint& size) { this->setSize(size.fX, size.fY); }
+    void        setWidth(SkScalar width) { this->setSize(width, fHeight); }
+    void        setHeight(SkScalar height) { this->setSize(fWidth, height); }
+
+    /** Call this to have the view draw into the specified canvas. */
+    virtual void draw(SkCanvas* canvas);
+
+    //  Click handling
+    class Click {
+    public:
+        Click(Sample* target);
+        virtual ~Click();
+
+        enum State {
+            kDown_State,
+            kMoved_State,
+            kUp_State
+        };
+        enum ModifierKeys {
+            kShift_ModifierKey    = 1 << 0,
+            kControl_ModifierKey  = 1 << 1,
+            kOption_ModifierKey   = 1 << 2,   // same as ALT
+            kCommand_ModifierKey  = 1 << 3,
+        };
+        SkPoint     fOrig, fPrev, fCurr;
+        SkIPoint    fIOrig, fIPrev, fICurr;
+        State       fState;
+        unsigned    fModifierKeys;
+
+        SkMetaData  fMeta;
+    private:
+        sk_sp<Sample> fTarget;
+
+        friend class Sample;
+    };
+    Click* findClickHandler(SkScalar x, SkScalar y, unsigned modifierKeys);
+    static void DoClickDown(Click*, int x, int y, unsigned modi);
+    static void DoClickMoved(Click*, int x, int y, unsigned modi);
+    static void DoClickUp(Click*, int x, int y, unsigned modi);
+
+    void setBGColor(SkColor color) { fBGColor = color; }
+    bool animate(const SkAnimTimer& timer) { return this->onAnimate(timer); }
+
+    class Event {
+    public:
+        Event();
+        explicit Event(const char type[]);
+        Event(const Event& src);
+        ~Event();
+
+        /** Returns true if the event's type matches exactly the specified type (case sensitive) */
+        bool isType(const char type[]) const;
+
+        /** Return the event's unnamed 32bit field. Default value is 0 */
+        uint32_t getFast32() const { return f32; }
+
+        /** Set the event's unnamed 32bit field. */
+        void setFast32(uint32_t x) { f32 = x; }
+
+        /** Return true if the event contains the named 32bit field, and return the field
+            in value (if value is non-null). If there is no matching named field, return false
+            and ignore the value parameter.
+        */
+        bool findS32(const char name[], int32_t* value = nullptr) const {
+            return fMeta.findS32(name, value);
+        }
+        /** Return true if the event contains the named SkScalar field, and return the field
+            in value (if value is non-null). If there is no matching named field, return false
+            and ignore the value parameter.
+        */
+        bool findScalar(const char name[], SkScalar* value = nullptr) const {
+            return fMeta.findScalar(name, value);
+        }
+        /** Return true if the event contains the named SkScalar field, and return the fields
+            in value[] (if value is non-null), and return the number of SkScalars in count
+            (if count is non-null). If there is no matching named field, return false
+            and ignore the value and count parameters.
+        */
+        const SkScalar* findScalars(const char name[], int* count, SkScalar values[]=nullptr) const{
+            return fMeta.findScalars(name, count, values);
+        }
+        /** Return the value of the named string field, or nullptr. */
+        const char* findString(const char name[]) const { return fMeta.findString(name); }
+        /** Return true if the event contains the named pointer field, and return the field
+            in value (if value is non-null). If there is no matching named field, return false
+            and ignore the value parameter.
+        */
+        bool findPtr(const char name[], void** value) const { return fMeta.findPtr(name, value); }
+        bool findBool(const char name[], bool* value) const { return fMeta.findBool(name, value); }
+        const void* findData(const char name[], size_t* byteCount = nullptr) const {
+            return fMeta.findData(name, byteCount);
+        }
+
+        /** Returns true if ethe event contains the named 32bit field, and if it equals the specified value */
+        bool hasS32(const char name[], int32_t value) const { return fMeta.hasS32(name, value); }
+        /** Returns true if ethe event contains the named SkScalar field, and if it equals the specified value */
+        bool hasScalar(const char name[], SkScalar value) const { return fMeta.hasScalar(name, value); }
+        /** Returns true if ethe event contains the named string field, and if it equals (using strcmp) the specified value */
+        bool hasString(const char name[], const char value[]) const { return fMeta.hasString(name, value); }
+        /** Returns true if ethe event contains the named pointer field, and if it equals the specified value */
+        bool hasPtr(const char name[], void* value) const { return fMeta.hasPtr(name, value); }
+        bool hasBool(const char name[], bool value) const { return fMeta.hasBool(name, value); }
+        bool hasData(const char name[], const void* data, size_t byteCount) const {
+            return fMeta.hasData(name, data, byteCount);
+        }
+
+        /** Add/replace the named 32bit field to the event. */
+        void setS32(const char name[], int32_t value) { fMeta.setS32(name, value); }
+        /** Add/replace the named SkScalar field to the event. */
+        void setScalar(const char name[], SkScalar value) { fMeta.setScalar(name, value); }
+        /** Add/replace the named SkScalar[] field to the event. */
+        SkScalar* setScalars(const char name[], int count, const SkScalar values[] = nullptr) {
+            return fMeta.setScalars(name, count, values);
+        }
+        /** Add/replace the named string field to the event. */
+        void setString(const char name[], const char value[]) { fMeta.setString(name, value); }
+        /** Add/replace the named pointer field to the event. */
+        void setPtr(const char name[], void* value) { fMeta.setPtr(name, value); }
+        void setBool(const char name[], bool value) { fMeta.setBool(name, value); }
+        void setData(const char name[], const void* data, size_t byteCount) {
+            fMeta.setData(name, data, byteCount);
+        }
+
+        /** Return the underlying metadata object */
+        SkMetaData& getMetaData() { return fMeta; }
+        /** Return the underlying metadata object */
+        const SkMetaData& getMetaData() const { return fMeta; }
+
+        ///////////////////////////////////////////////////////////////////////////
+
+    private:
+        SkMetaData      fMeta;
+        SkString        fType;
+        uint32_t        f32;
+    };
+
+    /** Pass an event to this object for processing. Returns true if the event was handled. */
+    bool doEvent(const Event&);
+
+    /** Returns true if the sink (or one of its subclasses) understands the event as a query.
+        If so, the sink may modify the event to communicate its "answer".
+    */
+    bool doQuery(Event* query);
+
+    static const char* kCharEvtName;
+    static const char* kTitleEvtName;
+    static bool CharQ(const Event&, SkUnichar* outUni);
+    static bool TitleQ(const Event&);
+    static void TitleR(Event*, const char title[]);
+    static bool RequestTitle(Sample* view, SkString* title);
+
+protected:
+    /** Override to handle events in your subclass.
+     *  Overriders must call the super class for unhandled events.
+     */
+    virtual bool onEvent(const Event&);
+    virtual bool onQuery(Event*);
+
+    /** Override to be notified of size changes. Overriders must call the super class. */
+    virtual void onSizeChange();
+
+    /** Override this if you might handle the click */
+    virtual Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi);
+
+    /** Override to track clicks. Return true as long as you want to track the pen/mouse. */
+    virtual bool onClick(Click*);
+
+    virtual void onDrawBackground(SkCanvas*);
+    virtual void onDrawContent(SkCanvas*) = 0;
+    virtual bool onAnimate(const SkAnimTimer&) { return false; }
+    virtual void onOnceBeforeDraw() {}
+
+private:
+    SkColor fBGColor;
+    SkScalar fWidth, fHeight;
+    bool fHaveCalledOnceBeforeDraw;
+};
+
+#endif
diff --git a/samplecode/Sample2PtRadial.cpp b/samplecode/Sample2PtRadial.cpp
index db3b24f..8d1fcc4 100644
--- a/samplecode/Sample2PtRadial.cpp
+++ b/samplecode/Sample2PtRadial.cpp
@@ -4,21 +4,19 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 
 
-class TwoPtConicalView : public SampleView {
+class TwoPtConicalView : public Sample {
 public:
     TwoPtConicalView() {}
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "2PtConical");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "2PtConical");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -40,10 +38,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new TwoPtConicalView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new TwoPtConicalView(); )
diff --git a/samplecode/SampleAAClip.cpp b/samplecode/SampleAAClip.cpp
index 4c79560..0003c6a 100644
--- a/samplecode/SampleAAClip.cpp
+++ b/samplecode/SampleAAClip.cpp
@@ -5,11 +5,10 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAAClip.h"
 #include "SkCanvas.h"
 #include "SkPath.h"
-#include "SkView.h"
 
 static void testop(const SkIRect& r0, const SkIRect& r1, SkRegion::Op op,
                    const SkIRect& expectedR) {
@@ -55,17 +54,16 @@
                        &paint);
 }
 
-class AAClipView : public SampleView {
+class AAClipView : public Sample {
 public:
     AAClipView() {
         testop();
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "AAClip");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "AAClip");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -116,10 +114,9 @@
     }
 
 private:
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new AAClipView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new AAClipView(); )
diff --git a/samplecode/SampleAAGeometry.cpp b/samplecode/SampleAAGeometry.cpp
index c431033..5746e2d 100644
--- a/samplecode/SampleAAGeometry.cpp
+++ b/samplecode/SampleAAGeometry.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkGeometry.h"
@@ -16,7 +16,6 @@
 // #include "SkPathStroker.h"
 #include "SkPointPriv.h"
 #include "SkString.h"
-#include "SkView.h"
 
 #if 0
 void SkStrokeSegment::dump() const {
@@ -645,7 +644,7 @@
 };
 
 
-class MyClick : public SampleView::Click {
+class MyClick : public Sample::Click {
 public:
     enum ClickType {
         kInvalidType = -1,
@@ -684,7 +683,7 @@
     SkPath::Verb fVerb;
     SkScalar fWeight;
 
-    MyClick(SkView* target, ClickType type, ControlType control)
+    MyClick(Sample* target, ClickType type, ControlType control)
         : Click(target)
         , fType(type)
         , fControl(control)
@@ -692,7 +691,7 @@
         , fWeight(1) {
     }
 
-    MyClick(SkView* target, ClickType type, int index)
+    MyClick(Sample* target, ClickType type, int index)
         : Click(target)
         , fType(type)
         , fControl((ControlType) index)
@@ -700,7 +699,7 @@
         , fWeight(1) {
     }
 
-    MyClick(SkView* target, ClickType type, int index, SkPath::Verb verb, SkScalar weight)
+    MyClick(Sample* target, ClickType type, int index, SkPath::Verb verb, SkScalar weight)
         : Click(target)
         , fType(type)
         , fControl((ControlType) index)
@@ -783,7 +782,7 @@
     PathUndo* fNext;
 };
 
-class AAGeometryView : public SampleView {
+class AAGeometryView : public Sample {
     SkPaint fActivePaint;
     SkPaint fComplexPaint;
     SkPaint fCoveragePaint;
@@ -971,8 +970,7 @@
 
     #undef SET_BUTTON
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override;
+    bool onQuery(Sample::Event* evt) override;
 
     void onSizeChange() override {
         setControlButtonsPos();
@@ -1611,7 +1609,7 @@
         return -1;
     }
 
-    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
         SkPoint pt = {x, y};
         int ptHit = hittest_pt(pt);
         if (ptHit >= 0) {
@@ -1787,7 +1785,7 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 static struct KeyCommand {
@@ -1822,17 +1820,16 @@
     }
 }
 
-// overrides from SkEventSink
-bool AAGeometryView::onQuery(SkEvent* evt) {
-    if (SampleCode::TitleQ(*evt)) {
-        SampleCode::TitleR(evt, "AAGeometry");
+bool AAGeometryView::onQuery(Sample::Event* evt) {
+    if (Sample::TitleQ(*evt)) {
+        Sample::TitleR(evt, "AAGeometry");
         return true;
     }
     SkUnichar uni;
     if (false) {
         return this->INHERITED::onQuery(evt);
     }
-    if (SampleCode::CharQ(*evt, &uni)) {
+    if (Sample::CharQ(*evt, &uni)) {
         for (int index = 0; index < kButtonCount; ++index) {
             Button* button = kButtonList[index].fButton;
             if (button->fVisible && uni == button->fLabel) {
diff --git a/samplecode/SampleAARectModes.cpp b/samplecode/SampleAARectModes.cpp
index 2e790e2..b10a9ef 100644
--- a/samplecode/SampleAARectModes.cpp
+++ b/samplecode/SampleAARectModes.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkColorPriv.h"
@@ -72,7 +71,7 @@
                                       &m);
 }
 
-class AARectsModesView : public SampleView {
+class AARectsModesView : public Sample {
     SkPaint fBGPaint;
 public:
     AARectsModesView () {
@@ -80,10 +79,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "AARectsModes");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "AARectsModes");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -120,10 +118,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new AARectsModesView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new AARectsModesView(); )
diff --git a/samplecode/SampleAARects.cpp b/samplecode/SampleAARects.cpp
index f83ab31..211b411 100644
--- a/samplecode/SampleAARects.cpp
+++ b/samplecode/SampleAARects.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
@@ -33,7 +32,7 @@
     return bitmap;
 }
 
-class AARectView : public SampleView {
+class AARectView : public Sample {
     SkBitmap fBitmap;
     enum {
         N = 64
@@ -46,10 +45,9 @@
         fWidth = N;
     }
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "AA Rects");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "AA Rects");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -184,10 +182,9 @@
 private:
     int fWidth;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new AARectView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new AARectView(); )
diff --git a/samplecode/SampleAll.cpp b/samplecode/SampleAll.cpp
index de9038b..6b94395 100644
--- a/samplecode/SampleAll.cpp
+++ b/samplecode/SampleAll.cpp
@@ -4,10 +4,9 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMask.h"
 #include "SkCanvas.h"
-#include "SkView.h"
 #include "Sk1DPathEffect.h"
 #include "Sk2DPathEffect.h"
 #include "SkBlurMaskFilter.h"
@@ -58,15 +57,14 @@
     typedef Sk2DPathEffect INHERITED;
 };
 
-class DemoView : public SampleView {
+class DemoView : public Sample {
 public:
     DemoView() {}
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Demo");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Demo");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -273,7 +271,7 @@
         canvas->restore();
     }
 
-    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
+    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
         fClickPt.set(x, y);
         return this->INHERITED::onFindClickHandler(x, y, modi);
     }
@@ -316,10 +314,9 @@
 private:
     SkPoint fClickPt;
     SkBitmap fBug, fTb, fTx;
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new DemoView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new DemoView(); )
diff --git a/samplecode/SampleAndroidShadows.cpp b/samplecode/SampleAndroidShadows.cpp
index cdc9e75..d4603a1 100644
--- a/samplecode/SampleAndroidShadows.cpp
+++ b/samplecode/SampleAndroidShadows.cpp
@@ -5,7 +5,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
 #include "SkBlurMask.h"
 #include "SkBlurMaskFilter.h"
@@ -17,12 +17,11 @@
 #include "SkPoint3.h"
 #include "SkShadowUtils.h"
 #include "SkUtils.h"
-#include "SkView.h"
 #include "sk_tool_utils.h"
 
 ////////////////////////////////////////////////////////////////////////////
 
-class ShadowsView : public SampleView {
+class ShadowsView : public Sample {
     SkPath    fRectPath;
     SkPath    fRRPath;
     SkPath    fCirclePath;
@@ -107,15 +106,14 @@
         fLightPos = SkPoint3::Make(350, 0, 600);
     }
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "AndroidShadows");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "AndroidShadows");
             return true;
         }
 
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             bool handled = false;
             switch (uni) {
                 case 'W':
@@ -353,10 +351,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ShadowsView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ShadowsView(); )
diff --git a/samplecode/SampleAnimBlur.cpp b/samplecode/SampleAnimBlur.cpp
index bf5005d..2d433ee 100644
--- a/samplecode/SampleAnimBlur.cpp
+++ b/samplecode/SampleAnimBlur.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
 #include "SkColorPriv.h"
 #include "SkCanvas.h"
@@ -22,15 +22,14 @@
     return amplitude * SkDoubleToScalar(sin(t)) + amplitude;
 }
 
-class AnimBlurView : public SampleView {
+class AnimBlurView : public Sample {
 public:
     AnimBlurView() : fBlurSigma(0), fCircleRadius(100) {}
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "AnimBlur");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "AnimBlur");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -65,10 +64,9 @@
 private:
     SkScalar fBlurSigma, fCircleRadius;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new AnimBlurView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new AnimBlurView(); )
diff --git a/samplecode/SampleAnimatedImage.cpp b/samplecode/SampleAnimatedImage.cpp
index bea6018..0d9adad 100644
--- a/samplecode/SampleAnimatedImage.cpp
+++ b/samplecode/SampleAnimatedImage.cpp
@@ -15,13 +15,13 @@
 #include "SkScalar.h"
 #include "SkString.h"
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "Resources.h"
 
 static constexpr char kPauseKey = 'p';
 static constexpr char kResetKey = 'r';
 
-class SampleAnimatedImage : public SampleView {
+class SampleAnimatedImage : public Sample {
 public:
     SampleAnimatedImage()
         : INHERITED()
@@ -97,14 +97,14 @@
         fDrawable = recorder.finishRecordingAsDrawable();
     }
 
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "AnimatedImage");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "AnimatedImage");
             return true;
         }
 
         SkUnichar uni;
-        if (fImage && SampleCode::CharQ(*evt, &uni)) {
+        if (fImage && Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case kPauseKey:
                     fRunning = !fRunning;
@@ -133,13 +133,9 @@
     double                  fCurrentTime = 0.0;
     double                  fLastWallTime = 0.0;
     double                  fTimeToShowNextFrame = 0.0;
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() {
-    return new SampleAnimatedImage;
-}
-
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new SampleAnimatedImage(); )
diff --git a/samplecode/SampleAnimatedText.cpp b/samplecode/SampleAnimatedText.cpp
index 71f3b87..71f1a95 100644
--- a/samplecode/SampleAnimatedText.cpp
+++ b/samplecode/SampleAnimatedText.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkUtils.h"
 #include "SkColorPriv.h"
@@ -40,7 +39,7 @@
 //            -- this feature boosts the rendering out of the small point-size
 //               SDF-text special case (which falls back to bitmap fonts for small points)
 
-class AnimatedTextView : public SampleView {
+class AnimatedTextView : public Sample {
 public:
     AnimatedTextView() : fScale(1.0f), fScaleInc(0.1f), fRotation(0.0f), fSizeScale(1) {
         fCurrentTime = 0;
@@ -49,15 +48,14 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "AnimatedText");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "AnimatedText");
             return true;
         }
 
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             if ('2' == uni) {
                 if (fSizeScale == 2) {
                     fSizeScale = 1;
@@ -155,10 +153,9 @@
     int         fCurrentTime;
 
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new AnimatedTextView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new AnimatedTextView(); )
diff --git a/samplecode/SampleAnimator.cpp b/samplecode/SampleAnimator.cpp
deleted file mode 100644
index a3ec83a..0000000
--- a/samplecode/SampleAnimator.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 "SampleCode.h"
-#include "SkView.h"
-#include "SkCanvas.h"
-
-#include "SkAnimator.h"
-#include "SkStream.h"
-#include "SkDOM.h"
-
-#include <memory>
-
-///////////////////////////////////////////////////////////////////////////////
-
-class SkAnimatorView : public SkView {
-public:
-    SkAnimatorView();
-    virtual ~SkAnimatorView();
-
-    void setURIBase(const char dir[]);
-
-    SkAnimator* getAnimator() const { return fAnimator; }
-
-    bool    decodeFile(const char path[]);
-    bool    decodeMemory(const void* buffer, size_t size);
-    bool    decodeStream(SkStream* stream);
-
-protected:
-    // overrides
-    virtual void onDraw(SkCanvas*);
-    virtual bool onQuery(SkEvent* evt);
-
-private:
-    SkString fBaseURI;
-    SkAnimator* fAnimator;
-
-    typedef SkView INHERITED;
-};
-
-SkAnimatorView::SkAnimatorView() : fAnimator(nullptr) {}
-
-SkAnimatorView::~SkAnimatorView() {
-    delete fAnimator;
-}
-
-void SkAnimatorView::setURIBase(const char dir[]) {
-    fBaseURI.set(dir);
-}
-
-bool SkAnimatorView::decodeFile(const char path[]) {
-    std::unique_ptr<SkStream> is = SkStream::MakeFromFile(path);
-    return is && this->decodeStream(is.get());
-}
-
-bool SkAnimatorView::decodeMemory(const void* buffer, size_t size) {
-    SkMemoryStream is(buffer, size);
-    return this->decodeStream(&is);
-}
-
-static const SkDOMNode* find_nodeID(const SkDOM& dom,
-                        const SkDOMNode* node, const char name[]) {
-    if (nullptr == node) {
-        node = dom.getRootNode();
-    }
-    do {
-        const char* idval = dom.findAttr(node, "id");
-        if (idval && !strcmp(idval, name)) {
-            return node;
-        }
-        const SkDOMNode* child = dom.getFirstChild(node);
-        if (child) {
-            const SkDOMNode* found = find_nodeID(dom, child, name);
-            if (found) {
-                return found;
-            }
-        }
-    } while ((node = dom.getNextSibling(node)) != nullptr);
-    return nullptr;
-}
-
-bool SkAnimatorView::decodeStream(SkStream* stream) {
-    delete fAnimator;
-    fAnimator = new SkAnimator;
-    fAnimator->setURIBase(fBaseURI.c_str());
-#if 0
-    if (!fAnimator->decodeStream(stream)) {
-        delete fAnimator;
-        fAnimator = nullptr;
-        return false;
-    }
-#else
-    size_t len = stream->getLength();
-    char* text = (char*)sk_malloc_throw(len);
-    stream->read(text, len);
-    SkDOM dom;
-    const SkDOM::Node* root = dom.build(text, len);
-    if (nullptr == root) {
-        return false;
-    }
-    if (!fAnimator->decodeDOM(dom, root)) {
-        delete fAnimator;
-        fAnimator = nullptr;
-        return false;
-    }
-    for (int i = 0; i <= 10; i++) {
-        SkString name("glyph");
-        name.appendS32(i);
-        const SkDOM::Node* node = find_nodeID(dom, nullptr, name.c_str());
-        SkASSERT(node);
-        SkRect r;
-        dom.findScalar(node, "left", &r.fLeft);
-        dom.findScalar(node, "top", &r.fTop);
-        dom.findScalar(node, "width", &r.fRight); r.fRight += r.fLeft;
-        dom.findScalar(node, "height", &r.fBottom); r.fBottom += r.fTop;
-        SkDebugf("--- %s [%g %g %g %g]\n", name.c_str(),
-                 r.fLeft, r.fTop, r.fRight, r.fBottom);
-    }
-#endif
-    return true;
-}
-
-#include "SkTime.h"
-
-void SkAnimatorView::onDraw(SkCanvas* canvas) {
-    canvas->drawColor(SK_ColorWHITE);
-    if (fAnimator) {
-        fAnimator->draw(canvas, 0);
-#if 0
-        canvas->save();
-        canvas->translate(120, 30);
-        canvas->scale(0.5, 0.5);
-        fAnimator->draw(canvas, 0);
-        canvas->restore();
-
-        canvas->save();
-        canvas->translate(190, 40);
-        canvas->scale(0.25, 0.25);
-        fAnimator->draw(canvas, 0);
-        canvas->restore();
-
-        this->inval(nullptr);
-#endif
-    }
-}
-
-bool SkAnimatorView::onQuery(SkEvent* evt) {
-    if (SampleCode::TitleQ(*evt)) {
-        SampleCode::TitleR(evt, "Animator");
-        return true;
-    }
-    return this->INHERITED::onQuery(evt);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-static SkView* MyFactory() {
-    SkAnimatorView* av = new SkAnimatorView;
-//    av->decodeFile("/skimages/test.xml");
-#if 0
-    av->setURIBase("/skia/trunk/animations/");
-    av->decodeFile("/skia/trunk/animations/checkbox.xml");
-#else
-    av->setURIBase("/");
-    av->decodeFile("/testanim.txt");
-#endif
-    return av;
-}
-
-static SkViewRegister reg(MyFactory);
diff --git a/samplecode/SampleArc.cpp b/samplecode/SampleArc.cpp
index a461a22..1222cf2 100644
--- a/samplecode/SampleArc.cpp
+++ b/samplecode/SampleArc.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
 #include "SkCanvas.h"
 #include "SkColorFilter.h"
@@ -21,7 +21,6 @@
 #include "SkShader.h"
 #include "SkString.h"
 #include "SkUtils.h"
-#include "SkView.h"
 #include "Sk1DPathEffect.h"
 
 #include "SkParsePath.h"
@@ -37,7 +36,7 @@
     SkParsePath::ToSVGString(p2, &str2);
 }
 
-class ArcsView : public SampleView {
+class ArcsView : public Sample {
     class MyDrawable : public SkDrawable {
         SkRect   fR;
         SkScalar fSweep;
@@ -99,10 +98,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Arcs");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Arcs");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -199,10 +197,9 @@
 private:
     SkScalar fSweep;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ArcsView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ArcsView(); )
diff --git a/samplecode/SampleAtlas.cpp b/samplecode/SampleAtlas.cpp
index fac8327..a6ab820 100644
--- a/samplecode/SampleAtlas.cpp
+++ b/samplecode/SampleAtlas.cpp
@@ -5,9 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
-#include "SkView.h"
 #include "SkCanvas.h"
 #include "SkDrawable.h"
 #include "SkPath.h"
@@ -201,7 +200,7 @@
     typedef SkDrawable INHERITED;
 };
 
-class DrawAtlasView : public SampleView {
+class DrawAtlasView : public Sample {
     const char* fName;
     DrawAtlasProc fProc;
     sk_sp<DrawAtlasDrawable> fDrawable;
@@ -210,13 +209,13 @@
     DrawAtlasView(const char name[], DrawAtlasProc proc) : fName(name), fProc(proc) { }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, fName);
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, fName);
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case 'C': fDrawable->toggleUseColors(); return true;
                 default: break;
@@ -246,7 +245,7 @@
 #endif
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/samplecode/SampleBigBlur.cpp b/samplecode/SampleBigBlur.cpp
index 0334983..d7bc5f0 100644
--- a/samplecode/SampleBigBlur.cpp
+++ b/samplecode/SampleBigBlur.cpp
@@ -4,22 +4,20 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMask.h"
 #include "SkCanvas.h"
 #include "SkMaskFilter.h"
-#include "SkView.h"
 
-class BigBlurView : public SampleView {
+class BigBlurView : public Sample {
 public:
     BigBlurView() {
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "BigBlur");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "BigBlur");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -38,10 +36,9 @@
     }
 
 private:
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new BigBlurView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new BigBlurView(); )
diff --git a/samplecode/SampleBigGradient.cpp b/samplecode/SampleBigGradient.cpp
index c174f6e..c921c37 100644
--- a/samplecode/SampleBigGradient.cpp
+++ b/samplecode/SampleBigGradient.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkMakeUnique.h"
@@ -17,14 +16,14 @@
     return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode);
 }
 
-class BigGradientView : public SampleView {
+class BigGradientView : public Sample {
 public:
     BigGradientView() {}
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "BigGradient");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "BigGradient");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -39,13 +38,12 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new BigGradientView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new BigGradientView(); )
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -261,14 +259,14 @@
 #endif
 
 #ifdef MyAllocator
-class RasterAllocatorSample : public SampleView {
+class RasterAllocatorSample : public Sample {
 public:
     RasterAllocatorSample() {}
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "raster-allocator");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "raster-allocator");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -310,7 +308,7 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 DEF_SAMPLE( return new RasterAllocatorSample; )
 #endif
diff --git a/samplecode/SampleBitmapRect.cpp b/samplecode/SampleBitmapRect.cpp
index 0e3ae5b..d8a6815 100644
--- a/samplecode/SampleBitmapRect.cpp
+++ b/samplecode/SampleBitmapRect.cpp
@@ -5,9 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
-#include "SkView.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
@@ -64,7 +63,7 @@
     bounce(&pt->fY, &vec->fY, limit.fTop, limit.fBottom);
 }
 
-class BitmapRectView : public SampleView {
+class BitmapRectView : public Sample {
     SkPoint fSrcPts[2];
     SkPoint fSrcVec[2];
     SkRect  fSrcLimit;
@@ -102,9 +101,9 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "BitmapRect");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "BitmapRect");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -146,7 +145,7 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
@@ -175,7 +174,7 @@
     canvas.drawString(gText, 0, paint.getTextSize()*4/5, paint);
 }
 
-class BitmapRectView2 : public SampleView {
+class BitmapRectView2 : public Sample {
     SkBitmap fBitmap;
 
     SkRect  fSrcR;
@@ -198,9 +197,9 @@
     BitmapRectView2() { }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "BigBitmapRect");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "BigBitmapRect");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -243,12 +242,10 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* F0() { return new BitmapRectView; }
-static SkView* F1() { return new BitmapRectView2; }
-static SkViewRegister gR0(F0);
-static SkViewRegister gR1(F1);
+DEF_SAMPLE( return new BitmapRectView(); )
+DEF_SAMPLE( return new BitmapRectView2(); )
diff --git a/samplecode/SampleBlur.cpp b/samplecode/SampleBlur.cpp
index 5890ce6..3a078bd 100644
--- a/samplecode/SampleBlur.cpp
+++ b/samplecode/SampleBlur.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkBlurMask.h"
 #include "SkCanvas.h"
@@ -13,18 +13,16 @@
 #include "SkGradientShader.h"
 #include "SkMaskFilter.h"
 #include "SkUtils.h"
-#include "SkView.h"
 
-class BlurView : public SampleView {
+class BlurView : public Sample {
     SkBitmap    fBM;
 public:
     BlurView() {}
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Blur");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Blur");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -83,10 +81,9 @@
     }
 
 private:
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new BlurView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new BlurView(); )
diff --git a/samplecode/SampleCCPRGeometry.cpp b/samplecode/SampleCCPRGeometry.cpp
index a1702f3..1c0945f 100644
--- a/samplecode/SampleCCPRGeometry.cpp
+++ b/samplecode/SampleCCPRGeometry.cpp
@@ -14,13 +14,12 @@
 #include "GrRenderTargetContext.h"
 #include "GrRenderTargetContextPriv.h"
 #include "GrResourceProvider.h"
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkMakeUnique.h"
 #include "SkPaint.h"
 #include "SkPath.h"
 #include "SkRectPriv.h"
-#include "SkView.h"
 #include "ccpr/GrCCCoverageProcessor.h"
 #include "ccpr/GrCCGeometry.h"
 #include "gl/GrGLGpu.cpp"
@@ -39,14 +38,14 @@
  * coverage=0 -> black, coverage=-1 -> red). Use the keys 1-7 to cycle through the different
  * geometry processors.
  */
-class CCPRGeometryView : public SampleView {
+class CCPRGeometryView : public Sample {
 public:
     CCPRGeometryView() { this->updateGpuData(); }
     void onDrawContent(SkCanvas*) override;
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override;
-    bool onClick(SampleView::Click*) override;
-    bool onQuery(SkEvent* evt) override;
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override;
+    bool onClick(Sample::Click*) override;
+    bool onQuery(Sample::Event* evt) override;
 
 private:
     class Click;
@@ -69,7 +68,7 @@
     SkTArray<TriPointInstance> fTriPointInstances;
     SkTArray<QuadPointInstance> fQuadPointInstances;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 class CCPRGeometryView::DrawCoverageCountOp : public GrDrawOp {
@@ -365,9 +364,9 @@
     }
 }
 
-class CCPRGeometryView::Click : public SampleView::Click {
+class CCPRGeometryView::Click : public Sample::Click {
 public:
-    Click(SkView* target, int ptIdx) : SampleView::Click(target), fPtIdx(ptIdx) {}
+    Click(Sample* target, int ptIdx) : Sample::Click(target), fPtIdx(ptIdx) {}
 
     void doClick(SkPoint points[]) {
         if (fPtIdx >= 0) {
@@ -388,7 +387,7 @@
     int fPtIdx;
 };
 
-SkView::Click* CCPRGeometryView::onFindClickHandler(SkScalar x, SkScalar y, unsigned) {
+Sample::Click* CCPRGeometryView::onFindClickHandler(SkScalar x, SkScalar y, unsigned) {
     for (int i = 0; i < 4; ++i) {
         if (PrimitiveType::kCubics != fPrimitiveType && 2 == i) {
             continue;
@@ -400,20 +399,20 @@
     return new Click(this, -1);
 }
 
-bool CCPRGeometryView::onClick(SampleView::Click* click) {
+bool CCPRGeometryView::onClick(Sample::Click* click) {
     Click* myClick = (Click*)click;
     myClick->doClick(fPoints);
     this->updateAndInval();
     return true;
 }
 
-bool CCPRGeometryView::onQuery(SkEvent* evt) {
-    if (SampleCode::TitleQ(*evt)) {
-        SampleCode::TitleR(evt, "CCPRGeometry");
+bool CCPRGeometryView::onQuery(Sample::Event* evt) {
+    if (Sample::TitleQ(*evt)) {
+        Sample::TitleR(evt, "CCPRGeometry");
         return true;
     }
     SkUnichar unichar;
-    if (SampleCode::CharQ(*evt, &unichar)) {
+    if (Sample::CharQ(*evt, &unichar)) {
         if (unichar >= '1' && unichar <= '4') {
             fPrimitiveType = PrimitiveType(unichar - '1');
             if (fPrimitiveType >= PrimitiveType::kWeightedTriangles) {
diff --git a/samplecode/SampleCamera.cpp b/samplecode/SampleCamera.cpp
index fdba403..9a79003 100644
--- a/samplecode/SampleCamera.cpp
+++ b/samplecode/SampleCamera.cpp
@@ -6,9 +6,8 @@
  */
 
 #include "DecodeFile.h"
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
-#include "SkView.h"
 #include "SkCanvas.h"
 #include "SkCamera.h"
 #include "SkEmbossMaskFilter.h"
@@ -20,7 +19,7 @@
 #include "SkString.h"
 #include "SkUtils.h"
 
-class CameraView : public SampleView {
+class CameraView : public Sample {
     SkTArray<sk_sp<SkShader>> fShaders;
     int     fShaderIndex;
     bool    fFrontFace;
@@ -52,10 +51,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Camera");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Camera");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -96,10 +94,9 @@
 
 private:
     SkScalar fRX, fRY, fRZ;
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new CameraView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new CameraView(); )
diff --git a/samplecode/SampleChart.cpp b/samplecode/SampleChart.cpp
index 3e663ec..6356dec 100644
--- a/samplecode/SampleChart.cpp
+++ b/samplecode/SampleChart.cpp
@@ -5,12 +5,11 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
 #include "SkPath.h"
 #include "SkRandom.h"
-#include "SkView.h"
 
 // Generates y values for the chart plots.
 static void gen_data(SkScalar yAvg, SkScalar ySpread, int count, SkTDArray<SkScalar>* dataPts) {
@@ -81,7 +80,7 @@
 
 // A set of scrolling line plots with the area between each plot filled. Stresses out GPU path
 // filling
-class ChartView : public SampleView {
+class ChartView : public Sample {
 public:
     ChartView() {
         fShift = 0;
@@ -89,9 +88,9 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Chart");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Chart");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -175,10 +174,9 @@
     int                 fShift;
     SkISize             fSize;
     SkTDArray<SkScalar> fData[kNumGraphs];
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ChartView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ChartView(); )
diff --git a/samplecode/SampleChineseFling.cpp b/samplecode/SampleChineseFling.cpp
index 05e0218..2a25998 100644
--- a/samplecode/SampleChineseFling.cpp
+++ b/samplecode/SampleChineseFling.cpp
@@ -6,7 +6,7 @@
  */
 
 #include "Resources.h"
-#include "SampleCode.h"
+#include "Sample.h"
 #include "sk_tool_utils.h"
 
 #include "SkCanvas.h"
@@ -46,14 +46,14 @@
 #endif
 }
 
-class ChineseFlingView : public SampleView {
+class ChineseFlingView : public Sample {
 public:
     ChineseFlingView() : fBlobs(kNumBlobs) {}
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "chinese-fling");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "chinese-fling");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -126,21 +126,21 @@
     SkRandom                    fRand;
     int                         fIndex;
 
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
-class ChineseZoomView : public SampleView {
+class ChineseZoomView : public Sample {
 public:
     ChineseZoomView() : fBlobs(kNumBlobs), fScale(15.0f), fTranslate(0.0f) {}
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "chinese-zoom");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "chinese-zoom");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             if ('>' == uni) {
                 fScale += 0.125f;
                 return true;
@@ -260,13 +260,10 @@
     SkScalar                    fTranslate;
     int                         fIndex;
 
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* FlingFactory() { return new ChineseFlingView; }
-static SkViewRegister regFling(FlingFactory);
-
-static SkView* ZoomFactory() { return new ChineseZoomView; }
-static SkViewRegister regZoom(ZoomFactory);
+DEF_SAMPLE( return new ChineseFlingView(); )
+DEF_SAMPLE( return new ChineseZoomView(); )
diff --git a/samplecode/SampleCircle.cpp b/samplecode/SampleCircle.cpp
index f4e6cc9..3063324 100644
--- a/samplecode/SampleCircle.cpp
+++ b/samplecode/SampleCircle.cpp
@@ -5,11 +5,10 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
 #include "SkPath.h"
-#include "SkView.h"
 
 // ensure that we don't accidentally screw up the bounds when the oval is
 // fractional, and the impl computes the center and radii, and uses them to
@@ -22,7 +21,7 @@
     SkASSERT(r == p.getBounds());
 }
 
-class CircleView : public SampleView {
+class CircleView : public Sample {
 public:
     static const SkScalar ANIM_DX;
     static const SkScalar ANIM_DY;
@@ -35,10 +34,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Circles");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Circles");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -107,7 +105,7 @@
 
 private:
     int fN;
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 const SkScalar CircleView::ANIM_DX(SK_Scalar1 / 67);
@@ -116,5 +114,4 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new CircleView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new CircleView(); )
diff --git a/samplecode/SampleClamp.cpp b/samplecode/SampleClamp.cpp
index 3046cde..4e6e0cb 100644
--- a/samplecode/SampleClamp.cpp
+++ b/samplecode/SampleClamp.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGraphics.h"
 #include "SkRandom.h"
@@ -18,7 +17,7 @@
     return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode);
 }
 
-class ClampView : public SampleView {
+class ClampView : public Sample {
     sk_sp<SkShader> fGrad;
 
 public:
@@ -27,10 +26,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Clamp");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Clamp");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -52,10 +50,10 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ClampView; }
-static SkViewRegister reg(MyFactory);
+static Sample* MyFactory() { return new ClampView; }
+static SampleRegister reg(MyFactory);
diff --git a/samplecode/SampleClip.cpp b/samplecode/SampleClip.cpp
index 05b5a25..d872cbf 100644
--- a/samplecode/SampleClip.cpp
+++ b/samplecode/SampleClip.cpp
@@ -5,9 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAAClip.h"
-#include "SkView.h"
 #include "SkCanvas.h"
 #include "SkColorPriv.h"
 #include "SkPaint.h"
@@ -103,7 +102,7 @@
 
 typedef void (*CanvasProc)(SkCanvas*, bool);
 
-class ClipView : public SampleView {
+class ClipView : public Sample {
 public:
     ClipView() {
         SkAAClip clip;
@@ -115,10 +114,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Clip");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Clip");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -155,10 +153,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ClipView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ClipView(); )
diff --git a/samplecode/SampleClipDrawMatch.cpp b/samplecode/SampleClipDrawMatch.cpp
index 0745eff..3b556ba 100644
--- a/samplecode/SampleClipDrawMatch.cpp
+++ b/samplecode/SampleClipDrawMatch.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkInterpolator.h"
 #include "SkPath.h"
@@ -114,7 +114,7 @@
     }
 }
 
-class ClipDrawMatchView : public SampleView {
+class ClipDrawMatchView : public Sample {
 public:
     ClipDrawMatchView() : fTrans(2, 5), fGeom(kRect_Geometry), fClipFirst(true), fSign(1) {
         SkScalar values[2];
@@ -133,13 +133,13 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "ClipDrawMatch");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "ClipDrawMatch");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case '1': fGeom = kRect_Geometry; return true;
                 case '2': fGeom = kRRect_Geometry; return true;
@@ -252,10 +252,9 @@
     int             fSign;
     const double    fStart = SkTime::GetMSecs();
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ClipDrawMatchView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ClipDrawMatchView(); )
diff --git a/samplecode/SampleClock.cpp b/samplecode/SampleClock.cpp
index ff3a5b1..dc240b3 100644
--- a/samplecode/SampleClock.cpp
+++ b/samplecode/SampleClock.cpp
@@ -4,7 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 
 #include "SkCanvas.h"
 #include "SkPath.h"
@@ -17,15 +17,14 @@
 
 #define USE_PATH 1
 
-class ClockView : public SampleView {
+class ClockView : public Sample {
 public:
     ClockView() {}
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Clock");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Clock");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -223,10 +222,9 @@
 
 private:
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ClockView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ClockView(); )
diff --git a/samplecode/SampleCode.cpp b/samplecode/SampleCode.cpp
deleted file mode 100644
index 6202106..0000000
--- a/samplecode/SampleCode.cpp
+++ /dev/null
@@ -1,107 +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 "SampleCode.h"
-#include "SkCanvas.h"
-#include "SkString.h"
-
-#if SK_SUPPORT_GPU
-#   include "GrContext.h"
-#else
-class GrContext;
-#endif
-
-//////////////////////////////////////////////////////////////////////////////
-
-bool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
-    if (evt.isType(gCharEvtName)) {
-        if (outUni) {
-            *outUni = evt.getFast32();
-        }
-        return true;
-    }
-    return false;
-}
-
-bool SampleCode::TitleQ(const SkEvent& evt) {
-    return evt.isType(gTitleEvtName);
-}
-
-void SampleCode::TitleR(SkEvent* evt, const char title[]) {
-    SkASSERT(evt && TitleQ(*evt));
-    evt->setString(gTitleEvtName, title);
-}
-
-bool SampleCode::RequestTitle(SkView* view, SkString* title) {
-    SkEvent evt(gTitleEvtName);
-    if (view->doQuery(&evt)) {
-        title->set(evt.findString(gTitleEvtName));
-        return true;
-    }
-    return false;
-}
-
-SkViewRegister* SkViewRegister::gHead;
-SkViewRegister::SkViewRegister(SkViewFactory* fact) : fFact(fact) {
-    fFact->ref();
-    fChain = gHead;
-    gHead = this;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkFuncViewFactory::SkFuncViewFactory(SkViewCreateFunc func)
-    : fCreateFunc(func) {
-}
-
-SkView* SkFuncViewFactory::operator() () const {
-    return (*fCreateFunc)();
-}
-
-SkViewRegister::SkViewRegister(SkViewCreateFunc func) {
-    fFact = new SkFuncViewFactory(func);
-    fChain = gHead;
-    gHead = this;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-static const char is_sample_view_tag[] = "sample-is-sample-view";
-
-bool SampleView::IsSampleView(SkView* view) {
-    SkEvent evt(is_sample_view_tag);
-    return view->doQuery(&evt);
-}
-
-bool SampleView::onQuery(SkEvent* evt) {
-    if (evt->isType(is_sample_view_tag)) {
-        return true;
-    }
-    return this->INHERITED::onQuery(evt);
-}
-
-void SampleView::onDraw(SkCanvas* canvas) {
-    if (!fHaveCalledOnceBeforeDraw) {
-        fHaveCalledOnceBeforeDraw = true;
-        this->onOnceBeforeDraw();
-    }
-    this->onDrawBackground(canvas);
-
-    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();
-    }
-#endif
-}
-
-void SampleView::onDrawBackground(SkCanvas* canvas) {
-    canvas->drawColor(fBGColor);
-}
-
diff --git a/samplecode/SampleCode.h b/samplecode/SampleCode.h
deleted file mode 100644
index 3310d28..0000000
--- a/samplecode/SampleCode.h
+++ /dev/null
@@ -1,108 +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.
- */
-
-#ifndef SampleCode_DEFINED
-#define SampleCode_DEFINED
-
-#include "SkColor.h"
-#include "SkEvent.h"
-#include "SkMacros.h"
-#include "SkView.h"
-
-class SkAnimTimer;
-
-#define DEF_SAMPLE(code) \
-    static SkView*          SK_MACRO_APPEND_LINE(F_)() { code } \
-    static SkViewRegister   SK_MACRO_APPEND_LINE(R_)(SK_MACRO_APPEND_LINE(F_));
-
-static const char gCharEvtName[] = "SampleCode_Char_Event";
-static const char gTitleEvtName[] = "SampleCode_Title_Event";
-
-class SampleCode {
-public:
-    static bool CharQ(const SkEvent&, SkUnichar* outUni);
-
-    static bool TitleQ(const SkEvent&);
-    static void TitleR(SkEvent*, const char title[]);
-    static bool RequestTitle(SkView* view, SkString* title);
-
-    friend class SampleWindow;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-// interface that constructs SkViews
-class SkViewFactory : public SkRefCnt {
-public:
-    virtual SkView* operator() () const = 0;
-};
-
-typedef SkView* (*SkViewCreateFunc)();
-
-// wraps SkViewCreateFunc in SkViewFactory interface
-class SkFuncViewFactory : public SkViewFactory {
-public:
-    SkFuncViewFactory(SkViewCreateFunc func);
-    SkView* operator() () const override;
-
-private:
-    SkViewCreateFunc fCreateFunc;
-};
-
-class SkViewRegister : public SkRefCnt {
-public:
-    explicit SkViewRegister(SkViewFactory*);
-    explicit SkViewRegister(SkViewCreateFunc);
-
-    ~SkViewRegister() {
-        fFact->unref();
-    }
-
-    static const SkViewRegister* Head() { return gHead; }
-
-    SkViewRegister* next() const { return fChain; }
-    const SkViewFactory*   factory() const { return fFact; }
-
-private:
-    SkViewFactory*  fFact;
-    SkViewRegister* fChain;
-
-    static SkViewRegister* gHead;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-class SampleView : public SkView {
-public:
-    SampleView()
-        : fBGColor(SK_ColorWHITE)
-        , fHaveCalledOnceBeforeDraw(false)
-    {}
-
-    void setBGColor(SkColor color) { fBGColor = color; }
-    bool animate(const SkAnimTimer& timer) { return this->onAnimate(timer); }
-
-    static bool IsSampleView(SkView*);
-
-protected:
-    virtual void onDrawBackground(SkCanvas*);
-    virtual void onDrawContent(SkCanvas*) = 0;
-    virtual bool onAnimate(const SkAnimTimer&) { return false; }
-    virtual void onOnceBeforeDraw() {}
-
-    // overrides
-    virtual bool onQuery(SkEvent* evt);
-    virtual void onDraw(SkCanvas*);
-
-    SkColor fBGColor;
-
-private:
-    bool fHaveCalledOnceBeforeDraw;
-    typedef SkView INHERITED;
-};
-
-#endif
diff --git a/samplecode/SampleColorFilter.cpp b/samplecode/SampleColorFilter.cpp
index efda5e9..8a44fc4 100644
--- a/samplecode/SampleColorFilter.cpp
+++ b/samplecode/SampleColorFilter.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 #include "sk_tool_utils.h"
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkColorFilter.h"
 #include "SkPaint.h"
@@ -107,7 +106,7 @@
     return bitmap;
 }
 
-class ColorFilterView : public SampleView {
+class ColorFilterView : public Sample {
     SkBitmap fBitmap;
     sk_sp<SkShader> fShader;
     enum {
@@ -125,10 +124,9 @@
         }
     }
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "ColorFilter");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "ColorFilter");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -190,10 +188,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ColorFilterView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ColorFilterView(); )
diff --git a/samplecode/SampleComplexClip.cpp b/samplecode/SampleComplexClip.cpp
index af7f38e..fea5dd1 100644
--- a/samplecode/SampleComplexClip.cpp
+++ b/samplecode/SampleComplexClip.cpp
@@ -5,23 +5,21 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkPath.h"
-#include "SkView.h"
 #include "SkClipOpPriv.h"
 
-class ComplexClipView : public SampleView {
+class ComplexClipView : public Sample {
 public:
     ComplexClipView() {
         this->setBGColor(0xFFA0DDA0);
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "ComplexClip");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "ComplexClip");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -145,10 +143,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ComplexClipView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ComplexClipView(); )
diff --git a/samplecode/SampleConcavePaths.cpp b/samplecode/SampleConcavePaths.cpp
index de9f9b6..dd125bd 100644
--- a/samplecode/SampleConcavePaths.cpp
+++ b/samplecode/SampleConcavePaths.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkGraphics.h"
@@ -22,15 +21,14 @@
 
 #include "SkGeometry.h"
 
-class ConcavePathView : public SampleView {
+class ConcavePathView : public Sample {
 public:
     ConcavePathView() {}
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "ConcavePaths");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "ConcavePaths");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -135,10 +133,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ConcavePathView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ConcavePathView(); )
diff --git a/samplecode/SampleCowboy.cpp b/samplecode/SampleCowboy.cpp
index f9b9d6e..06bbf88 100644
--- a/samplecode/SampleCowboy.cpp
+++ b/samplecode/SampleCowboy.cpp
@@ -9,7 +9,7 @@
 
 #ifdef SK_XML
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "Resources.h"
 #include "SkCanvas.h"
 #include "SkDOM.h"
@@ -18,11 +18,10 @@
 #include "SkRect.h"
 #include "SkStream.h"
 #include "SkSVGDOM.h"
-#include "SkView.h"
 
 namespace {
 
-class CowboyView : public SampleView {
+class CowboyView : public Sample {
 public:
     CowboyView()
         : fLabel("SampleCowboy")
@@ -97,9 +96,9 @@
         this->INHERITED::onSizeChange();
     }
 
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, fLabel.c_str());
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, fLabel.c_str());
             return true;
         }
 
@@ -140,7 +139,7 @@
     int             fAnimationLoop;
     SkScalar        fDelta;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 } // anonymous namespace
diff --git a/samplecode/SampleDash.cpp b/samplecode/SampleDash.cpp
index f2c6b8b..5880d79 100644
--- a/samplecode/SampleDash.cpp
+++ b/samplecode/SampleDash.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGraphics.h"
 #include "SkRandom.h"
@@ -32,17 +31,16 @@
     paint->setShader(s)->unref();
 }
 
-class DashView : public SampleView {
+class DashView : public Sample {
 public:
     DashView() {
         this->setBGColor(0xFFDDDDDD);
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Dash");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Dash");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -82,10 +80,10 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new DashView; }
-static SkViewRegister reg(MyFactory);
+static Sample* MyFactory() { return new DashView; }
+static SampleRegister reg(MyFactory);
diff --git a/samplecode/SampleDegenerateTwoPtRadials.cpp b/samplecode/SampleDegenerateTwoPtRadials.cpp
index cdd5e1c..b9044c1 100644
--- a/samplecode/SampleDegenerateTwoPtRadials.cpp
+++ b/samplecode/SampleDegenerateTwoPtRadials.cpp
@@ -5,9 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
-#include "SkView.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkString.h"
@@ -35,7 +34,7 @@
 }
 
 
-class DegenerateTwoPtRadialsView : public SampleView {
+class DegenerateTwoPtRadialsView : public Sample {
 public:
     DegenerateTwoPtRadialsView() {
         fTime = 0;
@@ -43,9 +42,9 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "DegenerateTwoPtRadials");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "DegenerateTwoPtRadials");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -82,10 +81,9 @@
 
 private:
     SkScalar           fTime;
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new DegenerateTwoPtRadialsView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new DegenerateTwoPtRadialsView(); )
diff --git a/samplecode/SampleDither.cpp b/samplecode/SampleDither.cpp
index 1dd4271..5eab2e1 100644
--- a/samplecode/SampleDither.cpp
+++ b/samplecode/SampleDither.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkPath.h"
@@ -103,7 +102,7 @@
     }
 }
 
-class DitherView : public SampleView {
+class DitherView : public Sample {
 public:
     SkBitmap    fBM, fBMPreDither, fBM16;
     SkScalar fAngle;
@@ -120,10 +119,9 @@
         this->setBGColor(0xFF181818);
     }
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Dither");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Dither");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -162,10 +160,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new DitherView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new DitherView(); )
diff --git a/samplecode/SampleEffects.cpp b/samplecode/SampleEffects.cpp
index d890232..4540cd7 100644
--- a/samplecode/SampleEffects.cpp
+++ b/samplecode/SampleEffects.cpp
@@ -4,7 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMask.h"
 #include "SkCanvas.h"
 #include "SkColorMatrixFilter.h"
@@ -12,7 +12,6 @@
 #include "SkEmbossMaskFilter.h"
 #include "SkGradientShader.h"
 #include "SkPaint.h"
-#include "SkView.h"
 
 
 //#define COLOR 0xFFFF8844
@@ -56,7 +55,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-class EffectsView : public SampleView {
+class EffectsView : public Sample {
 public:
     SkPath fPath;
     SkPaint fPaint[SK_ARRAY_COUNT(gPaintProcs)];
@@ -91,10 +90,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Effects");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Effects");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -110,10 +108,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new EffectsView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new EffectsView(); )
diff --git a/samplecode/SampleEmboss.cpp b/samplecode/SampleEmboss.cpp
index 4aba6fd..04823f3 100644
--- a/samplecode/SampleEmboss.cpp
+++ b/samplecode/SampleEmboss.cpp
@@ -5,9 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMask.h"
-#include "SkView.h"
 #include "SkCanvas.h"
 #include "SkEmbossMaskFilter.h"
 #include "SkGradientShader.h"
@@ -22,7 +21,7 @@
 #include "SkTime.h"
 #include "SkTypeface.h"
 
-class EmbossView : public SampleView {
+class EmbossView : public Sample {
     SkEmbossMaskFilter::Light   fLight;
 public:
     EmbossView() {
@@ -34,10 +33,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Emboss");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Emboss");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -59,10 +57,9 @@
 
 private:
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new EmbossView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new EmbossView(); )
diff --git a/samplecode/SampleFatBits.cpp b/samplecode/SampleFatBits.cpp
index 2074856..5e53816 100644
--- a/samplecode/SampleFatBits.cpp
+++ b/samplecode/SampleFatBits.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlendMode.h"
 #include "SkCanvas.h"
 #include "SkClipOpPriv.h"
@@ -23,7 +23,6 @@
 #include "SkString.h"
 #include "SkSurface.h"
 #include "SkTypes.h"
-#include "SkView.h"
 #include "sk_tool_utils.h"
 
 class SkEvent;
@@ -362,17 +361,17 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-class IndexClick : public SkView::Click {
+class IndexClick : public Sample::Click {
     int fIndex;
 public:
-    IndexClick(SkView* v, int index) : SkView::Click(v), fIndex(index) {}
+    IndexClick(Sample* v, int index) : Sample::Click(v), fIndex(index) {}
 
-    static int GetIndex(SkView::Click* click) {
+    static int GetIndex(Sample::Click* click) {
         return ((IndexClick*)click)->fIndex;
     }
 };
 
-class DrawLineView : public SampleView {
+class DrawLineView : public Sample {
     FatBits fFB;
     SkPoint fPts[3];
     bool    fIsRect;
@@ -392,13 +391,13 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "FatBits");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "FatBits");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case 'c':
                     fFB.setUseClip(!fFB.getUseClip());
@@ -475,7 +474,7 @@
         }
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
         SkPoint pt = { x, y };
         int index = -1;
         int count = fFB.getTriangle() ? 3 : 2;
@@ -506,10 +505,9 @@
 
 private:
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new DrawLineView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new DrawLineView(); )
diff --git a/samplecode/SampleFillType.cpp b/samplecode/SampleFillType.cpp
index 582dd96..cd60157 100644
--- a/samplecode/SampleFillType.cpp
+++ b/samplecode/SampleFillType.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkCornerPathEffect.h"
 #include "SkGradientShader.h"
@@ -14,7 +13,7 @@
 #include "SkShader.h"
 #include "SkUtils.h"
 
-class FillTypeView : public SampleView {
+class FillTypeView : public Sample {
     SkPath fPath;
 public:
     FillTypeView() {
@@ -26,10 +25,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "FillType");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "FillType");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -85,10 +83,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new FillTypeView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new FillTypeView(); )
diff --git a/samplecode/SampleFilter2.cpp b/samplecode/SampleFilter2.cpp
index 72beb06..33d09f4 100644
--- a/samplecode/SampleFilter2.cpp
+++ b/samplecode/SampleFilter2.cpp
@@ -6,8 +6,7 @@
  */
 
 #include "DecodeFile.h"
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkColorFilter.h"
 #include "SkColorPriv.h"
@@ -24,7 +23,7 @@
     "/skimages/background_01.png"
 };
 
-class Filter2View : public SampleView {
+class Filter2View : public Sample {
 public:
     SkBitmap*   fBitmaps;
     int         fBitmapCount;
@@ -50,12 +49,11 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
             SkString str("Filter/Dither ");
             str.append(gNames[fCurrIndex]);
-            SampleCode::TitleR(evt, str.c_str());
+            Sample::TitleR(evt, str.c_str());
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -109,10 +107,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new Filter2View; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new Filter2View(); )
diff --git a/samplecode/SampleFilterFuzz.cpp b/samplecode/SampleFilterFuzz.cpp
index 7038286b..393d974 100644
--- a/samplecode/SampleFilterFuzz.cpp
+++ b/samplecode/SampleFilterFuzz.cpp
@@ -4,7 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "Sk1DPathEffect.h"
 #include "Sk2DPathEffect.h"
 #include "SkAlphaThresholdFilter.h"
@@ -39,7 +39,6 @@
 #include "SkTableColorFilter.h"
 #include "SkTileImageFilter.h"
 #include "SkTypeface.h"
-#include "SkView.h"
 #include "SkXfermodeImageFilter.h"
 #if SK_SUPPORT_GPU
 #include "text/GrSDFMaskFilter.h"
@@ -786,17 +785,16 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-class ImageFilterFuzzView : public SampleView {
+class ImageFilterFuzzView : public Sample {
 public:
     ImageFilterFuzzView() {
         this->setBGColor(0xFFDDDDDD);
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "ImageFilterFuzzer");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "ImageFilterFuzzer");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -811,10 +809,9 @@
     }
 
 private:
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ImageFilterFuzzView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ImageFilterFuzzView(); )
diff --git a/samplecode/SampleFilterQuality.cpp b/samplecode/SampleFilterQuality.cpp
index d7edbd3..a686efb 100644
--- a/samplecode/SampleFilterQuality.cpp
+++ b/samplecode/SampleFilterQuality.cpp
@@ -5,10 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "gm.h"
-
 #include "Resources.h"
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
 #include "SkCanvas.h"
 #include "SkInterpolator.h"
@@ -138,7 +136,7 @@
     canvas->drawLine(r.left(), r.bottom(), r.right(), r.top(), p);
 }
 
-class FilterQualityView : public SampleView {
+class FilterQualityView : public Sample {
     sk_sp<SkImage>  fImage;
     AnimValue       fScale, fAngle;
     SkSize          fCell;
@@ -167,13 +165,13 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "FilterQuality");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "FilterQuality");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case '1': fAngle.inc(-ANGLE_DELTA); return true;
                 case '2': fAngle.inc( ANGLE_DELTA); return true;
@@ -297,10 +295,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new FilterQualityView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new FilterQualityView(); )
diff --git a/samplecode/SampleFlutterAnimate.cpp b/samplecode/SampleFlutterAnimate.cpp
index 8135729..975156f 100644
--- a/samplecode/SampleFlutterAnimate.cpp
+++ b/samplecode/SampleFlutterAnimate.cpp
@@ -5,9 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
-#include "SkView.h"
 #include "SkCanvas.h"
 #include "SkUtils.h"
 #include "SkColorPriv.h"
@@ -24,7 +23,7 @@
 
 // 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 SampleView {
+class FlutterAnimateView : public Sample {
 public:
     FlutterAnimateView() : fCurrTime(0), fResetTime(0) {}
 
@@ -34,10 +33,9 @@
         initChars();
     }
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "FlutterAnimate");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "FlutterAnimate");
             return true;
         }
 
@@ -106,10 +104,9 @@
     static constexpr int kNumChars = 40;
     AnimatedChar fChars[kNumChars];
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new FlutterAnimateView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new FlutterAnimateView(); )
diff --git a/samplecode/SampleFontCache.cpp b/samplecode/SampleFontCache.cpp
index 97c9565..2428657 100644
--- a/samplecode/SampleFontCache.cpp
+++ b/samplecode/SampleFontCache.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGraphics.h"
 #include "SkRandom.h"
@@ -75,7 +74,7 @@
     return nullptr;
 }
 
-class FontCacheView : public SampleView {
+class FontCacheView : public Sample {
 public:
     enum { N = 4 };
 
@@ -112,10 +111,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "FontCache");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "FontCache");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -132,10 +130,10 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new FontCacheView; }
-static SkViewRegister reg(MyFactory);
+static Sample* MyFactory() { return new FontCacheView; }
+static SampleRegister reg(MyFactory);
diff --git a/samplecode/SampleFontScalerTest.cpp b/samplecode/SampleFontScalerTest.cpp
index b41166d..c92f123 100644
--- a/samplecode/SampleFontScalerTest.cpp
+++ b/samplecode/SampleFontScalerTest.cpp
@@ -4,7 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "Sk1DPathEffect.h"
 #include "SkCanvas.h"
 #include "SkColorFilter.h"
@@ -19,7 +19,6 @@
 #include "SkShader.h"
 #include "SkTypeface.h"
 #include "SkUtils.h"
-#include "SkView.h"
 
 static constexpr struct {
     const char* fName;
@@ -36,7 +35,7 @@
 
 static const int gFaceCount = SK_ARRAY_COUNT(gFaces);
 
-class FontScalerTestView : public SampleView {
+class FontScalerTestView : public Sample {
     sk_sp<SkTypeface> fFaces[gFaceCount];
 
 public:
@@ -47,10 +46,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "FontScaler Test");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "FontScaler Test");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -117,10 +115,9 @@
     }
 
 private:
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new FontScalerTestView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new FontScalerTestView(); )
diff --git a/samplecode/SampleFuzz.cpp b/samplecode/SampleFuzz.cpp
index 1379e73..bf29de6 100644
--- a/samplecode/SampleFuzz.cpp
+++ b/samplecode/SampleFuzz.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkMaskFilter.h"
 #include "SkPaint.h"
@@ -359,17 +358,16 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-class FuzzView : public SampleView {
+class FuzzView : public Sample {
 public:
     FuzzView() {
         this->setBGColor(0xFFDDDDDD);
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Fuzzer");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Fuzzer");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -384,10 +382,9 @@
     }
 
 private:
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new FuzzView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new FuzzView(); )
diff --git a/samplecode/SampleGlyphTransform.cpp b/samplecode/SampleGlyphTransform.cpp
index b5d44f8..30ea434 100644
--- a/samplecode/SampleGlyphTransform.cpp
+++ b/samplecode/SampleGlyphTransform.cpp
@@ -4,7 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "sk_tool_utils.h"
 
 #include "SkAnimTimer.h"
@@ -17,7 +17,7 @@
 // Implementation in C++ of Animated Emoji
 // See https://t.d3fc.io/status/705212795936247808
 
-class GlyphTransformView : public SampleView {
+class GlyphTransformView : public Sample {
 public:
     GlyphTransformView() {}
 
@@ -27,10 +27,9 @@
         fEmojiFont.fText = sk_tool_utils::emoji_sample_text();
     }
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Glyph Transform");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Glyph Transform");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -72,10 +71,9 @@
     SkScalar fScale;
     SkScalar fRotate;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new GlyphTransformView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new GlyphTransformView(); )
diff --git a/samplecode/SampleGradients.cpp b/samplecode/SampleGradients.cpp
index 247bcf6..2ec26a5 100644
--- a/samplecode/SampleGradients.cpp
+++ b/samplecode/SampleGradients.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 
@@ -112,16 +111,16 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-class GradientsView : public SampleView {
+class GradientsView : public Sample {
 public:
     GradientsView() {
         this->setBGColor(0xFFDDDDDD);
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Gradients");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Gradients");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -163,10 +162,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new GradientsView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new GradientsView(); )
diff --git a/samplecode/SampleHT.cpp b/samplecode/SampleHT.cpp
index 7eb9806..b12aa27 100644
--- a/samplecode/SampleHT.cpp
+++ b/samplecode/SampleHT.cpp
@@ -5,9 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
-#include "SkView.h"
 #include "SkCanvas.h"
 #include "SkDrawable.h"
 #include "SkInterpolator.h"
@@ -114,7 +113,7 @@
     SkRect onGetBounds() override { return fR; }
 };
 
-class HTView : public SampleView {
+class HTView : public Sample {
 public:
     enum {
         N = 50,
@@ -143,9 +142,9 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "HT");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "HT");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -163,7 +162,7 @@
         return true;
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
         // search backwards to find the top-most
         for (int i = N - 1; i >= 0; --i) {
             if (fArray[i].fDrawable->hitTest(x, y)) {
@@ -175,10 +174,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new HTView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new HTView(); )
diff --git a/samplecode/SampleHairCurves.cpp b/samplecode/SampleHairCurves.cpp
index 967c4f2..a865815 100644
--- a/samplecode/SampleHairCurves.cpp
+++ b/samplecode/SampleHairCurves.cpp
@@ -4,22 +4,20 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkPath.h"
 #include "SkRandom.h"
 
-class HairCurvesView : public SampleView {
+class HairCurvesView : public Sample {
 public:
     HairCurvesView() {
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "HairCurves");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "HairCurves");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -123,10 +121,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new HairCurvesView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new HairCurvesView(); )
diff --git a/samplecode/SampleHairModes.cpp b/samplecode/SampleHairModes.cpp
index 320cb0c..d162bba 100644
--- a/samplecode/SampleHairModes.cpp
+++ b/samplecode/SampleHairModes.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkColorPriv.h"
@@ -69,7 +68,7 @@
                                       SkShader::kRepeat_TileMode, &m);
 }
 
-class HairModesView : public SampleView {
+class HairModesView : public Sample {
     SkPaint fBGPaint;
 public:
     HairModesView() {
@@ -77,10 +76,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "HairlineModes");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "HairlineModes");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -117,10 +115,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new HairModesView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new HairModesView(); )
diff --git a/samplecode/SampleHairline.cpp b/samplecode/SampleHairline.cpp
index b90e99e..426b819 100644
--- a/samplecode/SampleHairline.cpp
+++ b/samplecode/SampleHairline.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
@@ -23,7 +23,6 @@
 #include "SkTo.h"
 #include "SkTypeface.h"
 #include "SkUtils.h"
-#include "SkView.h"
 
 static SkRandom gRand;
 
@@ -168,7 +167,7 @@
     return (index + 1) % SK_ARRAY_COUNT(gProcs);
 }
 
-class HairlineView : public SampleView {
+class HairlineView : public Sample {
     SkMSec fNow;
     int fProcIndex;
     bool fDoAA;
@@ -180,12 +179,11 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
             SkString str;
             str.printf("Hair-%s", gProcs[fProcIndex].fName);
-            SampleCode::TitleR(evt, str.c_str());
+            Sample::TitleR(evt, str.c_str());
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -227,17 +225,16 @@
         return true;
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
         fDoAA = !fDoAA;
         return this->INHERITED::onFindClickHandler(x, y, modi);
     }
 
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new HairlineView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new HairlineView(); )
diff --git a/samplecode/SampleIdentityScale.cpp b/samplecode/SampleIdentityScale.cpp
index ad23541..217a2ca 100644
--- a/samplecode/SampleIdentityScale.cpp
+++ b/samplecode/SampleIdentityScale.cpp
@@ -6,10 +6,8 @@
  */
 
 #include "DecodeFile.h"
-#include "gm.h"
-
 #include "Resources.h"
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMaskFilter.h"
 #include "SkCanvas.h"
 #include "SkColorPriv.h"
@@ -22,7 +20,7 @@
 // Intended to exercise pixel snapping observed with scaled images (and
 // with non-scaled images, but for a different reason):  Bug 1145
 
-class IdentityScaleView : public SampleView {
+class IdentityScaleView : public Sample {
 public:
     IdentityScaleView(const char imageFilename[]) {
         if (!DecodeDataToBitmap(GetResourceAsData(imageFilename), &fBM)) {
@@ -34,10 +32,9 @@
 protected:
     SkBitmap fBM;
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "IdentityScale");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "IdentityScale");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -74,10 +71,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new IdentityScaleView("images/mandrill_256.png"); }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new IdentityScaleView("images/mandrill_256.png"); )
diff --git a/samplecode/SampleLCD.cpp b/samplecode/SampleLCD.cpp
index ca7d3f6..22aaba6 100644
--- a/samplecode/SampleLCD.cpp
+++ b/samplecode/SampleLCD.cpp
@@ -4,21 +4,19 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
 #include "SkShader.h"
 
-class LCDView : public SkView {
+class LCDView : public Sample {
 public:
     LCDView() {}
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "LCD Text");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "LCD Text");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -28,7 +26,7 @@
         canvas->drawColor(SK_ColorWHITE);
     }
 
-    virtual void onDraw(SkCanvas* canvas) {
+    void onDrawContent(SkCanvas* canvas) override {
         this->drawBG(canvas);
 
         SkPaint paint;
@@ -56,10 +54,9 @@
     }
 
 private:
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new LCDView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new LCDView(); )
diff --git a/samplecode/SampleLayerMask.cpp b/samplecode/SampleLayerMask.cpp
index b039421..b13ef31 100644
--- a/samplecode/SampleLayerMask.cpp
+++ b/samplecode/SampleLayerMask.cpp
@@ -5,26 +5,24 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
 #include "SkPath.h"
-#include "SkView.h"
 
 ///////////////////////////////////////////////////////////////////////////////
 
-class LayerMaskView : public SampleView {
+class LayerMaskView : public Sample {
 public:
     LayerMaskView() {
         this->setBGColor(0xFFDDDDDD);
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "LayerMask");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "LayerMask");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -66,10 +64,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new LayerMaskView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new LayerMaskView(); )
diff --git a/samplecode/SampleLayers.cpp b/samplecode/SampleLayers.cpp
index f6c637d..ac7b477 100644
--- a/samplecode/SampleLayers.cpp
+++ b/samplecode/SampleLayers.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkBlurMaskFilter.h"
 #include "SkCamera.h"
@@ -96,15 +95,14 @@
     canvas->drawRect(r, paint);
 }
 
-class LayersView : public SkView {
+class LayersView : public Sample {
 public:
     LayersView() {}
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Layers");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Layers");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -114,7 +112,7 @@
         canvas->drawColor(SK_ColorGRAY);
     }
 
-    void onDraw(SkCanvas* canvas) override {
+    void onDrawContent(SkCanvas* canvas) override {
         this->drawBG(canvas);
 
         if (true) {
@@ -176,7 +174,7 @@
     }
 
 private:
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 DEF_SAMPLE( return new LayersView; )
 
@@ -189,7 +187,7 @@
 #include "Resources.h"
 #include "SkAnimTimer.h"
 
-class BackdropView : public SampleView {
+class BackdropView : public Sample {
     SkPoint fCenter;
     SkScalar fAngle;
     sk_sp<SkImage> fImage;
@@ -203,10 +201,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Backdrop");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Backdrop");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -239,7 +236,7 @@
         return true;
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
         return new Click(this);
     }
 
@@ -249,6 +246,6 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 DEF_SAMPLE( return new BackdropView; )
diff --git a/samplecode/SampleLighting.cpp b/samplecode/SampleLighting.cpp
index 0e68135..ef0694b 100644
--- a/samplecode/SampleLighting.cpp
+++ b/samplecode/SampleLighting.cpp
@@ -6,7 +6,7 @@
  */
 
 #include "DecodeFile.h"
-#include "SampleCode.h"
+#include "Sample.h"
 #include "Resources.h"
 #include "SkCanvas.h"
 #include "SkLightingShader.h"
@@ -29,7 +29,7 @@
 
 ////////////////////////////////////////////////////////////////////////////
 
-class LightingView : public SampleView {
+class LightingView : public Sample {
 public:
     LightingView() : fLightAngle(0.0f) , fColorFactor(0.0f) {
         {
@@ -57,10 +57,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Lighting");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Lighting");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -78,7 +77,7 @@
         canvas->drawRect(fRect, paint);
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
         return this->INHERITED::onFindClickHandler(x, y, modi);
     }
 
@@ -100,10 +99,9 @@
     SkScalar              fLightAngle;
     SkScalar              fColorFactor;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new LightingView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new LightingView(); )
diff --git a/samplecode/SampleLines.cpp b/samplecode/SampleLines.cpp
index 657962c..0f270d6 100644
--- a/samplecode/SampleLines.cpp
+++ b/samplecode/SampleLines.cpp
@@ -6,8 +6,7 @@
  */
 
 #include "DecodeFile.h"
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkCornerPathEffect.h"
 #include "SkGradientShader.h"
@@ -24,15 +23,14 @@
 #include "SkStream.h"
 #include "SkColorPriv.h"
 
-class LinesView : public SampleView {
+class LinesView : public Sample {
 public:
     LinesView() {}
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Lines");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Lines");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -92,17 +90,16 @@
         canvas->drawLine(x, y, x + SkIntToScalar(90), y + SkIntToScalar(90), paint);
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
         fAlpha = SkScalarRoundToInt(y);
         return nullptr;
     }
 private:
 
     int fAlpha;
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new LinesView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new LinesView(); )
diff --git a/samplecode/SampleLitAtlas.cpp b/samplecode/SampleLitAtlas.cpp
index 9ca6df2..534b66b 100644
--- a/samplecode/SampleLitAtlas.cpp
+++ b/samplecode/SampleLitAtlas.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
 #include "SkBitmapProcShader.h"
 #include "SkCanvas.h"
@@ -15,7 +15,6 @@
 #include "SkNormalSource.h"
 #include "SkRandom.h"
 #include "SkRSXform.h"
-#include "SkView.h"
 
 #include "sk_tool_utils.h"
 
@@ -448,18 +447,18 @@
     typedef SkDrawable INHERITED;
 };
 
-class DrawLitAtlasView : public SampleView {
+class DrawLitAtlasView : public Sample {
 public:
     DrawLitAtlasView() : fDrawable(new DrawLitAtlasDrawable(SkRect::MakeWH(640, 480))) {}
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "DrawLitAtlas");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "DrawLitAtlas");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case 'C':
                     fDrawable->toggleUseColors();
@@ -494,10 +493,9 @@
 private:
     sk_sp<DrawLitAtlasDrawable> fDrawable;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new DrawLitAtlasView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new DrawLitAtlasView(); )
diff --git a/samplecode/SampleLua.cpp b/samplecode/SampleLua.cpp
index 7b04fd0..68cfc1d 100644
--- a/samplecode/SampleLua.cpp
+++ b/samplecode/SampleLua.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkLua.h"
 #include "SkCanvas.h"
 #include "Resources.h"
@@ -35,7 +34,7 @@
     "end"
     ;
 
-class LuaView : public SampleView {
+class LuaView : public Sample {
 public:
     LuaView() : fLua(nullptr) {}
 
@@ -69,13 +68,13 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Lua");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Lua");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             lua_State* L = this->ensureLua();
             lua_getglobal(L, gUnicharName);
             if (lua_isfunction(L, -1)) {
@@ -114,7 +113,7 @@
         }
     }
 
-    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
+    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
                                               unsigned modi) override {
         lua_State* L = this->ensureLua();
         lua_getglobal(L, gClickName);
@@ -160,10 +159,9 @@
 private:
     SkLua* fLua;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new LuaView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new LuaView(); )
diff --git a/samplecode/SampleManyRects.cpp b/samplecode/SampleManyRects.cpp
index 737787a..779c9e9 100644
--- a/samplecode/SampleManyRects.cpp
+++ b/samplecode/SampleManyRects.cpp
@@ -4,17 +4,16 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
 #include "SkRandom.h"
 #include "SkShader.h"
-#include "SkView.h"
 
 /**
  * Animated sample used to develop a predecessor of GrDrawOp combining.
  */
-class ManyRectsView : public SampleView {
+class ManyRectsView : public Sample {
 private:
     enum {
         N = 1000,
@@ -24,9 +23,9 @@
     ManyRectsView() {}
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "ManyRects");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "ManyRects");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -66,10 +65,9 @@
 
 private:
     SkRandom fRandom;
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ManyRectsView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ManyRectsView(); )
diff --git a/samplecode/SampleMeasure.cpp b/samplecode/SampleMeasure.cpp
index dc771db..24f38a8 100644
--- a/samplecode/SampleMeasure.cpp
+++ b/samplecode/SampleMeasure.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkPath.h"
@@ -77,7 +76,7 @@
     }
 }
 
-class MeasureView : public SampleView {
+class MeasureView : public Sample {
 public:
     SkPaint fPaint;
 
@@ -88,10 +87,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Measure");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Measure");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -103,10 +101,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new MeasureView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new MeasureView(); )
diff --git a/samplecode/SampleMegaStroke.cpp b/samplecode/SampleMegaStroke.cpp
index a7c2e54..a8f349a 100644
--- a/samplecode/SampleMegaStroke.cpp
+++ b/samplecode/SampleMegaStroke.cpp
@@ -5,12 +5,12 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkPath.h"
 #include "SkRandom.h"
 
-class MegaStrokeView : public SampleView {
+class MegaStrokeView : public Sample {
 public:
     MegaStrokeView() {
         fClip.set(0, 0, 950, 600);
@@ -26,15 +26,14 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "MegaStroke");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "MegaStroke");
             return true;
         }
 
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
            fClip.set(0, 0, 950, 600);
         }
         if (evt->isType("SampleCode_Key_Event")) {
@@ -88,10 +87,9 @@
     SkRect      fClip;
     int         fAngle;
     int         fPlusMinus;
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new MegaStrokeView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new MegaStrokeView(); )
diff --git a/samplecode/SampleNima.cpp b/samplecode/SampleNima.cpp
index f7bee1b..c9e1d62 100644
--- a/samplecode/SampleNima.cpp
+++ b/samplecode/SampleNima.cpp
@@ -5,16 +5,15 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SampleNimaActor.h"
 #include "SkAnimTimer.h"
-#include "SkView.h"
 #include <nima/Animation/ActorAnimationInstance.hpp>
 #include <cmath>
 
 using namespace nima;
 
-class NimaView : public SampleView {
+class NimaView : public Sample {
 public:
     NimaView()
         : fActor(nullptr)
@@ -22,10 +21,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Nima");
+    virtual bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Nima");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -65,10 +63,9 @@
     std::unique_ptr<SampleActor> fActor;
     ActorAnimationInstance*      fAnimation;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new NimaView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new NimaView(); )
diff --git a/samplecode/SamplePatch.cpp b/samplecode/SamplePatch.cpp
index 80f051d..7b62d9d 100644
--- a/samplecode/SamplePatch.cpp
+++ b/samplecode/SamplePatch.cpp
@@ -6,9 +6,8 @@
  */
 
 #include "DecodeFile.h"
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
-#include "SkView.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkGraphics.h"
@@ -203,7 +202,7 @@
 const SkScalar DX = 20;
 const SkScalar DY = 0;
 
-class PatchView : public SampleView {
+class PatchView : public Sample {
     SkScalar    fAngle;
     sk_sp<SkShader> fShader0;
     sk_sp<SkShader> fShader1;
@@ -238,10 +237,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt)  override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Patch");
+    bool onQuery(Sample::Event* evt)  override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Patch");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -302,14 +300,14 @@
     class PtClick : public Click {
     public:
         int fIndex;
-        PtClick(SkView* view, int index) : Click(view), fIndex(index) {}
+        PtClick(Sample* view, int index) : Click(view), fIndex(index) {}
     };
 
     static bool hittest(const SkPoint& pt, SkScalar x, SkScalar y) {
         return SkPoint::Length(pt.fX - x, pt.fY - y) < SkIntToScalar(5);
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
         x -= DX;
         y -= DY;
         for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
@@ -326,10 +324,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new PatchView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new PatchView(); )
diff --git a/samplecode/SamplePath.cpp b/samplecode/SamplePath.cpp
index 52d5d64..1a0d9c6 100644
--- a/samplecode/SamplePath.cpp
+++ b/samplecode/SamplePath.cpp
@@ -5,9 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
-#include "SkView.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
@@ -71,7 +70,7 @@
     canvas.drawPath(path, paint);
 }
 
-class PathView : public SampleView {
+class PathView : public Sample {
     SkScalar fPrevSecs;
 public:
     SkScalar fDStroke, fStroke, fMinStroke, fMaxStroke;
@@ -130,10 +129,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Paths");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Paths");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -196,13 +194,13 @@
         return true;
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
         fShowHairline = !fShowHairline;
         return this->INHERITED::onFindClickHandler(x, y, modi);
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 DEF_SAMPLE( return new PathView; )
 
@@ -211,7 +209,7 @@
 #include "SkCornerPathEffect.h"
 #include "SkRandom.h"
 
-class ArcToView : public SampleView {
+class ArcToView : public Sample {
     bool fDoFrame, fDoCorner, fDoConic;
     SkPaint fPtsPaint, fSkeletonPaint, fCornerPaint;
 public:
@@ -251,14 +249,13 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "ArcTo");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "ArcTo");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case '1': this->toggle(fDoFrame); return true;
                 case '2': this->toggle(fDoCorner); return true;
@@ -302,7 +299,7 @@
         return false;
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned 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) {
@@ -316,13 +313,13 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 DEF_SAMPLE( return new ArcToView; )
 
 /////////////
 
-class FatStroke : public SampleView {
+class FatStroke : public Sample {
     bool fClosed, fShowStroke, fShowHidden, fShowSkeleton;
     int  fJoinType, fCapType;
     float fWidth = 30;
@@ -369,14 +366,13 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "FatStroke");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "FatStroke");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case '1': this->toggle(fShowSkeleton); return true;
                 case '2': this->toggle(fShowStroke); return true;
@@ -436,7 +432,7 @@
         return false;
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned 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) {
@@ -450,7 +446,7 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 DEF_SAMPLE( return new FatStroke; )
 
@@ -475,7 +471,7 @@
     return n;
 }
 
-class CubicCurve : public SampleView {
+class CubicCurve : public Sample {
 public:
     enum {
         N = 4
@@ -491,9 +487,9 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "CubicCurve");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "CubicCurve");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -559,7 +555,7 @@
         return false;
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned 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) {
@@ -573,7 +569,7 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 DEF_SAMPLE( return new CubicCurve; )
 
@@ -596,7 +592,7 @@
     return SkFindUnitQuadRoots(3 * A.cross(Z), 2 * B.cross(Z), C.cross(Z), ts);
 }
 
-class CubicCurve2 : public SampleView {
+class CubicCurve2 : public Sample {
 public:
     enum {
         N = 7
@@ -620,13 +616,13 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "CubicCurve2");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "CubicCurve2");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case 's': fShowSub = !fShowSub; break;
                 case 'f': fShowFlatness = !fShowFlatness; break;
@@ -753,7 +749,7 @@
         return false;
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned 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) {
@@ -767,7 +763,7 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 DEF_SAMPLE( return new CubicCurve2; )
 
diff --git a/samplecode/SamplePathClip.cpp b/samplecode/SamplePathClip.cpp
index ab9fb4b..1d63a31 100644
--- a/samplecode/SamplePathClip.cpp
+++ b/samplecode/SamplePathClip.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkColorFilter.h"
 #include "SkColorPriv.h"
@@ -18,11 +18,10 @@
 #include "SkTo.h"
 #include "SkTypeface.h"
 #include "SkUtils.h"
-#include "SkView.h"
 
 #include <utility>
 
-class PathClipView : public SampleView {
+class PathClipView : public Sample {
 public:
     SkRect fOval;
     SkPoint fCenter;
@@ -30,9 +29,9 @@
     PathClipView() : fOval(SkRect::MakeWH(200, 50)), fCenter(SkPoint::Make(250, 250)) {}
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "PathClip");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "PathClip");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -59,7 +58,7 @@
         canvas->drawOval(oval, p);
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
         return new Click(this);
     }
 
@@ -69,7 +68,7 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 DEF_SAMPLE( return new PathClipView; )
 
@@ -152,7 +151,7 @@
 
 // Demonstrate edge-clipping that is used in the scan converter
 //
-class EdgeClipView : public SampleView {
+class EdgeClipView : public Sample {
     enum {
         N = 3
     };
@@ -172,9 +171,9 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "EdgeClip");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "EdgeClip");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -240,21 +239,21 @@
 
     class MyClick : public Click {
     public:
-        MyClick(SkView* view) : Click(view) {}
+        MyClick(Sample* view) : Click(view) {}
         virtual void handleMove() = 0;
     };
 
     class VertClick : public MyClick {
         SkPoint* fPt;
     public:
-        VertClick(SkView* view, SkPoint* pt) : MyClick(view), fPt(pt) {}
+        VertClick(Sample* view, SkPoint* pt) : MyClick(view), fPt(pt) {}
         void handleMove() override { *fPt = snap(fCurr); }
     };
 
     class DragRectClick : public MyClick {
         SkRect* fRect;
     public:
-        DragRectClick(SkView* view, SkRect* rect) : MyClick(view), fRect(rect) {}
+        DragRectClick(Sample* view, SkRect* rect) : MyClick(view), fRect(rect) {}
         void handleMove() override { fRect->offset(fCurr.x() - fPrev.x(), fCurr.y() - fPrev.y()); }
     };
 
@@ -263,7 +262,7 @@
         SkPoint* fPoly;
         int fCount;
     public:
-        DragPolyClick(SkView* view, SkPoint poly[], int count)
+        DragPolyClick(Sample* view, SkPoint poly[], int count)
             : MyClick(view), fPoly(poly), fCount(count)
         {
             SkASSERT((size_t)count <= SK_ARRAY_COUNT(fSrc));
@@ -280,7 +279,7 @@
 
     class DoNothingClick : public MyClick {
     public:
-        DoNothingClick(SkView* view) : MyClick(view) {}
+        DoNothingClick(Sample* view) : MyClick(view) {}
         void handleMove() override {}
     };
 
@@ -291,7 +290,7 @@
         return dx*dx + dy*dy <= rad*rad;
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
         for (int i = 0; i < N; ++i) {
             if (hit_test(fPoly[i], x, y)) {
                 return new VertClick(this, &fPoly[i]);
@@ -316,6 +315,7 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
+
 DEF_SAMPLE( return new EdgeClipView; )
diff --git a/samplecode/SamplePathEffects.cpp b/samplecode/SamplePathEffects.cpp
index 5d80e5a..42d190d 100644
--- a/samplecode/SamplePathEffects.cpp
+++ b/samplecode/SamplePathEffects.cpp
@@ -5,9 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
-#include "SkView.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkPath.h"
@@ -68,7 +67,7 @@
 
 #include "SkColorFilter.h"
 
-class PathEffectView : public SampleView {
+class PathEffectView : public Sample {
     SkPath  fPath;
     SkPoint fClickPt;
     SkScalar fPhase;
@@ -109,9 +108,9 @@
         this->setBGColor(0xFFDDDDDD);
     }
 
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "PathEffects");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "PathEffects");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -145,10 +144,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new PathEffectView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new PathEffectView(); )
diff --git a/samplecode/SamplePathFill.cpp b/samplecode/SamplePathFill.cpp
index fbc4c2e..990daaa 100644
--- a/samplecode/SamplePathFill.cpp
+++ b/samplecode/SamplePathFill.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGraphics.h"
 #include "SkRandom.h"
@@ -103,7 +102,7 @@
 
 #define N   SK_ARRAY_COUNT(gProcs)
 
-class PathFillView : public SampleView {
+class PathFillView : public Sample {
     SkPath  fPath[N];
     SkScalar fDY[N];
 
@@ -116,10 +115,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "PathFill");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "PathFill");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -136,10 +134,10 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new PathFillView; }
-static SkViewRegister reg(MyFactory);
+static Sample* MyFactory() { return new PathFillView; }
+static SampleRegister reg(MyFactory);
diff --git a/samplecode/SamplePathFuzz.cpp b/samplecode/SamplePathFuzz.cpp
index 13c72ca..35951d7 100644
--- a/samplecode/SamplePathFuzz.cpp
+++ b/samplecode/SamplePathFuzz.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
 #include "SkPath.h"
@@ -646,17 +645,16 @@
     });
 }
 
-class PathFuzzView : public SampleView {
+class PathFuzzView : public Sample {
 public:
     PathFuzzView()
         : fOneDraw(false)
     {
     }
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "PathFuzzer");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "PathFuzzer");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -693,8 +691,7 @@
     SkBitmap offscreen;
     FuzzPath fuzzPath;
     bool fOneDraw;
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
-static SkView* MyFactory() { return new PathFuzzView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new PathFuzzView(); )
diff --git a/samplecode/SamplePathOverstroke.cpp b/samplecode/SamplePathOverstroke.cpp
index b6202a7..0ed6e4b 100644
--- a/samplecode/SamplePathOverstroke.cpp
+++ b/samplecode/SamplePathOverstroke.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkPath.h"
 
@@ -16,7 +15,7 @@
 
 #define LIN_SEGMENTS 10
 
-class OverstrokeView : public SampleView {
+class OverstrokeView : public Sample {
    public:
     SkScalar fStroke;
     int fPathType;  // super lazy enum
@@ -33,13 +32,13 @@
     }
 
    protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "PathOverstroke");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "PathOverstroke");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case ',':
                     fStroke += 1.0;
@@ -197,10 +196,9 @@
     }
 
    private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new OverstrokeView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new OverstrokeView(); )
diff --git a/samplecode/SamplePathText.cpp b/samplecode/SamplePathText.cpp
index 0f58c53..cf09708 100644
--- a/samplecode/SamplePathText.cpp
+++ b/samplecode/SamplePathText.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
 #include "SkCanvas.h"
 #include "SkGlyphCache.h"
@@ -18,7 +18,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Static text from paths.
-class PathText : public SampleView {
+class PathText : public Sample {
 public:
     constexpr static int kNumPaths = 1500;
     virtual const char* getName() const { return "PathText"; }
@@ -49,13 +49,13 @@
     void onOnceBeforeDraw() final { this->INHERITED::onOnceBeforeDraw(); this->reset(); }
     void onSizeChange() final { this->INHERITED::onSizeChange(); this->reset(); }
 
-    bool onQuery(SkEvent* evt) final {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, this->getName());
+    bool onQuery(Sample::Event* evt) final {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, this->getName());
             return true;
         }
         SkUnichar unichar;
-        if (SampleCode::CharQ(*evt, &unichar)) {
+        if (Sample::CharQ(*evt, &unichar)) {
             if (unichar == 'X') {
                 fDoClip = !fDoClip;
                 return true;
@@ -106,7 +106,7 @@
     SkPath     fClipPath = sk_tool_utils::make_star(SkRect{0,0,1,1}, 11, 3);
     bool       fDoClip = false;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 void PathText::Glyph::init(SkRandom& rand, const SkPath& path) {
diff --git a/samplecode/SamplePdfFileViewer.cpp b/samplecode/SamplePdfFileViewer.cpp
index 1842abe..df1b9d2 100644
--- a/samplecode/SamplePdfFileViewer.cpp
+++ b/samplecode/SamplePdfFileViewer.cpp
@@ -9,8 +9,7 @@
 
 #ifdef SAMPLE_PDF_FILE_VIEWER
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkGraphics.h"
@@ -27,7 +26,7 @@
 #include "SkTypeface.h"
 #include "SkPdfRenderer.h"
 
-class PdfFileViewer : public SampleView {
+class PdfFileViewer : public Sample {
 private:
     SkString    fFilename;
     SkPicture*  fPicture;  // TODO(edisonn): multiple pages, one page / picture, make it an array
@@ -56,13 +55,12 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
             SkString name("P:");
             const char* basename = strrchr(fFilename.c_str(), SkPATH_SEPARATOR);
             name.append(basename ? basename+1: fFilename.c_str());
-            SampleCode::TitleR(evt, name.c_str());
+            Sample::TitleR(evt, name.c_str());
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -85,19 +83,19 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
-SampleView* CreateSamplePdfFileViewer(const char filename[]);
-SampleView* CreateSamplePdfFileViewer(const char filename[]) {
+Sample* CreateSamplePdfFileViewer(const char filename[]);
+Sample* CreateSamplePdfFileViewer(const char filename[]) {
     return new PdfFileViewer(filename);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
 #if 0
-static SkView* MyFactory() { return new PdfFileViewer; }
-static SkViewRegister reg(MyFactory);
+static Sample* MyFactory() { return new PdfFileViewer; }
+static SampleRegister reg(MyFactory);
 #endif
 
 #endif  // SAMPLE_PDF_FILE_VIEWER
diff --git a/samplecode/SamplePoints.cpp b/samplecode/SamplePoints.cpp
index 13b9897..a55203c 100644
--- a/samplecode/SamplePoints.cpp
+++ b/samplecode/SamplePoints.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkGraphics.h"
@@ -21,15 +20,14 @@
 #include "SkTypeface.h"
 #include "SkStream.h"
 
-class PointsView : public SampleView {
+class PointsView : public Sample {
 public:
     PointsView() {}
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Points");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Points");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -69,10 +67,9 @@
 
 private:
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new PointsView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new PointsView(); )
diff --git a/samplecode/SamplePolyToPoly.cpp b/samplecode/SamplePolyToPoly.cpp
index dd63a78..7108614 100644
--- a/samplecode/SamplePolyToPoly.cpp
+++ b/samplecode/SamplePolyToPoly.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGraphics.h"
 #include "SkPath.h"
@@ -13,7 +12,7 @@
 #include "SkString.h"
 #include "SkTime.h"
 
-class PolyToPolyView : public SampleView {
+class PolyToPolyView : public Sample {
 public:
     PolyToPolyView() {
         // tests
@@ -67,10 +66,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt)  {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "PolyToPolyView");
+    virtual bool onQuery(Sample::Event* evt)  {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "PolyToPolyView");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -153,10 +151,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new PolyToPolyView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new PolyToPolyView(); )
diff --git a/samplecode/SampleQuadStroker.cpp b/samplecode/SampleQuadStroker.cpp
index 6d17026..e7823a2 100644
--- a/samplecode/SampleQuadStroker.cpp
+++ b/samplecode/SampleQuadStroker.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlendMode.h"
 #include "SkCanvas.h"
 #include "SkColor.h"
@@ -28,7 +28,6 @@
 #include "SkTArray.h"
 #include "SkTemplates.h"
 #include "SkTypes.h"
-#include "SkView.h"
 #include "sk_tool_utils.h"
 
 #include <cfloat>
@@ -111,7 +110,7 @@
     bool fFill;
 };
 
-class QuadStrokerView : public SampleView {
+class QuadStrokerView : public Sample {
     enum {
         SKELETON_COLOR = 0xFF0000FF,
         WIREFRAME_COLOR = 0x80FF0000
@@ -208,13 +207,13 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "QuadStroker");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "QuadStroker");
             return true;
         }
         SkUnichar uni;
-        if (fTextButton.fEnabled && SampleCode::CharQ(*evt, &uni)) {
+        if (fTextButton.fEnabled && Sample::CharQ(*evt, &uni)) {
             switch (uni) {
                 case ' ':
                     fText = "";
@@ -718,10 +717,10 @@
     class MyClick : public Click {
     public:
         int fIndex;
-        MyClick(SkView* target, int index) : Click(target), fIndex(index) {}
+        MyClick(Sample* target, int index) : Click(target), fIndex(index) {}
     };
 
-    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
+    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
                                               unsigned modi) override {
         for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); ++i) {
             if (hittest(fPts[i], x, y)) {
@@ -807,10 +806,9 @@
     }
 
 private:
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkView* F2() { return new QuadStrokerView; }
-static SkViewRegister gR2(F2);
+DEF_SAMPLE( return new QuadStrokerView(); )
diff --git a/samplecode/SampleRectanizer.cpp b/samplecode/SampleRectanizer.cpp
index d402416..e6a8bc7 100644
--- a/samplecode/SampleRectanizer.cpp
+++ b/samplecode/SampleRectanizer.cpp
@@ -5,9 +5,10 @@
  * found in the LICENSE file.
  */
 
-#include "gm.h"
-#include "SampleCode.h"
+#include "Sample.h"
+#include "SkCanvas.h"
 #include "SkRandom.h"
+#include "SkPaint.h"
 #include "SkUtils.h"
 #if SK_SUPPORT_GPU
 #include "GrRectanizer_pow2.h"
@@ -22,7 +23,7 @@
 //          Rand -> random rects from 2-256
 //          Pow2Rand -> random power of 2 sized rects from 2-256
 //          SmallPow2 -> 128x128 rects
-class RectanizerView : public SampleView {
+class RectanizerView : public Sample {
 public:
     RectanizerView()
         : fCurRandRect(0)
@@ -52,13 +53,13 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Rectanizer");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Rectanizer");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             char utf8[SkUTF::kMaxBytesInUTF8Sequence];
             size_t size = SkUTF::ToUTF8(uni, utf8);
             // Only consider events for single char keys
@@ -183,11 +184,11 @@
         fCurRandRect = 0;
     }
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
-static SkView* MyFactory() { return new RectanizerView; }
-static SkViewRegister reg(MyFactory);
+
+DEF_SAMPLE( return new RectanizerView(); )
 
 #endif
diff --git a/samplecode/SampleRegion.cpp b/samplecode/SampleRegion.cpp
index 82883c6..7f691c6 100644
--- a/samplecode/SampleRegion.cpp
+++ b/samplecode/SampleRegion.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
@@ -148,7 +147,7 @@
     }
 }
 
-class RegionView : public SampleView {
+class RegionView : public Sample {
 public:
     RegionView() {
         fBase.set(100, 100, 150, 150);
@@ -172,10 +171,9 @@
 
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Regions");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Regions");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -328,7 +326,7 @@
         }
     }
 
-    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
+    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
                                               unsigned modi) override {
         return fRect.contains(SkScalarRoundToInt(x),
                               SkScalarRoundToInt(y)) ? new Click(this) : nullptr;
@@ -343,10 +341,9 @@
 private:
     SkIRect    fBase, fRect;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new RegionView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new RegionView(); )
diff --git a/samplecode/SampleRepeatTile.cpp b/samplecode/SampleRepeatTile.cpp
index f648031..7eff1c7 100644
--- a/samplecode/SampleRepeatTile.cpp
+++ b/samplecode/SampleRepeatTile.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkShader.h"
@@ -39,17 +38,16 @@
     paint->setShader(SkShader::MakeBitmapShader(bm, tm, tm));
 }
 
-class RepeatTileView : public SampleView {
+class RepeatTileView : public Sample {
 public:
     RepeatTileView() {
         this->setBGColor(SK_ColorGRAY);
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "RepeatTile");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "RepeatTile");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -65,10 +63,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new RepeatTileView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new RepeatTileView(); )
diff --git a/samplecode/SampleSVGFile.cpp b/samplecode/SampleSVGFile.cpp
index e03d9ff..ba043ff 100644
--- a/samplecode/SampleSVGFile.cpp
+++ b/samplecode/SampleSVGFile.cpp
@@ -9,18 +9,17 @@
 
 #ifdef SK_XML
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkDOM.h"
 #include "SkOSFile.h"
 #include "SkOSPath.h"
 #include "SkStream.h"
 #include "SkSVGDOM.h"
-#include "SkView.h"
 
 namespace {
 
-class SVGFileView : public SampleView {
+class SVGFileView : public Sample {
 public:
     SVGFileView(const SkString& path)
         : fPath(path), fLabel(SkStringPrintf("[%s]", SkOSPath::Basename(path.c_str()).c_str())) {}
@@ -60,9 +59,9 @@
         this->INHERITED::onSizeChange();
     }
 
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, fLabel.c_str());
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, fLabel.c_str());
             return true;
         }
 
@@ -73,13 +72,13 @@
     SkString        fPath;
     SkString        fLabel;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 } // anonymous namespace
 
-SampleView* CreateSampleSVGFileView(const SkString& filename);
-SampleView* CreateSampleSVGFileView(const SkString& filename) {
+Sample* CreateSampleSVGFileView(const SkString& filename);
+Sample* CreateSampleSVGFileView(const SkString& filename) {
     return new SVGFileView(filename);
 }
 #endif  // SK_XML
diff --git a/samplecode/SampleShaderText.cpp b/samplecode/SampleShaderText.cpp
index b6e3538..23eac1c 100644
--- a/samplecode/SampleShaderText.cpp
+++ b/samplecode/SampleShaderText.cpp
@@ -5,12 +5,11 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkPath.h"
-#include "SkView.h"
 
 static void makebm(SkBitmap* bm, int w, int h) {
     bm->allocN32Pixels(w, h);
@@ -94,17 +93,16 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-class ShaderTextView : public SampleView {
+class ShaderTextView : public Sample {
 public:
     ShaderTextView() {
         this->setBGColor(0xFFDDDDDD);
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Shader Text");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Shader Text");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -190,10 +188,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ShaderTextView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ShaderTextView(); )
diff --git a/samplecode/SampleShaders.cpp b/samplecode/SampleShaders.cpp
index 2f545a3..51c459f 100644
--- a/samplecode/SampleShaders.cpp
+++ b/samplecode/SampleShaders.cpp
@@ -6,8 +6,7 @@
  */
 
 #include "DecodeFile.h"
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
 #include "SkGraphics.h"
@@ -36,7 +35,7 @@
     return SkShader::MakeComposeShader(std::move(shaderB), std::move(shaderA), SkBlendMode::kDstIn);
 }
 
-class ShaderView : public SampleView {
+class ShaderView : public Sample {
 public:
     sk_sp<SkShader> fShader;
     SkBitmap        fBitmap;
@@ -64,10 +63,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Shaders");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Shaders");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -101,10 +99,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ShaderView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ShaderView(); )
diff --git a/samplecode/SampleShadowColor.cpp b/samplecode/SampleShadowColor.cpp
index 337bb28..f4b31ed 100644
--- a/samplecode/SampleShadowColor.cpp
+++ b/samplecode/SampleShadowColor.cpp
@@ -5,7 +5,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "Resources.h"
 #include "SkCanvas.h"
 #include "SkImage.h"
@@ -16,7 +16,7 @@
 ////////////////////////////////////////////////////////////////////////////
 // Sample to demonstrate tonal color shadows
 
-class ShadowColorView : public SampleView {
+class ShadowColorView : public Sample {
     SkPath    fRectPath;
     int       fZIndex;
 
@@ -42,15 +42,14 @@
         fRectPath.addRect(SkRect::MakeXYWH(-50, -50, 100, 100));
     }
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "ShadowColor");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "ShadowColor");
             return true;
         }
 
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             bool handled = false;
             switch (uni) {
                 case 'W':
@@ -225,10 +224,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ShadowColorView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ShadowColorView(); )
diff --git a/samplecode/SampleShadowReference.cpp b/samplecode/SampleShadowReference.cpp
index 6cd6379..5e60b74 100644
--- a/samplecode/SampleShadowReference.cpp
+++ b/samplecode/SampleShadowReference.cpp
@@ -5,7 +5,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "Resources.h"
 #include "SkCanvas.h"
 #include "SkImage.h"
@@ -16,7 +16,7 @@
 ////////////////////////////////////////////////////////////////////////////
 // Sample to compare the Material Design shadow reference to our results
 
-class ShadowRefView : public SampleView {
+class ShadowRefView : public Sample {
     SkPath         fRRectPath;
     sk_sp<SkImage> fReferenceImage;
 
@@ -38,15 +38,14 @@
         fReferenceImage = GetResourceAsImage("images/shadowreference.png");
     }
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "ShadowReference");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "ShadowReference");
             return true;
         }
 
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             bool handled = false;
             switch (uni) {
                 case 'W':
@@ -198,10 +197,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ShadowRefView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ShadowRefView(); )
diff --git a/samplecode/SampleShadowUtils.cpp b/samplecode/SampleShadowUtils.cpp
index 4929877..2dd086e 100644
--- a/samplecode/SampleShadowUtils.cpp
+++ b/samplecode/SampleShadowUtils.cpp
@@ -5,7 +5,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
 #include "SkBlurMask.h"
 #include "SkBlurMaskFilter.h"
@@ -17,12 +17,11 @@
 #include "SkPoint3.h"
 #include "SkShadowUtils.h"
 #include "SkUtils.h"
-#include "SkView.h"
 #include "sk_tool_utils.h"
 
 ////////////////////////////////////////////////////////////////////////////
 
-class ShadowUtilsView : public SampleView {
+class ShadowUtilsView : public Sample {
     SkTArray<SkPath> fConvexPaths;
     SkTArray<SkPath> fConcavePaths;
     SkScalar         fZDelta;
@@ -74,15 +73,14 @@
         fConcavePaths.back().cubicTo(0, -25, 40, -50, 50, 0);
     }
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "ShadowUtils");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "ShadowUtils");
             return true;
         }
 
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             bool handled = false;
             switch (uni) {
                 case 'W':
@@ -257,10 +255,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ShadowUtilsView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new ShadowUtilsView(); )
diff --git a/samplecode/SampleShip.cpp b/samplecode/SampleShip.cpp
index de650af..a4871fa 100644
--- a/samplecode/SampleShip.cpp
+++ b/samplecode/SampleShip.cpp
@@ -5,10 +5,9 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "Resources.h"
 #include "SkAnimTimer.h"
-#include "SkView.h"
 #include "SkCanvas.h"
 #include "SkRSXform.h"
 #include "SkSurface.h"
@@ -45,7 +44,7 @@
 }
 
 
-class DrawShipView : public SampleView {
+class DrawShipView : public Sample {
 public:
     DrawShipView(const char name[], DrawAtlasProc proc) : fName(name), fProc(proc) {
         fAtlas = GetResourceAsImage("images/ship.png");
@@ -88,10 +87,9 @@
     ~DrawShipView() override {}
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, fName);
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, fName);
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -174,7 +172,7 @@
     int         fCurrentTime;
 
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/samplecode/SampleSlides.cpp b/samplecode/SampleSlides.cpp
index 998896c..e4f0b23 100644
--- a/samplecode/SampleSlides.cpp
+++ b/samplecode/SampleSlides.cpp
@@ -4,7 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMask.h"
 #include "SkBlurMaskFilter.h"
 #include "SkCanvas.h"
@@ -13,7 +13,6 @@
 #include "SkGradientShader.h"
 #include "SkPaint.h"
 #include "SkVertices.h"
-#include "SkView.h"
 
 #include "sk_tool_utils.h"
 
@@ -470,7 +469,7 @@
     mesh_slide,
 };
 
-class SlideView : public SampleView {
+class SlideView : public Sample {
     int fIndex;
     bool fOnce;
 public:
@@ -504,10 +503,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Slides");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Slides");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -518,17 +516,16 @@
         gProc[fIndex](canvas);
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
         this->init();
         fIndex = (fIndex + 1) % SK_ARRAY_COUNT(gProc);
         return nullptr;
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new SlideView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new SlideView(); )
diff --git a/samplecode/SampleStringArt.cpp b/samplecode/SampleStringArt.cpp
index e0e0691..70a8dd1 100644
--- a/samplecode/SampleStringArt.cpp
+++ b/samplecode/SampleStringArt.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkPath.h"
 
@@ -15,15 +15,14 @@
 // The particular shape rendered can be controlled by clicking horizontally, thereby
 // generating an angle from 0 to 1.
 
-class StringArtView : public SampleView {
+class StringArtView : public Sample {
 public:
     StringArtView() : fAngle(0.305f) {}
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "StringArt");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "StringArt");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -57,17 +56,16 @@
         canvas->drawPath(path, paint);
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
         fAngle = x/width();
         return nullptr;
     }
 private:
 
     SkScalar fAngle;
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new StringArtView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new StringArtView(); )
diff --git a/samplecode/SampleStrokePath.cpp b/samplecode/SampleStrokePath.cpp
index d51f24f..adf5a44 100644
--- a/samplecode/SampleStrokePath.cpp
+++ b/samplecode/SampleStrokePath.cpp
@@ -4,14 +4,13 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMask.h"
 #include "SkCanvas.h"
 #include "SkMaskFilter.h"
 #include "SkParsePath.h"
 #include "SkPath.h"
 #include "SkRandom.h"
-#include "SkView.h"
 
 
 static void test_huge_stroke(SkCanvas* canvas) {
@@ -94,7 +93,7 @@
     { SkPaint::kStrokeAndFill_Style,    SkPaint::kMiter_Join,   10 },
 };
 
-class StrokePathView : public SampleView {
+class StrokePathView : public Sample {
     SkScalar    fWidth;
     SkPath      fPath;
 protected:
@@ -121,10 +120,9 @@
         this->setBGColor(0xFFDDDDDD);
     }
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "StrokePath");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "StrokePath");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -206,10 +204,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new StrokePathView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new StrokePathView(); )
diff --git a/samplecode/SampleStrokeRect.cpp b/samplecode/SampleStrokeRect.cpp
index 805d510..d80afe7 100644
--- a/samplecode/SampleStrokeRect.cpp
+++ b/samplecode/SampleStrokeRect.cpp
@@ -4,20 +4,18 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
 
-class StrokeRectSample : public SampleView {
+class StrokeRectSample : public Sample {
 public:
     StrokeRectSample() {}
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Stroke Rects");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Stroke Rects");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -64,10 +62,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new StrokeRectSample; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new StrokeRectSample(); )
diff --git a/samplecode/SampleSubpixelTranslate.cpp b/samplecode/SampleSubpixelTranslate.cpp
index 7ce1885..d394127 100644
--- a/samplecode/SampleSubpixelTranslate.cpp
+++ b/samplecode/SampleSubpixelTranslate.cpp
@@ -6,10 +6,8 @@
  */
 
 #include "DecodeFile.h"
-#include "gm.h"
-
 #include "Resources.h"
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMaskFilter.h"
 #include "SkCanvas.h"
 #include "SkColorPriv.h"
@@ -19,7 +17,7 @@
 // Intended to exercise pixel snapping observed with scaled images (and
 // with non-scaled images, but for a different reason):  Bug 1145
 
-class SubpixelTranslateView : public SampleView {
+class SubpixelTranslateView : public Sample {
 public:
     SubpixelTranslateView(const char imageFilename[],
                           float horizontalVelocity,
@@ -42,10 +40,9 @@
 
     SkPoint fCurPos;
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "SubpixelTranslate");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "SubpixelTranslate");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -103,10 +100,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new SubpixelTranslateView("images/mandrill_256.png", .05f, .05f); }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new SubpixelTranslateView("images/mandrill_256.png", .05f, .05f); )
diff --git a/samplecode/SampleText.cpp b/samplecode/SampleText.cpp
index 1b67103..1c8ccb6 100644
--- a/samplecode/SampleText.cpp
+++ b/samplecode/SampleText.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
@@ -66,7 +65,7 @@
 #endif
 }
 
-class TextSpeedView : public SampleView {
+class TextSpeedView : public Sample {
 public:
     TextSpeedView() {
         fHints = 0;
@@ -74,10 +73,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Text");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Text");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -144,7 +142,7 @@
         }
     }
 
-    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
+    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
                                               unsigned modi) override {
         fClickX = x;
         return this->INHERITED::onFindClickHandler(x, y, modi);
@@ -158,10 +156,9 @@
     int fHints;
     SkScalar fClickX;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new TextSpeedView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new TextSpeedView(); )
diff --git a/samplecode/SampleTextAlpha.cpp b/samplecode/SampleTextAlpha.cpp
index c6ef3d7..ff651de 100644
--- a/samplecode/SampleTextAlpha.cpp
+++ b/samplecode/SampleTextAlpha.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMask.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
@@ -20,22 +20,20 @@
 #include "SkColorFilter.h"
 #include "SkTime.h"
 #include "SkTypeface.h"
-#include "SkView.h"
 
 #include "SkOSFile.h"
 #include "SkStream.h"
 
-class TextAlphaView : public SampleView {
+class TextAlphaView : public Sample {
 public:
     TextAlphaView() {
         fByte = 0xFF;
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "TextAlpha");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "TextAlpha");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -65,7 +63,7 @@
         }
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
         return new Click(this);
     }
 
@@ -83,10 +81,9 @@
 private:
     int fByte;
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new TextAlphaView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new TextAlphaView(); )
diff --git a/samplecode/SampleTextBox.cpp b/samplecode/SampleTextBox.cpp
index 3c1e9eb..80eee8e 100644
--- a/samplecode/SampleTextBox.cpp
+++ b/samplecode/SampleTextBox.cpp
@@ -4,7 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 
 #include "SkBlurMaskFilter.h"
 #include "SkCanvas.h"
@@ -24,7 +24,6 @@
 #include "SkTime.h"
 #include "SkTypeface.h"
 #include "SkUtils.h"
-#include "SkView.h"
 
 extern void skia_set_text_gamma(float blackGamma, float whiteGamma);
 
@@ -40,7 +39,7 @@
     "a decent respect to the opinions of mankind requires that they should "
     "declare the causes which impel them to the separation.";
 
-class TextBoxView : public SampleView {
+class TextBoxView : public Sample {
 public:
     TextBoxView() {
 #if defined(SK_BUILD_FOR_WIN) && defined(SK_FONTHOST_WIN_GDI)
@@ -58,10 +57,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "TextBox");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "TextBox");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -105,10 +103,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new TextBoxView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new TextBoxView(); )
diff --git a/samplecode/ClockFaceView.cpp b/samplecode/SampleTextEffects.cpp
similarity index 81%
rename from samplecode/ClockFaceView.cpp
rename to samplecode/SampleTextEffects.cpp
index 0b1d293..7f3fcb7 100644
--- a/samplecode/ClockFaceView.cpp
+++ b/samplecode/SampleTextEffects.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkCanvas.h"
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
@@ -103,67 +102,63 @@
     return sk_make_sp<Dot2DPathEffect>(rad, lattice, pts);
 }
 
-class ClockFaceView : public SkView {
+class TextEffectsView : public Sample {
     sk_sp<SkTypeface> fFace;
     SkScalar fInterp;
     SkScalar fDx;
 
 public:
-    ClockFaceView() {
+    TextEffectsView() {
         fFace = SkTypeface::MakeFromFile("/Users/reed/Downloads/p052024l.pfb");
         fInterp = 0;
         fDx = SK_Scalar1/64;
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Text Effects");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Text Effects");
             return true;
         }
         return this->INHERITED::onQuery(evt);
     }
 
     void drawBG(SkCanvas* canvas) {
-//        canvas->drawColor(0xFFDDDDDD);
         canvas->drawColor(SK_ColorWHITE);
     }
 
-    static void drawdots(SkCanvas* canvas, const SkPaint& orig) {
+    void drawdots(SkCanvas* canvas, SkString s, SkScalar x, SkScalar y, const SkPaint& p) {
         SkTDArray<SkPoint> pts;
-        auto pe = makepe(0, &pts);
+        auto pe = makepe(fInterp, &pts);
 
         SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
         SkPath path, dstPath;
-        orig.getTextPath("9", 1, 0, 0, &path);
+        p.getTextPath(s.c_str(), s.size(), x, y, &path);
         pe->filterPath(&dstPath, path, &rec, nullptr);
 
-        SkPaint p;
-        p.setAntiAlias(true);
-        p.setStrokeWidth(10);
-        p.setColor(SK_ColorRED);
-        canvas->drawPoints(SkCanvas::kPoints_PointMode, pts.count(), pts.begin(), p);
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setStrokeWidth(10);
+        paint.setColor(SK_ColorRED);
+        canvas->drawPoints(SkCanvas::kPoints_PointMode, pts.count(), pts.begin(), paint);
     }
 
-    virtual void onDraw(SkCanvas* canvas) {
+    void onDrawContent(SkCanvas* canvas) override {
         this->drawBG(canvas);
 
-        SkScalar    x = SkIntToScalar(20);
-        SkScalar    y = SkIntToScalar(300);
-        SkPaint     paint;
+        SkScalar x = SkIntToScalar(20);
+        SkScalar y = SkIntToScalar(300);
 
+        SkPaint paint;
         paint.setAntiAlias(true);
         paint.setTextSize(SkIntToScalar(240));
         paint.setTypeface(SkTypeface::MakeFromName("sans-serif", SkFontStyle::Bold()));
+        paint.setTypeface(fFace);
 
         SkString str("9");
 
-        paint.setTypeface(fFace);
-
         canvas->drawString(str, x, y, paint);
-
-    //    drawdots(canvas, paint);
+        drawdots(canvas, str, x, y, paint);
 
         if (false) {
             fInterp += fDx;
@@ -178,10 +173,9 @@
     }
 
 private:
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new ClockFaceView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new TextEffectsView(); )
diff --git a/samplecode/SampleTextOnPath.cpp b/samplecode/SampleTextOnPath.cpp
index 0e43181..e222237 100644
--- a/samplecode/SampleTextOnPath.cpp
+++ b/samplecode/SampleTextOnPath.cpp
@@ -4,7 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMask.h"
 #include "SkBlurDrawLooper.h"
 #include "SkCanvas.h"
@@ -85,7 +85,7 @@
     canvas->drawTextOnPath(text, len, path, &matrix, paint);
 }
 
-class TextOnPathView : public SampleView {
+class TextOnPathView : public Sample {
 public:
     SkPath      fPath;
     SkScalar    fHOffset;
@@ -101,10 +101,9 @@
         fHOffset = SkIntToScalar(50);
     }
 
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Text On Path");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Text On Path");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -145,20 +144,16 @@
         textPathMatrix(canvas);
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
         fHints += 1;
         return this->INHERITED::onFindClickHandler(x, y, modi);
     }
 
 private:
     int fHints;
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() {
-    return new TextOnPathView;
-}
-
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new TextOnPathView(); )
diff --git a/samplecode/SampleTextureDomain.cpp b/samplecode/SampleTextureDomain.cpp
index 7b429cb..3de6cee 100644
--- a/samplecode/SampleTextureDomain.cpp
+++ b/samplecode/SampleTextureDomain.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMask.h"
 #include "SkBlurMaskFilter.h"
 #include "SkCanvas.h"
@@ -24,7 +24,7 @@
     return bm;
 }
 
-class TextureDomainView : public SampleView {
+class TextureDomainView : public Sample {
     SkBitmap    fBM;
 
 public:
@@ -33,10 +33,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Texture Domain");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Texture Domain");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -94,10 +93,9 @@
         canvas->drawBitmapRect(fBM, dstRect, &paint);
     }
 private:
-    typedef SkView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new TextureDomainView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new TextureDomainView(); )
diff --git a/samplecode/SampleTiling.cpp b/samplecode/SampleTiling.cpp
index cb8061e..76243f6 100644
--- a/samplecode/SampleTiling.cpp
+++ b/samplecode/SampleTiling.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkPaint.h"
@@ -54,7 +53,7 @@
 static const int gWidth = 32;
 static const int gHeight = 32;
 
-class TilingView : public SampleView {
+class TilingView : public Sample {
     sk_sp<SkPicture>     fTextPicture;
     sk_sp<SkDrawLooper>  fLooper;
 public:
@@ -73,10 +72,9 @@
     SkBitmap    fTexture[SK_ARRAY_COUNT(gColorTypes)];
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Tiling");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Tiling");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -162,10 +160,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new TilingView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new TilingView(); )
diff --git a/samplecode/SampleUnpremul.cpp b/samplecode/SampleUnpremul.cpp
index 4f41418..bf89a6c 100644
--- a/samplecode/SampleUnpremul.cpp
+++ b/samplecode/SampleUnpremul.cpp
@@ -5,12 +5,10 @@
  * found in the LICENSE file.
  */
 
-#include "gm.h"
-
 #include "sk_tool_utils.h"
 #include "DecodeFile.h"
 #include "Resources.h"
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkBlurMask.h"
 #include "SkBlurDrawLooper.h"
 #include "SkCanvas.h"
@@ -21,7 +19,6 @@
 #include "SkString.h"
 #include "SkTypes.h"
 #include "SkUtils.h"
-#include "SkView.h"
 
 /**
  *  Interprets c as an unpremultiplied color, and returns the
@@ -35,7 +32,7 @@
     return SkPreMultiplyARGB(a, r, g, b);
 }
 
-class UnpremulView : public SampleView {
+class UnpremulView : public Sample {
 public:
     UnpremulView(SkString res)
     : fResPath(res)
@@ -45,14 +42,13 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "unpremul");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "unpremul");
             return true;
         }
         SkUnichar uni;
-        if (SampleCode::CharQ(*evt, &uni)) {
+        if (Sample::CharQ(*evt, &uni)) {
             char utf8[SkUTF::kMaxBytesInUTF8Sequence];
             size_t size = SkUTF::ToUTF8(uni, utf8);
             // Only consider events for single char keys
@@ -170,12 +166,9 @@
         this->decodeCurrFile();
     }
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() {
-    return new UnpremulView(GetResourcePath("images"));
-}
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new UnpremulView(GetResourcePath("images")); )
diff --git a/samplecode/SampleVertices.cpp b/samplecode/SampleVertices.cpp
index 55ded03..4a511d0 100644
--- a/samplecode/SampleVertices.cpp
+++ b/samplecode/SampleVertices.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkGradientShader.h"
@@ -46,7 +45,7 @@
                     SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode);
 }
 
-class VerticesView : public SampleView {
+class VerticesView : public Sample {
     sk_sp<SkShader> fShader0;
     sk_sp<SkShader> fShader1;
 
@@ -67,10 +66,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "Vertices");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "Vertices");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -107,7 +105,7 @@
         }
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
         return new Click(this);
     }
 
@@ -210,10 +208,9 @@
 
     Rec fRecs[3];
 
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new VerticesView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new VerticesView(); )
diff --git a/samplecode/SampleWritePixels.cpp b/samplecode/SampleWritePixels.cpp
index 2aff982..ae39360 100644
--- a/samplecode/SampleWritePixels.cpp
+++ b/samplecode/SampleWritePixels.cpp
@@ -4,8 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkCornerPathEffect.h"
@@ -27,16 +26,15 @@
     canvas.drawCircle(SkIntToScalar(W)/2, SkIntToScalar(H)/2, SkIntToScalar(W)/2, paint);
 }
 
-class WritePixelsView : public SampleView {
+class WritePixelsView : public Sample {
     SkPath fPath;
 public:
     WritePixelsView() {}
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "WritePixels");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "WritePixels");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -58,10 +56,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new WritePixelsView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new WritePixelsView(); )
diff --git a/samplecode/SampleXfer.cpp b/samplecode/SampleXfer.cpp
index d459274..d0ba35e 100644
--- a/samplecode/SampleXfer.cpp
+++ b/samplecode/SampleXfer.cpp
@@ -5,10 +5,9 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
+#include "Sample.h"
 #include "SkAnimTimer.h"
 #include "SkDrawable.h"
-#include "SkView.h"
 #include "SkCanvas.h"
 #include "SkDrawable.h"
 #include "SkPath.h"
@@ -103,7 +102,7 @@
     }
 };
 
-class XferDemo : public SampleView {
+class XferDemo : public Sample {
     enum {
         N = 4
     };
@@ -137,9 +136,9 @@
     }
 
 protected:
-    bool onQuery(SkEvent* evt) override {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "XferDemo");
+    bool onQuery(Sample::Event* evt) override {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "XferDemo");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -167,7 +166,7 @@
         canvas->restore();
     }
 
-    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
+    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
         // Check mode buttons first
         for (int i = 0; i < N_Modes; ++i) {
             if (fModeButtons[i].hitTest(x, y)) {
@@ -200,7 +199,7 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/samplecode/SampleXfermodesBlur.cpp b/samplecode/SampleXfermodesBlur.cpp
index 0ef144e..e063579 100644
--- a/samplecode/SampleXfermodesBlur.cpp
+++ b/samplecode/SampleXfermodesBlur.cpp
@@ -5,8 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "SampleCode.h"
-#include "SkView.h"
+#include "Sample.h"
 #include "SkBitmap.h"
 #include "SkBlurMask.h"
 #include "SkCanvas.h"
@@ -33,7 +32,7 @@
 
 static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };
 
-class XfermodesBlurView : public SampleView {
+class XfermodesBlurView : public Sample {
     SkBitmap    fBG;
     SkBitmap    fSrcB, fDstB;
 
@@ -72,10 +71,9 @@
     }
 
 protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "XfermodesBlur");
+    virtual bool onQuery(Sample::Event* evt) {
+        if (Sample::TitleQ(*evt)) {
+            Sample::TitleR(evt, "XfermodesBlur");
             return true;
         }
         return this->INHERITED::onQuery(evt);
@@ -173,10 +171,9 @@
     }
 
 private:
-    typedef SampleView INHERITED;
+    typedef Sample INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-static SkView* MyFactory() { return new XfermodesBlurView; }
-static SkViewRegister reg(MyFactory);
+DEF_SAMPLE( return new XfermodesBlurView(); )