diff --git a/gm/modecolorfilters.cpp b/gm/modecolorfilters.cpp
new file mode 100644
index 0000000..40e65fc
--- /dev/null
+++ b/gm/modecolorfilters.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2012 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"
+#include "SkBitmapProcShader.h"
+#include "SkColorFilter.h"
+#include "SkGradientShader.h"
+
+#define WIDTH 512
+#define HEIGHT 1024
+
+namespace skiagm {
+
+// Using gradients because GPU doesn't currently have an implementation of SkColorShader (duh!)
+static SkShader* make_color_shader(SkColor color) {
+    static const SkPoint kPts[] = {{0, 0}, {1, 1}};
+    SkColor colors[] = {color, color};
+
+    return SkGradientShader::CreateLinear(kPts, colors, NULL, 2, SkShader::kClamp_TileMode);
+}
+
+static SkShader* make_solid_shader() {
+    return make_color_shader(SkColorSetARGB(0xFF, 0x40, 0x80, 0x20));
+}
+
+static SkShader* make_transparent_shader() {
+    return make_color_shader(SkColorSetARGB(0x80, 0x10, 0x70, 0x20));
+}
+
+static SkShader* make_trans_black_shader() {
+    return make_color_shader(0x0);
+}
+
+// draws a background behind each test rect to see transparency
+static SkShader* make_bg_shader(int checkSize) {
+    SkBitmap bmp;
+    bmp.setConfig(SkBitmap::kARGB_8888_Config, 2 * checkSize, 2 * checkSize);
+    bmp.allocPixels();
+    SkCanvas canvas(bmp);
+    canvas.clear(0xFF800000);
+    SkPaint paint;
+    paint.setColor(0xFF000080);
+    SkRect rect0 = SkRect::MakeXYWH(0, 0,
+                                    SkIntToScalar(checkSize), SkIntToScalar(checkSize));
+    SkRect rect1 = SkRect::MakeXYWH(SkIntToScalar(checkSize), SkIntToScalar(checkSize),
+                                    SkIntToScalar(checkSize), SkIntToScalar(checkSize));
+    canvas.drawRect(rect1, paint);
+    canvas.drawRect(rect0, paint);
+    return SkNEW_ARGS(SkBitmapProcShader, (bmp, SkShader::kRepeat_TileMode,
+                                                SkShader::kRepeat_TileMode));
+}
+
+class ModeColorFilterGM : public GM {
+public:
+    ModeColorFilterGM() {
+        this->setBGColor(0xFF303030);
+    }
+
+protected:
+    virtual SkString onShortName() {
+        return SkString("modecolorfilters");
+    }
+
+    virtual SkISize onISize() {
+        return make_isize(WIDTH, HEIGHT);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) {
+        // size of rect for each test case
+        static const int kRectWidth  = 20;
+        static const int kRectHeight = 20;        
+
+        static const int kCheckSize  = 10;
+
+        if (!fBmpShader) {
+            fBmpShader.reset(make_bg_shader(kCheckSize));
+        }
+        SkPaint bgPaint;
+        bgPaint.setShader(fBmpShader);
+        bgPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
+
+        SkShader* shaders[] = {
+            NULL,                                   // use a paint color instead of a shader
+            make_solid_shader(),
+            make_transparent_shader(),
+            make_trans_black_shader(),
+        };
+
+        // used without shader
+        SkColor colors[] = {
+            SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF),
+            SkColorSetARGB(0xFF, 0x00, 0x00, 0x00),
+            SkColorSetARGB(0x00, 0x00, 0x00, 0x00),
+            SkColorSetARGB(0xFF, 0x10, 0x20, 0x40),
+            SkColorSetARGB(0xA0, 0x20, 0x30, 0x90),
+        };
+
+        // used with shaders
+        SkColor alphas[] = {0xFFFFFFFF, 0x80808080};
+        
+        SkXfermode::Mode modes[]  = { // currently just doing the Modes expressible as Coeffs
+            SkXfermode::kClear_Mode,
+            SkXfermode::kSrc_Mode,
+            SkXfermode::kDst_Mode,
+            SkXfermode::kSrcOver_Mode,
+            SkXfermode::kDstOver_Mode,
+            SkXfermode::kSrcIn_Mode,
+            SkXfermode::kDstIn_Mode,
+            SkXfermode::kSrcOut_Mode,
+            SkXfermode::kDstOut_Mode,
+            SkXfermode::kSrcATop_Mode,
+            SkXfermode::kDstATop_Mode,
+            SkXfermode::kXor_Mode,
+            SkXfermode::kPlus_Mode,
+            SkXfermode::kMultiply_Mode,
+        };
+
+        SkPaint paint;
+        int idx = 0;
+        static const int kRectsPerRow = SkMax32(this->getISize().fWidth / kRectWidth, 1);
+        for (size_t cfm = 0; cfm < SK_ARRAY_COUNT(modes); ++cfm) {
+            for (int cfc = 0; cfc < SK_ARRAY_COUNT(colors); ++cfc) {
+                SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(colors[cfc],
+                                                                               modes[cfm]));
+                paint.setColorFilter(cf);
+                for (int s = 0; s < SK_ARRAY_COUNT(shaders); ++s) {
+                    paint.setShader(shaders[s]);
+                    bool hasShader = NULL == paint.getShader();
+                    int paintColorCnt = hasShader ? SK_ARRAY_COUNT(alphas) : SK_ARRAY_COUNT(colors);
+                    SkColor* paintColors = hasShader ? alphas : colors;
+                    for (int pc = 0; pc < paintColorCnt; ++pc) {
+                        paint.setColor(paintColors[pc]);
+                        SkScalar x = SkIntToScalar(idx % kRectsPerRow);
+                        SkScalar y = SkIntToScalar(idx / kRectsPerRow);
+                        SkRect rect = SkRect::MakeXYWH(x * kRectWidth, y * kRectHeight,
+                                                       kRectWidth, kRectHeight);
+                        canvas->drawRect(rect, bgPaint);
+                        canvas->drawRect(rect, paint);
+                        ++idx;
+                    }
+                }
+            }
+        }
+
+        for (int i = 0; i < SK_ARRAY_COUNT(shaders); ++i) {
+            SkSafeUnref(shaders[i]);
+        }
+    }
+
+private:
+    SkAutoTUnref<SkShader> fBmpShader;
+    typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static GM* MyFactory(void*) { return new ModeColorFilterGM; }
+static GMRegistry reg(MyFactory);
+
+}
