Import all GMs as Samples.

Review URL: http://codereview.appspot.com/5332043/



git-svn-id: http://skia.googlecode.com/svn/trunk@2564 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/aarectmodes.cpp b/gm/aarectmodes.cpp
index ffb267d..4ef1f60 100644
--- a/gm/aarectmodes.cpp
+++ b/gm/aarectmodes.cpp
@@ -107,7 +107,6 @@
         virtual SkISize onISize() { return make_isize(640, 480); }
 
         virtual void onDraw(SkCanvas* canvas) {
-            canvas->drawColor(SK_ColorWHITE);
 
             const SkRect bounds = SkRect::MakeWH(W, H);
             static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 };
diff --git a/gm/bitmapfilters.cpp b/gm/bitmapfilters.cpp
index 9521cfd..cf98dcd 100644
--- a/gm/bitmapfilters.cpp
+++ b/gm/bitmapfilters.cpp
@@ -86,6 +86,7 @@
         fBM8.copyTo(&fBM4444, SkBitmap::kARGB_4444_Config);
         fBM8.copyTo(&fBM16, SkBitmap::kRGB_565_Config);
         fBM8.copyTo(&fBM32, SkBitmap::kARGB_8888_Config);
+        this->setBGColor(0xFFDDDDDD);
     }
 
 protected:
@@ -98,7 +99,6 @@
     }
 
     virtual void onDraw(SkCanvas* canvas) {
-        canvas->drawColor(0xFFDDDDDD);
 
         SkScalar x = SkIntToScalar(10);
         SkScalar y = SkIntToScalar(10);
diff --git a/gm/bitmapscroll.cpp b/gm/bitmapscroll.cpp
index c12dd05..70d1052 100644
--- a/gm/bitmapscroll.cpp
+++ b/gm/bitmapscroll.cpp
@@ -49,6 +49,7 @@
     BitmapScrollGM() {
         // Create the original bitmap.
         make_bitmap(quarterWidth, quarterHeight, &origBitmap);
+        this->setBGColor(0xFFDDDDDD);
     }
 
 protected:
@@ -68,8 +69,7 @@
         int xSpacing = quarterWidth * 20;
         int ySpacing = quarterHeight * 16;
 
-        // Draw background and left-hand text labels.
-        canvas->drawColor(0xFFDDDDDD);
+        // Draw left-hand text labels.
         drawLabel(canvas, "scroll entire bitmap",
                   x, y, x, y + ySpacing);
         drawLabel(canvas, "scroll part of bitmap",
diff --git a/gm/blurs.cpp b/gm/blurs.cpp
index ac9432a..69504f7 100644
--- a/gm/blurs.cpp
+++ b/gm/blurs.cpp
@@ -12,7 +12,9 @@
 
 class BlursGM : public GM {
 public:
-    BlursGM() {}
+    BlursGM() {
+        this->setBGColor(0xFFDDDDDD);
+    }
 
 protected:
     virtual SkString onShortName() {
@@ -23,13 +25,7 @@
         return make_isize(700, 500);
     }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(0xFFDDDDDD);
-    }
-
     virtual void onDraw(SkCanvas* canvas) {
-        drawBG(canvas);
-
         SkBlurMaskFilter::BlurStyle NONE = SkBlurMaskFilter::BlurStyle(-999);
         static const struct {
             SkBlurMaskFilter::BlurStyle fStyle;
diff --git a/gm/complexclip.cpp b/gm/complexclip.cpp
index 0a4b6c2..204a378 100644
--- a/gm/complexclip.cpp
+++ b/gm/complexclip.cpp
@@ -16,6 +16,7 @@
 class ComplexClipGM : public GM {
 public:
 	ComplexClipGM() {
+        this->setBGColor(SkColorSetRGB(0xA0,0xDD,0xA0));
     }
 
 protected:
@@ -26,10 +27,6 @@
 
     SkISize onISize() { return make_isize(550, 1000); }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(SkColorSetRGB(0xA0,0xDD,0xA0));
-    }
-
     virtual void onDraw(SkCanvas* canvas) {
         SkPath path;
         path.moveTo(SkIntToScalar(0),   SkIntToScalar(50));
@@ -70,7 +67,6 @@
         clipB.close();
         SkColor colorB = SK_ColorRED;
 
-        drawBG(canvas);
         SkPaint paint;
         paint.setAntiAlias(true);
 
diff --git a/gm/complexclip2.cpp b/gm/complexclip2.cpp
index 44a8935..d6b653e 100644
--- a/gm/complexclip2.cpp
+++ b/gm/complexclip2.cpp
@@ -16,6 +16,8 @@
 class ComplexClip2GM : public GM {
 public:
     ComplexClip2GM() {
+        this->setBGColor(SkColorSetRGB(0xDD,0xA0,0xDD));
+        
         SkScalar xA =  0 * SK_Scalar1;
         SkScalar xB = 10 * SK_Scalar1;
         SkScalar xC = 20 * SK_Scalar1;
@@ -86,12 +88,7 @@
                           SkScalarRoundToInt(fTotalHeight));
     }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(SkColorSetRGB(0xDD,0xA0,0xDD));
-    }
-
     virtual void onDraw(SkCanvas* canvas) {
-        this->drawBG(canvas);
         SkPaint rectPaint;
         rectPaint.setStyle(SkPaint::kStroke_Style);
         rectPaint.setStrokeWidth(-1);
diff --git a/gm/emptypath.cpp b/gm/emptypath.cpp
index ee9dd0c..c52932e 100644
--- a/gm/emptypath.cpp
+++ b/gm/emptypath.cpp
@@ -23,10 +23,6 @@
         
     SkISize onISize() { return make_isize(600, 280); }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
-    }
-
     void drawEmpty(SkCanvas* canvas,
                     SkColor color,
                     const SkRect& clip,
@@ -44,7 +40,6 @@
     }
     
     virtual void onDraw(SkCanvas* canvas) {
-        this->drawBG(canvas);
         struct FillAndName {
             SkPath::FillType fFill;
             const char*      fName;
diff --git a/gm/filltypes.cpp b/gm/filltypes.cpp
index 0910f6c..73c718e 100644
--- a/gm/filltypes.cpp
+++ b/gm/filltypes.cpp
@@ -13,6 +13,7 @@
     SkPath fPath;
 public:
 	FillTypeGM() {
+        this->setBGColor(0xFFDDDDDD);
         const SkScalar radius = SkIntToScalar(45);
         fPath.addCircle(SkIntToScalar(50), SkIntToScalar(50), radius);
         fPath.addCircle(SkIntToScalar(100), SkIntToScalar(100), radius);
@@ -56,8 +57,6 @@
     }
 
     virtual void onDraw(SkCanvas* canvas) {
-        canvas->drawColor(0xFFDDDDDD);
-        
         canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
         
         SkPaint paint;
diff --git a/gm/gm.cpp b/gm/gm.cpp
new file mode 100644
index 0000000..cf4b640
--- /dev/null
+++ b/gm/gm.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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 "gm.h"
+using namespace skiagm;
+
+GM::GM() {
+    fBGColor = SK_ColorWHITE;
+}
+GM::~GM() {}
+
+void GM::draw(SkCanvas* canvas) {
+    this->drawBackground(canvas);
+    this->drawContent(canvas);
+}
+
+void GM::drawContent(SkCanvas* canvas) {
+    this->onDraw(canvas);
+}
+
+void GM::drawBackground(SkCanvas* canvas) {
+    this->onDrawBackground(canvas);
+}
+
+const char* GM::shortName() {
+    if (fShortName.size() == 0) {
+        fShortName = this->onShortName();
+    }
+    return fShortName.c_str();
+}
+
+void GM::setBGColor(SkColor color) {
+    fBGColor = color;
+}
+
+void GM::onDrawBackground(SkCanvas* canvas) {
+    canvas->drawColor(fBGColor);
+}
+
+// need to explicitly declare this, or we get some weird infinite loop llist
+template GMRegistry* SkTRegistry<GM*, void*>::gHead;
diff --git a/gm/gm.h b/gm/gm.h
index 4035034..4259c39 100644
--- a/gm/gm.h
+++ b/gm/gm.h
@@ -35,27 +35,29 @@
             kSkipPicture_Flag   = 1 << 1
         };
 
-		void draw(SkCanvas*);
+        void draw(SkCanvas*);
+        void drawBackground(SkCanvas*);
+        void drawContent(SkCanvas*);
+        
 		SkISize getISize() { return this->onISize(); }
-        const char* shortName() {
-            if (fShortName.size() == 0) {
-                fShortName = this->onShortName();
-            }
-            return fShortName.c_str();
-        }
+        const char* shortName();
 
         uint32_t getFlags() const {
             return this->onGetFlags();
         }
+        
+        void setBGColor(SkColor);
 
 	protected:
 		virtual void onDraw(SkCanvas*) = 0;
+		virtual void onDrawBackground(SkCanvas*);
 		virtual SkISize onISize() = 0;
         virtual SkString onShortName() = 0;
         virtual uint32_t onGetFlags() const { return 0; }
         
     private:
         SkString fShortName;
+        SkColor  fBGColor;
     };
 
     typedef SkTRegistry<GM*, void*> GMRegistry;
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index 35a14f4..4051fee 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -41,9 +41,6 @@
 
 using namespace skiagm;
 
-// need to explicitly declare this, or we get some weird infinite loop llist
-template GMRegistry* SkTRegistry<GM*, void*>::gHead;
-
 class Iter {
 public:
     Iter() {
@@ -707,14 +704,3 @@
     }
     return 0;
 }
-
-///////////////////////////////////////////////////////////////////////////////
-
-using namespace skiagm;
-
-GM::GM() {}
-GM::~GM() {}
-
-void GM::draw(SkCanvas* canvas) {
-    this->onDraw(canvas);
-}
diff --git a/gm/gradients.cpp b/gm/gradients.cpp
index ae715ce..aac8a96 100644
--- a/gm/gradients.cpp
+++ b/gm/gradients.cpp
@@ -80,7 +80,9 @@
 
 class GradientsGM : public GM {
 public:
-	GradientsGM() {}
+	GradientsGM() {
+        this->setBGColor(0xFFDDDDDD);
+    }
     
 protected:
     SkString onShortName() {
@@ -88,13 +90,8 @@
     }
     
     virtual SkISize onISize() { return make_isize(640, 510); }
-    
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(0xFFDDDDDD);
-    }
-    
+        
     virtual void onDraw(SkCanvas* canvas) {
-        this->drawBG(canvas);
         
         SkPoint pts[2] = {
             { 0, 0 },
diff --git a/gm/hairmodes.cpp b/gm/hairmodes.cpp
index cbbfe86..8bfa186 100644
--- a/gm/hairmodes.cpp
+++ b/gm/hairmodes.cpp
@@ -105,8 +105,6 @@
         virtual SkISize onISize() { return make_isize(640, 480); }
         
         virtual void onDraw(SkCanvas* canvas) {
-            canvas->drawColor(SK_ColorWHITE);
-
             const SkRect bounds = SkRect::MakeWH(W, H);
             static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 };
             
diff --git a/gm/lcdtext.cpp b/gm/lcdtext.cpp
index e0e895c..ab8b8e4 100644
--- a/gm/lcdtext.cpp
+++ b/gm/lcdtext.cpp
@@ -30,13 +30,8 @@
 
     SkISize onISize() { return make_isize(640, 480); }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
-    }
-
     virtual void onDraw(SkCanvas* canvas) {
-        this->drawBG(canvas);
-
+        
         y = textHeight;
         drawText(canvas, SkString("TEXT: SubpixelTrue LCDRenderTrue"),
                  true,  true);
diff --git a/gm/ninepatchstretch.cpp b/gm/ninepatchstretch.cpp
index f18e5fc..d1d4dda 100644
--- a/gm/ninepatchstretch.cpp
+++ b/gm/ninepatchstretch.cpp
@@ -66,8 +66,6 @@
     }
 
     virtual void onDraw(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
-
         SkBitmap bm;
         SkIRect center;
         make_bitmap(&bm, NULL /*SampleCode::GetGr()*/, &center);
diff --git a/gm/nocolorbleed.cpp b/gm/nocolorbleed.cpp
index d8e34bf..26b8184 100755
--- a/gm/nocolorbleed.cpp
+++ b/gm/nocolorbleed.cpp
@@ -11,7 +11,9 @@
 
 class NoColorBleedGM : public GM {
 public:
-    NoColorBleedGM() {}
+    NoColorBleedGM() {
+        this->setBGColor(0xFFDDDDDD);
+    }
 
 protected:
     virtual SkString onShortName() {
@@ -22,13 +24,7 @@
         return make_isize(200, 200);
     }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(0xFFDDDDDD);
-    }
-
     virtual void onDraw(SkCanvas* canvas) {
-        drawBG(canvas);
-
         SkBitmap sprite;
         sprite.setConfig(SkBitmap::kARGB_8888_Config, 4, 4, 4*sizeof(SkColor));
         const SkColor spriteData[16] = {
diff --git a/gm/pathfill.cpp b/gm/pathfill.cpp
index 71a45e4..9d4b3c8 100644
--- a/gm/pathfill.cpp
+++ b/gm/pathfill.cpp
@@ -125,13 +125,7 @@
         return make_isize(640, 480);
     }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
-    }
-
     virtual void onDraw(SkCanvas* canvas) {
-        this->drawBG(canvas);
-
         SkPaint paint;
         paint.setAntiAlias(true);
         
diff --git a/gm/points.cpp b/gm/points.cpp
index 8ac85b7..e4f3c2e 100644
--- a/gm/points.cpp
+++ b/gm/points.cpp
@@ -23,10 +23,6 @@
         return make_isize(640, 490);
     }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
-    }
-
     static void fill_pts(SkPoint pts[], size_t n, SkRandom* rand) {
         for (size_t i = 0; i < n; i++) {
             // Compute these independently and store in variables, rather
@@ -39,8 +35,6 @@
     }
 
     virtual void onDraw(SkCanvas* canvas) {
-        this->drawBG(canvas);
-
         canvas->translate(SK_Scalar1, SK_Scalar1);
 
         SkRandom rand;
diff --git a/gm/poly2poly.cpp b/gm/poly2poly.cpp
index 6a2df87..df824b5 100644
--- a/gm/poly2poly.cpp
+++ b/gm/poly2poly.cpp
@@ -21,10 +21,6 @@
 	virtual SkISize onISize() {
         return make_isize(835, 840);
     }
-
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
-    }
 	
     static void doDraw(SkCanvas* canvas, SkPaint* paint, const int isrc[],
                        const int idst[], int count) {
@@ -60,9 +56,7 @@
         canvas->restore();
     }
     
-    virtual void onDraw(SkCanvas* canvas) {
-        this->drawBG(canvas);
-        
+    virtual void onDraw(SkCanvas* canvas) {        
         SkPaint paint;
         paint.setAntiAlias(true);
         paint.setStrokeWidth(SkIntToScalar(4));
diff --git a/gm/shadertext.cpp b/gm/shadertext.cpp
index 2df03cc..b574ab6 100644
--- a/gm/shadertext.cpp
+++ b/gm/shadertext.cpp
@@ -109,7 +109,9 @@
 
 class ShaderTextGM : public GM {
 public:
-	ShaderTextGM() {}
+	ShaderTextGM() {
+        this->setBGColor(0xFFDDDDDD);
+    }
 
 protected:
 
@@ -119,13 +121,7 @@
 
 	SkISize onISize() { return make_isize(1450, 500); }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(0xFFDDDDDD);
-    }
-
     virtual void onDraw(SkCanvas* canvas) {
-        this->drawBG(canvas);
-
         const char text[] = "Shaded Text";
         const int textLen = SK_ARRAY_COUNT(text) - 1;
         const int pointSize = 36;
diff --git a/gm/shadows.cpp b/gm/shadows.cpp
index 454fa6a..d4dd72f 100644
--- a/gm/shadows.cpp
+++ b/gm/shadows.cpp
@@ -28,6 +28,7 @@
     SkRect fRect;
 
     ShadowsGM() {
+        this->setBGColor(0xFFDDDDDD);
         fCirclePath.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(10) );
         fRect.set(SkIntToScalar(10), SkIntToScalar(10),
                   SkIntToScalar(30), SkIntToScalar(30));
@@ -42,13 +43,7 @@
         return make_isize(200, 80);
     }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(0xFFDDDDDD);
-    }
-
     virtual void onDraw(SkCanvas* canvas) {
-        this->drawBG(canvas);
-
     SkBlurDrawLooper* shadowLoopers[5];
     shadowLoopers[0] =
         new SkBlurDrawLooper (SkIntToScalar(10), SkIntToScalar(5),
diff --git a/gm/shapes.cpp b/gm/shapes.cpp
index 09d90fd..0f46355 100644
--- a/gm/shapes.cpp
+++ b/gm/shapes.cpp
@@ -50,6 +50,8 @@
     SkMatrixRef*    fMatrixRefs[4];
 public:
 	ShapesGM() {
+        this->setBGColor(0xFFDDDDDD);
+        
         SkMatrix m;
         fGroup.appendShape(make_shape0(false))->unref();
         m.setRotate(SkIntToScalar(30), SkIntToScalar(50), SkIntToScalar(50));
@@ -83,13 +85,7 @@
         return make_isize(380, 480);
     }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(0xFFDDDDDD);
-    }
-
     virtual void onDraw(SkCanvas* canvas) {
-        this->drawBG(canvas);
-
         SkMatrix matrix;
 
         SkGroupShape* gs = new SkGroupShape;
diff --git a/gm/strokerects.cpp b/gm/strokerects.cpp
index 44c0120..92f2a18 100644
--- a/gm/strokerects.cpp
+++ b/gm/strokerects.cpp
@@ -46,8 +46,6 @@
     }
 
     virtual void onDraw(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
-
         SkPaint paint;
         paint.setStyle(SkPaint::kStroke_Style);
 
diff --git a/gm/strokes.cpp b/gm/strokes.cpp
index d8b21b2..ec265ad 100644
--- a/gm/strokes.cpp
+++ b/gm/strokes.cpp
@@ -49,9 +49,7 @@
         return make_isize(W, H*2);
     }
     
-    virtual void onDraw(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
-        
+    virtual void onDraw(SkCanvas* canvas) {        
         SkPaint paint;
         paint.setStyle(SkPaint::kStroke_Style);
         paint.setStrokeWidth(SkIntToScalar(9)/2);
diff --git a/gm/texdata.cpp b/gm/texdata.cpp
index af0a122..e3547af 100644
--- a/gm/texdata.cpp
+++ b/gm/texdata.cpp
@@ -18,7 +18,9 @@
 
 class TexDataGM : public GM {
 public:
-    TexDataGM() {}
+    TexDataGM() {
+        this->setBGColor(0xff000000);
+    }
 
 protected:
     virtual SkString onShortName() {
@@ -29,12 +31,7 @@
         return make_isize(2*S, 2*S);
     }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(0xff000000);
-    }
-
     virtual void onDraw(SkCanvas* canvas) {
-        drawBG(canvas);
         SkDevice* device = canvas->getDevice();
         GrRenderTarget* target = (GrRenderTarget*) device->accessRenderTarget();
         GrContext* ctx = GetGr();
diff --git a/gm/tilemodes.cpp b/gm/tilemodes.cpp
index 12b1b09..289caae 100644
--- a/gm/tilemodes.cpp
+++ b/gm/tilemodes.cpp
@@ -80,12 +80,7 @@
     
 	SkISize onISize() { return make_isize(880, 560); }
     
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
-    }
-    
     virtual void onDraw(SkCanvas* canvas) {
-        this->drawBG(canvas);
         
         SkRect r = { 0, 0, SkIntToScalar(gWidth*2), SkIntToScalar(gHeight*2) };
 
diff --git a/gm/tinybitmap.cpp b/gm/tinybitmap.cpp
index 2c45437..d532b5b 100644
--- a/gm/tinybitmap.cpp
+++ b/gm/tinybitmap.cpp
@@ -35,6 +35,7 @@
     SkBitmap    fBM;
 public:
     TinyBitmapGM() {
+        this->setBGColor(0xFFDDDDDD);
         fBM = make_bitmap();
     }
     
@@ -46,7 +47,6 @@
     virtual SkISize onISize() { return make_isize(100, 100); }
 
     virtual void onDraw(SkCanvas* canvas) {
-        canvas->drawColor(0xFFDDDDDD);
         SkShader* s = 
             SkShader::CreateBitmapShader(fBM, SkShader::kRepeat_TileMode,
                                          SkShader::kMirror_TileMode);
diff --git a/gm/xfermodes.cpp b/gm/xfermodes.cpp
index 51a959e..4977062 100644
--- a/gm/xfermodes.cpp
+++ b/gm/xfermodes.cpp
@@ -78,15 +78,9 @@
         return make_isize(790, 640);
     }
 
-    void drawBG(SkCanvas* canvas) {
-        canvas->drawColor(SK_ColorWHITE);
-    }
-
     virtual void onDraw(SkCanvas* canvas) {
         canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
 
-        this->drawBG(canvas);
-
         const struct {
             SkXfermode::Mode  fMode;
             const char*         fLabel;
diff --git a/gyp/SampleApp.gyp b/gyp/SampleApp.gyp
index d893f28..ba65096 100644
--- a/gyp/SampleApp.gyp
+++ b/gyp/SampleApp.gyp
@@ -10,27 +10,18 @@
       'mac_bundle' : 1,
       'include_dirs' : [
         '../src/core', # needed to get SkConcaveToTriangle, maybe this should be moved to include dir?
-        '../gm',       # SampleGM.cpp pulls gm.h
+        '../gm',       # needed to pull gm.h
         '../include/pipe', # To pull in SkGPipe.h for pipe reader/writer
         '../samplecode', # To pull SampleApp.h and SampleCode.h
       ],
+      'includes': [
+        'gmslides.gypi',
+      ],
       'sources': [
-        # gm files needed for SampleGM.cpp
-        '../gm/bitmapfilters.cpp',
-        '../gm/blurs.cpp',
-        '../gm/complexclip.cpp',
-        '../gm/filltypes.cpp',
+        '../gm/gm.cpp',
         '../gm/gm.h',
-        '../gm/gradients.cpp',
-        '../gm/nocolorbleed.cpp',
-        '../gm/points.cpp',
-        '../gm/poly2poly.cpp',
-        '../gm/shadertext.cpp',
-        '../gm/shadows.cpp',
-        '../gm/shapes.cpp',
-        '../gm/tilemodes.cpp',
-        '../gm/xfermodes.cpp',
 
+        '../samplecode/GMSampleView.h',
         '../samplecode/ClockFaceView.cpp',
         '../samplecode/OverView.cpp',
         '../samplecode/Sample2PtRadial.cpp',
@@ -71,7 +62,6 @@
         '../samplecode/SampleFontCache.cpp',
         '../samplecode/SampleFontScalerTest.cpp',
         '../samplecode/SampleFuzz.cpp',
-        '../samplecode/SampleGM.cpp',
         '../samplecode/SampleGradients.cpp',
         '../samplecode/SampleHairCurves.cpp',
         '../samplecode/SampleHairline.cpp',
diff --git a/gyp/gm.gyp b/gyp/gm.gyp
index 575cb8d..16577e9 100644
--- a/gyp/gm.gyp
+++ b/gyp/gm.gyp
@@ -8,34 +8,12 @@
     {
       'target_name': 'gm',
       'type': 'executable',
+      'includes': [
+        'gmslides.gypi',
+      ],
       'sources': [
-        '../gm/aarectmodes.cpp',
-        '../gm/bitmapfilters.cpp',
-        '../gm/bitmapscroll.cpp',
-        '../gm/blurs.cpp',
-        '../gm/complexclip.cpp',
-        '../gm/complexclip2.cpp',
-        '../gm/emptypath.cpp',
-        '../gm/filltypes.cpp',
-        '../gm/filltypespersp.cpp',
+        '../gm/gm.cpp',
         '../gm/gmmain.cpp',
-        '../gm/gradients.cpp',
-        '../gm/hairmodes.cpp',
-        '../gm/lcdtext.cpp',
-        '../gm/ninepatchstretch.cpp',
-        '../gm/nocolorbleed.cpp',
-        '../gm/pathfill.cpp',
-        '../gm/points.cpp',
-        '../gm/poly2poly.cpp',
-        '../gm/shadertext.cpp',
-        '../gm/shadows.cpp',
-        '../gm/shapes.cpp',
-        '../gm/strokerects.cpp',
-        '../gm/strokes.cpp',
-        '../gm/texdata.cpp',
-        '../gm/tilemodes.cpp',
-        '../gm/tinybitmap.cpp',
-        '../gm/xfermodes.cpp',
       ],
       'dependencies': [
         'core.gyp:core',
diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi
new file mode 100644
index 0000000..f772993
--- /dev/null
+++ b/gyp/gmslides.gypi
@@ -0,0 +1,37 @@
+# include this gypi to include all the golden master slides.
+{
+  'sources': [
+    '../gm/aarectmodes.cpp',
+    '../gm/bitmapfilters.cpp',
+    '../gm/bitmapscroll.cpp',
+    '../gm/blurs.cpp',
+    '../gm/complexclip.cpp',
+    '../gm/complexclip2.cpp',
+    '../gm/emptypath.cpp',
+    '../gm/filltypes.cpp',
+    '../gm/filltypespersp.cpp',
+    '../gm/gradients.cpp',
+    '../gm/hairmodes.cpp',
+    '../gm/lcdtext.cpp',
+    '../gm/ninepatchstretch.cpp',
+    '../gm/nocolorbleed.cpp',
+    '../gm/pathfill.cpp',
+    '../gm/points.cpp',
+    '../gm/poly2poly.cpp',
+    '../gm/shadertext.cpp',
+    '../gm/shadows.cpp',
+    '../gm/shapes.cpp',
+    '../gm/strokerects.cpp',
+    '../gm/strokes.cpp',
+    '../gm/texdata.cpp',
+    '../gm/tilemodes.cpp',
+    '../gm/tinybitmap.cpp',
+    '../gm/xfermodes.cpp',
+  ],
+}
+
+# Local Variables:
+# tab-width:2
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=2 shiftwidth=2:
diff --git a/samplecode/GMSampleView.h b/samplecode/GMSampleView.h
new file mode 100644
index 0000000..08acfcc
--- /dev/null
+++ b/samplecode/GMSampleView.h
@@ -0,0 +1,50 @@
+
+/*
+ * 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 GMSampleView_DEFINED
+#define GMSampleView_DEFINED
+
+#include "SampleCode.h"
+#include "gm.h"
+
+class GMSampleView : public SampleView {
+private:
+    typedef skiagm::GM GM;
+
+public:
+    GMSampleView(GM* gm)
+    : fGM(gm) {}
+    
+    virtual ~GMSampleView() {
+        delete fGM;
+    }
+    
+protected:
+    virtual bool onQuery(SkEvent* evt) {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, fGM->shortName());
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+    
+    virtual void onDrawContent(SkCanvas* canvas) {
+        fGM->drawContent(canvas);
+    }
+
+    virtual void onDrawBackground(SkCanvas* canvas) {
+        fGM->drawBackground(canvas);
+    }
+
+private:
+    GM* fGM;
+    typedef SampleView INHERITED;
+};
+
+#endif
diff --git a/samplecode/OverView.cpp b/samplecode/OverView.cpp
index 1a6d9e9..fc4a9ef 100644
--- a/samplecode/OverView.cpp
+++ b/samplecode/OverView.cpp
@@ -20,7 +20,7 @@
 }
 class OverView : public SkView {
 public:
-    OverView(int count, const SkViewFactory factories[]);
+    OverView(int count, const SkViewFactory* factories[]);
     virtual ~OverView();
     
 protected:
@@ -61,17 +61,16 @@
 
 private:
     int             fCount;
-    const SkViewFactory*  fFactories;
+    const SkViewFactory**  fFactories;
 
     typedef SkView INHERITED;
 };
 
-SkView* create_overview(int count, const SkViewFactory factories[]);
-SkView* create_overview(int count, const SkViewFactory factories[]) {
+SkView* create_overview(int count, const SkViewFactory* factories[]) {
     return SkNEW_ARGS(OverView, (count, factories));
 };
 
-OverView::OverView(int count, const SkViewFactory factories[]) {
+OverView::OverView(int count, const SkViewFactory* factories[]) {
     fCount = count;
     fFactories = factories;
 }
@@ -89,7 +88,7 @@
     SkScalar locX = 0;
     SkScalar locY = 0;
     for (int i = 0; i < fCount; i++) {
-        SkView* view = fFactories[i]();
+        SkView* view = (*fFactories[i])();
         view->setVisibleP(true);
         this->attachChildToBack(view)->unref();
         view->setLoc(locX, locY);
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index b0d471d..7947e74 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -56,7 +56,7 @@
 #define USE_ARROWS_FOR_ZOOM true
 //#define DEFAULT_TO_GPU
 
-extern SkView* create_overview(int, const SkViewFactory[]);
+extern SkView* create_overview(int, const SkViewFactory*[]);
 extern bool is_overview(SkView* view);
 extern SkView* create_transition(SkView*, SkView*, int);
 extern bool is_transition(SkView* view);
@@ -240,18 +240,75 @@
 }
 //////////////////
 
-SkViewRegister* SkViewRegister::gHead;
-SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
-    static bool gOnce;
-    if (!gOnce) {
-        gHead = NULL;
-        gOnce = true;
-    }
+SkFuncViewFactory::SkFuncViewFactory(SkViewCreateFunc func)
+    : fCreateFunc(func) {
+}
 
+SkView* SkFuncViewFactory::operator() () const SK_OVERRIDE {
+    return (*fCreateFunc)();
+}
+
+#include "GMSampleView.h"
+
+SkGMSampleViewFactory::SkGMSampleViewFactory(GMFactoryFunc func)
+    : fFunc(func) {
+}
+
+SkView* SkGMSampleViewFactory::operator() () const {
+    return new GMSampleView(fFunc(NULL));
+}
+
+SkViewRegister* SkViewRegister::gHead;
+SkViewRegister::SkViewRegister(SkViewFactory* fact) : fFact(fact) {
+    fFact->ref();
     fChain = gHead;
     gHead = this;
 }
 
+SkViewRegister::SkViewRegister(SkViewCreateFunc func) {
+    fFact = new SkFuncViewFactory(func);
+    fChain = gHead;
+    gHead = this;
+}
+
+SkViewRegister::SkViewRegister(GMFactoryFunc func) {
+    fFact = new SkGMSampleViewFactory(func);
+    fChain = gHead;
+    gHead = this;
+}
+
+class AutoUnrefArray {
+public:
+    AutoUnrefArray() {}
+    ~AutoUnrefArray() {
+        int count = fObjs.count();
+        for (int i = 0; i < count; ++i) {
+            fObjs[i]->unref();
+        }
+    }
+    SkRefCnt*& push_back() { return *fObjs.append(); }
+    
+private:
+    SkTDArray<SkRefCnt*> fObjs;
+};
+
+// registers GMs as Samples
+// This can't be performed during static initialization because it could be
+// run before GMRegistry has been fully built.
+void SkGMRegistyToSampleRegistry() {
+    static bool gOnce;
+    static AutoUnrefArray fRegisters; 
+
+    if (!gOnce) {
+        const skiagm::GMRegistry* gmreg = skiagm::GMRegistry::Head();
+        while (gmreg) {
+            fRegisters.push_back() = new SkViewRegister(gmreg->factory());
+            gmreg = gmreg->next();
+        }
+        gOnce = true;
+    }
+}
+
 #if 0
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFURLAccess.h>
@@ -416,6 +473,11 @@
     return gSampleWindow ? gSampleWindow->getGrContext() : NULL;
 }
 
+// some GMs rely on having a skiagm::GetGr function defined
+namespace skiagm {
+    GrContext* GetGr() { return SampleCode::GetGr(); }
+}
+
 //////////////////////////////////////////////////////////////////////////////
 
 static SkView* curr_view(SkWindow* wind) {
@@ -570,6 +632,7 @@
     this->setVisibleP(true);
     this->setClipToBounds(false);
 
+    SkGMRegistyToSampleRegistry();
     {
         const SkViewRegister* reg = SkViewRegister::Head();
         while (reg) {
@@ -591,7 +654,7 @@
             fprintf(stderr, "Unknown sample \"%s\"\n", argv[1]);
         }
     }
-    this->loadView(fSamples[fCurrIndex]());
+    this->loadView((*fSamples[fCurrIndex])());
     
     fPDFData = NULL;
 
@@ -1158,26 +1221,26 @@
 
 bool SampleWindow::previousSample() {
     fCurrIndex = (fCurrIndex - 1 + fSamples.count()) % fSamples.count();
-    this->loadView(create_transition(curr_view(this), fSamples[fCurrIndex](), 
+    this->loadView(create_transition(curr_view(this), (*fSamples[fCurrIndex])(), 
                                      fTransitionPrev));
     return true;
 }
 
 bool SampleWindow::nextSample() {
     fCurrIndex = (fCurrIndex + 1) % fSamples.count();
-    this->loadView(create_transition(curr_view(this), fSamples[fCurrIndex](), 
+    this->loadView(create_transition(curr_view(this), (*fSamples[fCurrIndex])(), 
                                      fTransitionNext));
     return true;
 }
 
 bool SampleWindow::goToSample(int i) {
     fCurrIndex = (i) % fSamples.count();
-    this->loadView(create_transition(curr_view(this),fSamples[fCurrIndex](), 6));
+    this->loadView(create_transition(curr_view(this),(*fSamples[fCurrIndex])(), 6));
     return true;
 }
 
 SkString SampleWindow::getSampleTitle(int i) {
-    SkView* view = fSamples[i]();
+    SkView* view = (*fSamples[i])();
     SkString title;
     SampleCode::RequestTitle(view, &title);
     view->unref();
@@ -1288,7 +1351,7 @@
         return true;
     }
     if (query->isType("get-slide-title")) {
-        SkView* view = fSamples[query->getFast32()]();
+        SkView* view = (*fSamples[query->getFast32()])();
         SkEvent evt(gTitleEvtName);
         if (view->doQuery(&evt)) {
             query->setString("title", evt.findString(gTitleEvtName));
diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h
index dba022a..0f1a2af 100644
--- a/samplecode/SampleApp.h
+++ b/samplecode/SampleApp.h
@@ -30,7 +30,7 @@
 class SkData;
 
 class SampleWindow : public SkOSWindow {
-    SkTDArray<SkViewFactory> fSamples;
+    SkTDArray<const SkViewFactory*> fSamples;
 public:
     enum DeviceType {
         kRaster_DeviceType,
diff --git a/samplecode/SampleCode.h b/samplecode/SampleCode.h
index d6c7929..197e0f1 100644
--- a/samplecode/SampleCode.h
+++ b/samplecode/SampleCode.h
@@ -5,6 +5,8 @@
  * 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
 
@@ -39,19 +41,59 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-typedef SkView* (*SkViewFactory)();
-
-class SkViewRegister : SkNoncopyable {
+// interface that constructs SkViews
+class SkViewFactory : public SkRefCnt {
 public:
-    explicit SkViewRegister(SkViewFactory);
+    virtual SkView* operator() () const = 0;
+};
+
+typedef SkView* (*SkViewCreateFunc)();
+
+// wraps SkViewCreateFunc in SkViewFactory interface
+class SkFuncViewFactory : public SkViewFactory {
+public:
+    SkFuncViewFactory(SkViewCreateFunc func);
+    virtual SkView* operator() () const SK_OVERRIDE;
+    
+private:
+    SkViewCreateFunc fCreateFunc;
+};
+
+namespace skiagm {
+class GM;
+}
+
+// factory function that creates a skiagm::GM
+typedef skiagm::GM* (*GMFactoryFunc)(void*);
+
+// Takes a GM factory function and implements the SkViewFactory interface 
+// by making the GM and wrapping it in a GMSampleView. GMSampleView bridges
+// the SampleView interface to skiagm::GM.
+class SkGMSampleViewFactory : public SkViewFactory {
+public:
+    SkGMSampleViewFactory(GMFactoryFunc func);
+    virtual SkView* operator() () const SK_OVERRIDE;
+private:
+    GMFactoryFunc fFunc;
+};
+
+class SkViewRegister : public SkRefCnt {
+public:
+    explicit SkViewRegister(SkViewFactory*);
+    explicit SkViewRegister(SkViewCreateFunc);
+    explicit SkViewRegister(GMFactoryFunc);
+
+    ~SkViewRegister() {
+        fFact->unref();
+    }
     
     static const SkViewRegister* Head() { return gHead; }
     
     SkViewRegister* next() const { return fChain; }
-    SkViewFactory   factory() const { return fFact; }
+    const SkViewFactory*   factory() const { return fFact; }
     
 private:
-    SkViewFactory   fFact;
+    SkViewFactory*  fFact;
     SkViewRegister* fChain;
     
     static SkViewRegister* gHead;
diff --git a/samplecode/SampleGM.cpp b/samplecode/SampleGM.cpp
deleted file mode 100644
index 2d172af..0000000
--- a/samplecode/SampleGM.cpp
+++ /dev/null
@@ -1,121 +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 "gm.h"
-
-using namespace skiagm;
-
-// need to explicitly declare this, or we get some weird infinite loop llist
-template GMRegistry* GMRegistry::gHead;
-
-class Iter {
-public:
-    Iter() {
-        fReg = GMRegistry::Head();
-    }
-	
-    void reset() {
-        fReg = GMRegistry::Head();
-    }
-        
-    GM* next() {
-        if (fReg) {
-            GMRegistry::Factory fact = fReg->factory();
-            fReg = fReg->next();
-            return fact(0);
-        }
-        return NULL;
-    }
-	
-    static int Count() {
-        const GMRegistry* reg = GMRegistry::Head();
-        int count = 0;
-        while (reg) {
-            count += 1;
-            reg = reg->next();
-        }
-        return count;
-    }
-	
-private:
-    const GMRegistry* fReg;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-class GMView : public SampleView {
-    Iter fIter;
-    GM*  fGM;
-public:
-	GMView() {
-        fGM = fIter.next();
-        this->postNextGM();
-        
-        this->setBGColor(0xFFDDDDDD);
-    }
-
-    virtual ~GMView() {
-        delete fGM;
-    }
-
-protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "GM");
-            return true;
-        }
-        return this->INHERITED::onQuery(evt);
-    }
-
-    virtual bool onEvent(const SkEvent& evt) {
-        if (evt.isType("next-gm")) {
-            delete fGM;
-            if (!(fGM = fIter.next())) {
-                fIter.reset();
-                fGM = fIter.next();
-            }
-            this->inval(NULL);
-            this->postNextGM();
-            return true;
-        }
-        return this->INHERITED::onEvent(evt);
-    }
-
-    virtual void onDrawContent(SkCanvas* canvas) {
-        fGM->draw(canvas);
-    }
-    
-private:
-    void postNextGM() {
-        (new SkEvent("next-gm", this->getSinkID()))->postDelay(1500);
-    }
-
-    typedef SampleView INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-static SkView* MyFactory() { return new GMView; }
-static SkViewRegister reg(MyFactory);
-
-///////////////////////////////////////////////////////////////////////////////
-
-using namespace skiagm;
-
-GM::GM() {}
-GM::~GM() {}
-
-void GM::draw(SkCanvas* canvas) {
-	this->onDraw(canvas);
-}
-
-