diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 603a2fd..bcb124b 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -162,6 +162,8 @@
       '<(skia_src_path)/gpu/effects/GrDistanceFieldTextureEffect.h',
       '<(skia_src_path)/gpu/effects/GrDitherEffect.cpp',
       '<(skia_src_path)/gpu/effects/GrDitherEffect.h',
+      '<(skia_src_path)/gpu/effects/GrMatrixConvolutionEffect.cpp',
+      '<(skia_src_path)/gpu/effects/GrMatrixConvolutionEffect.h',
       '<(skia_src_path)/gpu/effects/GrOvalEffect.cpp',
       '<(skia_src_path)/gpu/effects/GrOvalEffect.h',
       '<(skia_src_path)/gpu/effects/GrRRectEffect.cpp',
diff --git a/include/effects/SkMatrixConvolutionImageFilter.h b/include/effects/SkMatrixConvolutionImageFilter.h
index 6d4c826..0cb848b 100644
--- a/include/effects/SkMatrixConvolutionImageFilter.h
+++ b/include/effects/SkMatrixConvolutionImageFilter.h
@@ -23,9 +23,10 @@
 public:
     /*! \enum TileMode */
     enum TileMode {
-      kClamp_TileMode,         /*!< Clamp to the image's edge pixels. */
+      kClamp_TileMode = 0,         /*!< Clamp to the image's edge pixels. */
       kRepeat_TileMode,        /*!< Wrap around to the image's opposite edge. */
       kClampToBlack_TileMode,  /*!< Fill with transparent black. */
+      kMax_TileMode = kClampToBlack_TileMode
     };
 
     virtual ~SkMatrixConvolutionImageFilter();
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index 676cab7..f101720 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -14,12 +14,7 @@
 #include "SkUnPreMultiply.h"
 
 #if SK_SUPPORT_GPU
-#include "gl/GrGLEffect.h"
-#include "gl/GrGLShaderBuilder.h"
-#include "effects/GrSingleTextureEffect.h"
-#include "GrTBackendEffectFactory.h"
-#include "GrTexture.h"
-#include "SkMatrix.h"
+#include "effects/GrMatrixConvolutionEffect.h"
 #endif
 
 static bool tile_mode_is_valid(SkMatrixConvolutionImageFilter::TileMode tileMode) {
@@ -324,340 +319,17 @@
 
 #if SK_SUPPORT_GPU
 
-///////////////////////////////////////////////////////////////////////////////
-
-class GrGLMatrixConvolutionEffect;
-
-class GrMatrixConvolutionEffect : public GrSingleTextureEffect {
-public:
-    typedef SkMatrixConvolutionImageFilter::TileMode TileMode;
-    static GrEffect* Create(GrTexture* texture,
-                            const SkIRect& bounds,
-                            const SkISize& kernelSize,
-                            const SkScalar* kernel,
-                            SkScalar gain,
-                            SkScalar bias,
-                            const SkIPoint& kernelOffset,
-                            TileMode tileMode,
-                            bool convolveAlpha) {
-        return SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
-                                                      bounds,
-                                                      kernelSize,
-                                                      kernel,
-                                                      gain,
-                                                      bias,
-                                                      kernelOffset,
-                                                      tileMode,
-                                                      convolveAlpha));
-    }
-    virtual ~GrMatrixConvolutionEffect();
-
-    virtual void getConstantColorComponents(GrColor* color,
-                                            uint32_t* validFlags) const SK_OVERRIDE {
-        // TODO: Try to do better?
-        *validFlags = 0;
-    }
-
-    static const char* Name() { return "MatrixConvolution"; }
-    const SkIRect& bounds() const { return fBounds; }
-    const SkISize& kernelSize() const { return fKernelSize; }
-    const float* kernelOffset() const { return fKernelOffset; }
-    const float* kernel() const { return fKernel; }
-    float gain() const { return fGain; }
-    float bias() const { return fBias; }
-    TileMode tileMode() const { return fTileMode; }
-    bool convolveAlpha() const { return fConvolveAlpha; }
-
-    typedef GrGLMatrixConvolutionEffect GLEffect;
-
-    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
-
-private:
-    GrMatrixConvolutionEffect(GrTexture*,
-                              const SkIRect& bounds,
-                              const SkISize& kernelSize,
-                              const SkScalar* kernel,
-                              SkScalar gain,
-                              SkScalar bias,
-                              const SkIPoint& kernelOffset,
-                              TileMode tileMode,
-                              bool convolveAlpha);
-
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
-
-    SkIRect  fBounds;
-    SkISize  fKernelSize;
-    float   *fKernel;
-    float    fGain;
-    float    fBias;
-    float    fKernelOffset[2];
-    TileMode fTileMode;
-    bool     fConvolveAlpha;
-
-    GR_DECLARE_EFFECT_TEST;
-
-    typedef GrSingleTextureEffect INHERITED;
-};
-
-class GrGLMatrixConvolutionEffect : public GrGLEffect {
-public:
-    GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
-                                const GrDrawEffect& effect);
-    virtual void emitCode(GrGLShaderBuilder*,
-                          const GrDrawEffect&,
-                          const GrEffectKey&,
-                          const char* outputColor,
-                          const char* inputColor,
-                          const TransformedCoordsArray&,
-                          const TextureSamplerArray&) SK_OVERRIDE;
-
-    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
-
-    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
-
-private:
-    typedef GrGLUniformManager::UniformHandle        UniformHandle;
-    typedef SkMatrixConvolutionImageFilter::TileMode TileMode;
-    SkISize             fKernelSize;
-    TileMode            fTileMode;
-    bool                fConvolveAlpha;
-
-    UniformHandle       fBoundsUni;
-    UniformHandle       fKernelUni;
-    UniformHandle       fImageIncrementUni;
-    UniformHandle       fKernelOffsetUni;
-    UniformHandle       fGainUni;
-    UniformHandle       fBiasUni;
-
-    typedef GrGLEffect INHERITED;
-};
-
-GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
-                                                         const GrDrawEffect& drawEffect)
-    : INHERITED(factory) {
-    const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
-    fKernelSize = m.kernelSize();
-    fTileMode = m.tileMode();
-    fConvolveAlpha = m.convolveAlpha();
-}
-
-static void appendTextureLookup(GrGLShaderBuilder* builder,
-                                const GrGLShaderBuilder::TextureSampler& sampler,
-                                const char* coord,
-                                const char* bounds,
-                                SkMatrixConvolutionImageFilter::TileMode tileMode) {
-    SkString clampedCoord;
-    switch (tileMode) {
-        case SkMatrixConvolutionImageFilter::kClamp_TileMode:
-            clampedCoord.printf("clamp(%s, %s.xy, %s.zw)", coord, bounds, bounds);
-            coord = clampedCoord.c_str();
-            break;
-        case SkMatrixConvolutionImageFilter::kRepeat_TileMode:
-            clampedCoord.printf("mod(%s - %s.xy, %s.zw - %s.xy) + %s.xy", coord, bounds, bounds, bounds, bounds);
-            coord = clampedCoord.c_str();
-            break;
-        case SkMatrixConvolutionImageFilter::kClampToBlack_TileMode:
-            builder->fsCodeAppendf("clamp(%s, %s.xy, %s.zw) != %s ? vec4(0, 0, 0, 0) : ", coord, bounds, bounds, coord);
-            break;
-    }
-    builder->fsAppendTextureLookup(sampler, coord);
-}
-
-void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
-                                           const GrDrawEffect&,
-                                           const GrEffectKey& key,
-                                           const char* outputColor,
-                                           const char* inputColor,
-                                           const TransformedCoordsArray& coords,
-                                           const TextureSamplerArray& samplers) {
-    sk_ignore_unused_variable(inputColor);
-    SkString coords2D = builder->ensureFSCoords2D(coords, 0);
-    fBoundsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                     kVec4f_GrSLType, "Bounds");
-    fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                             kVec2f_GrSLType, "ImageIncrement");
-    fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
-                                             kFloat_GrSLType,
-                                             "Kernel",
-                                             fKernelSize.width() * fKernelSize.height());
-    fKernelOffsetUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                             kVec2f_GrSLType, "KernelOffset");
-    fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                   kFloat_GrSLType, "Gain");
-    fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
-                                   kFloat_GrSLType, "Bias");
-
-    const char* bounds = builder->getUniformCStr(fBoundsUni);
-    const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni);
-    const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
-    const char* kernel = builder->getUniformCStr(fKernelUni);
-    const char* gain = builder->getUniformCStr(fGainUni);
-    const char* bias = builder->getUniformCStr(fBiasUni);
-    int kWidth = fKernelSize.width();
-    int kHeight = fKernelSize.height();
-
-    builder->fsCodeAppend("\t\tvec4 sum = vec4(0, 0, 0, 0);\n");
-    builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(), kernelOffset, imgInc);
-    builder->fsCodeAppendf("\t\tfor (int y = 0; y < %d; y++) {\n", kHeight);
-    builder->fsCodeAppendf("\t\t\tfor (int x = 0; x < %d; x++) {\n", kWidth);
-    builder->fsCodeAppendf("\t\t\t\tfloat k = %s[y * %d + x];\n", kernel, kWidth);
-    builder->fsCodeAppendf("\t\t\t\tvec2 coord2 = coord + vec2(x, y) * %s;\n", imgInc);
-    builder->fsCodeAppend("\t\t\t\tvec4 c = ");
-    appendTextureLookup(builder, samplers[0], "coord2", bounds, fTileMode);
-    builder->fsCodeAppend(";\n");
-    if (!fConvolveAlpha) {
-        builder->fsCodeAppend("\t\t\t\tc.rgb /= c.a;\n");
-    }
-    builder->fsCodeAppend("\t\t\t\tsum += c * k;\n");
-    builder->fsCodeAppend("\t\t\t}\n");
-    builder->fsCodeAppend("\t\t}\n");
-    if (fConvolveAlpha) {
-        builder->fsCodeAppendf("\t\t%s = sum * %s + %s;\n", outputColor, gain, bias);
-        builder->fsCodeAppendf("\t\t%s.rgb = clamp(%s.rgb, 0.0, %s.a);\n",
-            outputColor, outputColor, outputColor);
-    } else {
-        builder->fsCodeAppend("\t\tvec4 c = ");
-        appendTextureLookup(builder, samplers[0], coords2D.c_str(), bounds, fTileMode);
-        builder->fsCodeAppend(";\n");
-        builder->fsCodeAppendf("\t\t%s.a = c.a;\n", outputColor);
-        builder->fsCodeAppendf("\t\t%s.rgb = sum.rgb * %s + %s;\n", outputColor, gain, bias);
-        builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
-    }
-}
-
-namespace {
-
-int encodeXY(int x, int y) {
-    SkASSERT(x >= 1 && y >= 1 && x * y <= 32);
-    if (y < x)
-        return 0x40 | encodeXY(y, x);
-    else
-        return (0x40 >> x) | (y - x);
-}
-
-};
-
-void GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
-                                         const GrGLCaps&, GrEffectKeyBuilder* b) {
-    const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
-    uint32_t key = encodeXY(m.kernelSize().width(), m.kernelSize().height());
-    key |= m.tileMode() << 7;
-    key |= m.convolveAlpha() ? 1 << 9 : 0;
-    b->add32(key);
-}
-
-void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
-                                          const GrDrawEffect& drawEffect) {
-    const GrMatrixConvolutionEffect& conv = drawEffect.castEffect<GrMatrixConvolutionEffect>();
-    GrTexture& texture = *conv.texture(0);
-    // the code we generated was for a specific kernel size
-    SkASSERT(conv.kernelSize() == fKernelSize);
-    SkASSERT(conv.tileMode() == fTileMode);
-    float imageIncrement[2];
-    float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f;
-    imageIncrement[0] = 1.0f / texture.width();
-    imageIncrement[1] = ySign / texture.height();
-    uman.set2fv(fImageIncrementUni, 1, imageIncrement);
-    uman.set2fv(fKernelOffsetUni, 1, conv.kernelOffset());
-    uman.set1fv(fKernelUni, fKernelSize.width() * fKernelSize.height(), conv.kernel());
-    uman.set1f(fGainUni, conv.gain());
-    uman.set1f(fBiasUni, conv.bias());
-    const SkIRect& bounds = conv.bounds();
-    float left = (float) bounds.left() / texture.width();
-    float top = (float) bounds.top() / texture.height();
-    float right = (float) bounds.right() / texture.width();
-    float bottom = (float) bounds.bottom() / texture.height();
-    if (texture.origin() == kBottomLeft_GrSurfaceOrigin) {
-        uman.set4f(fBoundsUni, left, 1.0f - bottom, right, 1.0f - top);
-    } else {
-        uman.set4f(fBoundsUni, left, top, right, bottom);
-    }
-}
-
-GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
-                                                     const SkIRect& bounds,
-                                                     const SkISize& kernelSize,
-                                                     const SkScalar* kernel,
-                                                     SkScalar gain,
-                                                     SkScalar bias,
-                                                     const SkIPoint& kernelOffset,
-                                                     TileMode tileMode,
-                                                     bool convolveAlpha)
-  : INHERITED(texture, MakeDivByTextureWHMatrix(texture)),
-    fBounds(bounds),
-    fKernelSize(kernelSize),
-    fGain(SkScalarToFloat(gain)),
-    fBias(SkScalarToFloat(bias) / 255.0f),
-    fTileMode(tileMode),
-    fConvolveAlpha(convolveAlpha) {
-    fKernel = new float[kernelSize.width() * kernelSize.height()];
-    for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) {
-        fKernel[i] = SkScalarToFloat(kernel[i]);
-    }
-    fKernelOffset[0] = static_cast<float>(kernelOffset.x());
-    fKernelOffset[1] = static_cast<float>(kernelOffset.y());
-    this->setWillNotUseInputColor();
-}
-
-GrMatrixConvolutionEffect::~GrMatrixConvolutionEffect() {
-    delete[] fKernel;
-}
-
-const GrBackendEffectFactory& GrMatrixConvolutionEffect::getFactory() const {
-    return GrTBackendEffectFactory<GrMatrixConvolutionEffect>::getInstance();
-}
-
-bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrMatrixConvolutionEffect& s = CastEffect<GrMatrixConvolutionEffect>(sBase);
-    return this->texture(0) == s.texture(0) &&
-           fKernelSize == s.kernelSize() &&
-           !memcmp(fKernel, s.kernel(),
-                   fKernelSize.width() * fKernelSize.height() * sizeof(float)) &&
-           fGain == s.gain() &&
-           fBias == s.bias() &&
-           fKernelOffset == s.kernelOffset() &&
-           fTileMode == s.tileMode() &&
-           fConvolveAlpha == s.convolveAlpha();
-}
-
-GR_DEFINE_EFFECT_TEST(GrMatrixConvolutionEffect);
-
-// A little bit less than the minimum # uniforms required by DX9SM2 (32).
-// Allows for a 5x5 kernel (or 25x1, for that matter).
-#define MAX_KERNEL_SIZE 25
-
-GrEffect* GrMatrixConvolutionEffect::TestCreate(SkRandom* random,
-                                                GrContext* context,
-                                                const GrDrawTargetCaps&,
-                                                GrTexture* textures[]) {
-    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
-                                      GrEffectUnitTest::kAlphaTextureIdx;
-    int width = random->nextRangeU(1, MAX_KERNEL_SIZE);
-    int height = random->nextRangeU(1, MAX_KERNEL_SIZE / width);
-    SkISize kernelSize = SkISize::Make(width, height);
-    SkAutoTDeleteArray<SkScalar> kernel(new SkScalar[width * height]);
-    for (int i = 0; i < width * height; i++) {
-        kernel.get()[i] = random->nextSScalar1();
-    }
-    SkScalar gain = random->nextSScalar1();
-    SkScalar bias = random->nextSScalar1();
-    SkIPoint kernelOffset = SkIPoint::Make(random->nextRangeU(0, kernelSize.width()),
-                                           random->nextRangeU(0, kernelSize.height()));
-    SkIRect bounds = SkIRect::MakeXYWH(random->nextRangeU(0, textures[texIdx]->width()),
-                                       random->nextRangeU(0, textures[texIdx]->height()),
-                                       random->nextRangeU(0, textures[texIdx]->width()),
-                                       random->nextRangeU(0, textures[texIdx]->height()));
-    TileMode tileMode = static_cast<TileMode>(random->nextRangeU(0, 2));
-    bool convolveAlpha = random->nextBool();
-    return GrMatrixConvolutionEffect::Create(textures[texIdx],
-                                             bounds,
-                                             kernelSize,
-                                             kernel.get(),
-                                             gain,
-                                             bias,
-                                             kernelOffset,
-                                             tileMode,
-                                             convolveAlpha);
+static GrMatrixConvolutionEffect::TileMode convert_tilemodes(
+        SkMatrixConvolutionImageFilter::TileMode tileMode) {
+    GR_STATIC_ASSERT(static_cast<int>(SkMatrixConvolutionImageFilter::kClamp_TileMode) ==
+                     static_cast<int>(GrMatrixConvolutionEffect::kClamp_TileMode));
+    GR_STATIC_ASSERT(static_cast<int>(SkMatrixConvolutionImageFilter::kRepeat_TileMode) ==
+                     static_cast<int>(GrMatrixConvolutionEffect::kRepeat_TileMode));
+    GR_STATIC_ASSERT(static_cast<int>(SkMatrixConvolutionImageFilter::kClampToBlack_TileMode) ==
+                     static_cast<int>(GrMatrixConvolutionEffect::kClampToBlack_TileMode));
+    GR_STATIC_ASSERT(static_cast<int>(SkMatrixConvolutionImageFilter::kMax_TileMode) ==
+                     static_cast<int>(GrMatrixConvolutionEffect::kMax_TileMode));
+    return static_cast<GrMatrixConvolutionEffect::TileMode>(tileMode);
 }
 
 bool SkMatrixConvolutionImageFilter::asNewEffect(GrEffect** effect,
@@ -676,11 +348,8 @@
                                                 fGain,
                                                 fBias,
                                                 fKernelOffset,
-                                                fTileMode,
+                                                convert_tilemodes(fTileMode),
                                                 fConvolveAlpha);
     return true;
 }
-
-///////////////////////////////////////////////////////////////////////////////
-
 #endif
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
new file mode 100644
index 0000000..283138e
--- /dev/null
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "GrMatrixConvolutionEffect.h"
+#include "gl/GrGLShaderBuilder.h"
+#include "gl/GrGLEffect.h"
+#include "gl/GrGLSL.h"
+#include "gl/GrGLTexture.h"
+#include "GrTBackendEffectFactory.h"
+
+class GrGLMatrixConvolutionEffect : public GrGLEffect {
+public:
+    GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
+                                const GrDrawEffect& effect);
+    virtual void emitCode(GrGLShaderBuilder*,
+                          const GrDrawEffect&,
+                          const GrEffectKey&,
+                          const char* outputColor,
+                          const char* inputColor,
+                          const TransformedCoordsArray&,
+                          const TextureSamplerArray&) SK_OVERRIDE;
+
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
+
+    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
+
+private:
+    typedef GrGLUniformManager::UniformHandle        UniformHandle;
+    typedef GrMatrixConvolutionEffect::TileMode TileMode;
+    SkISize             fKernelSize;
+    TileMode            fTileMode;
+    bool                fConvolveAlpha;
+
+    UniformHandle       fBoundsUni;
+    UniformHandle       fKernelUni;
+    UniformHandle       fImageIncrementUni;
+    UniformHandle       fKernelOffsetUni;
+    UniformHandle       fGainUni;
+    UniformHandle       fBiasUni;
+
+    typedef GrGLEffect INHERITED;
+};
+
+GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFactory& factory,
+                                                         const GrDrawEffect& drawEffect)
+    : INHERITED(factory) {
+    const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
+    fKernelSize = m.kernelSize();
+    fTileMode = m.tileMode();
+    fConvolveAlpha = m.convolveAlpha();
+}
+
+static void appendTextureLookup(GrGLShaderBuilder* builder,
+                                const GrGLShaderBuilder::TextureSampler& sampler,
+                                const char* coord,
+                                const char* bounds,
+                                GrMatrixConvolutionEffect::TileMode tileMode) {
+    SkString clampedCoord;
+    switch (tileMode) {
+        case GrMatrixConvolutionEffect::kClamp_TileMode:
+            clampedCoord.printf("clamp(%s, %s.xy, %s.zw)", coord, bounds, bounds);
+            coord = clampedCoord.c_str();
+            break;
+        case GrMatrixConvolutionEffect::kRepeat_TileMode:
+            clampedCoord.printf("mod(%s - %s.xy, %s.zw - %s.xy) + %s.xy", coord, bounds, bounds, bounds, bounds);
+            coord = clampedCoord.c_str();
+            break;
+        case GrMatrixConvolutionEffect::kClampToBlack_TileMode:
+            builder->fsCodeAppendf("clamp(%s, %s.xy, %s.zw) != %s ? vec4(0, 0, 0, 0) : ", coord, bounds, bounds, coord);
+            break;
+    }
+    builder->fsAppendTextureLookup(sampler, coord);
+}
+
+void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
+                                           const GrDrawEffect&,
+                                           const GrEffectKey& key,
+                                           const char* outputColor,
+                                           const char* inputColor,
+                                           const TransformedCoordsArray& coords,
+                                           const TextureSamplerArray& samplers) {
+    sk_ignore_unused_variable(inputColor);
+    SkString coords2D = builder->ensureFSCoords2D(coords, 0);
+    fBoundsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+                                     kVec4f_GrSLType, "Bounds");
+    fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+                                             kVec2f_GrSLType, "ImageIncrement");
+    fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
+                                             kFloat_GrSLType,
+                                             "Kernel",
+                                             fKernelSize.width() * fKernelSize.height());
+    fKernelOffsetUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+                                             kVec2f_GrSLType, "KernelOffset");
+    fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+                                   kFloat_GrSLType, "Gain");
+    fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+                                   kFloat_GrSLType, "Bias");
+
+    const char* bounds = builder->getUniformCStr(fBoundsUni);
+    const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni);
+    const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
+    const char* kernel = builder->getUniformCStr(fKernelUni);
+    const char* gain = builder->getUniformCStr(fGainUni);
+    const char* bias = builder->getUniformCStr(fBiasUni);
+    int kWidth = fKernelSize.width();
+    int kHeight = fKernelSize.height();
+
+    builder->fsCodeAppend("\t\tvec4 sum = vec4(0, 0, 0, 0);\n");
+    builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(), kernelOffset, imgInc);
+    builder->fsCodeAppendf("\t\tfor (int y = 0; y < %d; y++) {\n", kHeight);
+    builder->fsCodeAppendf("\t\t\tfor (int x = 0; x < %d; x++) {\n", kWidth);
+    builder->fsCodeAppendf("\t\t\t\tfloat k = %s[y * %d + x];\n", kernel, kWidth);
+    builder->fsCodeAppendf("\t\t\t\tvec2 coord2 = coord + vec2(x, y) * %s;\n", imgInc);
+    builder->fsCodeAppend("\t\t\t\tvec4 c = ");
+    appendTextureLookup(builder, samplers[0], "coord2", bounds, fTileMode);
+    builder->fsCodeAppend(";\n");
+    if (!fConvolveAlpha) {
+        builder->fsCodeAppend("\t\t\t\tc.rgb /= c.a;\n");
+    }
+    builder->fsCodeAppend("\t\t\t\tsum += c * k;\n");
+    builder->fsCodeAppend("\t\t\t}\n");
+    builder->fsCodeAppend("\t\t}\n");
+    if (fConvolveAlpha) {
+        builder->fsCodeAppendf("\t\t%s = sum * %s + %s;\n", outputColor, gain, bias);
+        builder->fsCodeAppendf("\t\t%s.rgb = clamp(%s.rgb, 0.0, %s.a);\n",
+            outputColor, outputColor, outputColor);
+    } else {
+        builder->fsCodeAppend("\t\tvec4 c = ");
+        appendTextureLookup(builder, samplers[0], coords2D.c_str(), bounds, fTileMode);
+        builder->fsCodeAppend(";\n");
+        builder->fsCodeAppendf("\t\t%s.a = c.a;\n", outputColor);
+        builder->fsCodeAppendf("\t\t%s.rgb = sum.rgb * %s + %s;\n", outputColor, gain, bias);
+        builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
+    }
+}
+
+namespace {
+
+int encodeXY(int x, int y) {
+    SkASSERT(x >= 1 && y >= 1 && x * y <= 32);
+    if (y < x)
+        return 0x40 | encodeXY(y, x);
+    else
+        return (0x40 >> x) | (y - x);
+}
+
+};
+
+void GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
+                                         const GrGLCaps&, GrEffectKeyBuilder* b) {
+    const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
+    uint32_t key = encodeXY(m.kernelSize().width(), m.kernelSize().height());
+    key |= m.tileMode() << 7;
+    key |= m.convolveAlpha() ? 1 << 9 : 0;
+    b->add32(key);
+}
+
+void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
+                                          const GrDrawEffect& drawEffect) {
+    const GrMatrixConvolutionEffect& conv = drawEffect.castEffect<GrMatrixConvolutionEffect>();
+    GrTexture& texture = *conv.texture(0);
+    // the code we generated was for a specific kernel size
+    SkASSERT(conv.kernelSize() == fKernelSize);
+    SkASSERT(conv.tileMode() == fTileMode);
+    float imageIncrement[2];
+    float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f;
+    imageIncrement[0] = 1.0f / texture.width();
+    imageIncrement[1] = ySign / texture.height();
+    uman.set2fv(fImageIncrementUni, 1, imageIncrement);
+    uman.set2fv(fKernelOffsetUni, 1, conv.kernelOffset());
+    uman.set1fv(fKernelUni, fKernelSize.width() * fKernelSize.height(), conv.kernel());
+    uman.set1f(fGainUni, conv.gain());
+    uman.set1f(fBiasUni, conv.bias());
+    const SkIRect& bounds = conv.bounds();
+    float left = (float) bounds.left() / texture.width();
+    float top = (float) bounds.top() / texture.height();
+    float right = (float) bounds.right() / texture.width();
+    float bottom = (float) bounds.bottom() / texture.height();
+    if (texture.origin() == kBottomLeft_GrSurfaceOrigin) {
+        uman.set4f(fBoundsUni, left, 1.0f - bottom, right, 1.0f - top);
+    } else {
+        uman.set4f(fBoundsUni, left, top, right, bottom);
+    }
+}
+
+GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
+                                                     const SkIRect& bounds,
+                                                     const SkISize& kernelSize,
+                                                     const SkScalar* kernel,
+                                                     SkScalar gain,
+                                                     SkScalar bias,
+                                                     const SkIPoint& kernelOffset,
+                                                     TileMode tileMode,
+                                                     bool convolveAlpha)
+  : INHERITED(texture, MakeDivByTextureWHMatrix(texture)),
+    fBounds(bounds),
+    fKernelSize(kernelSize),
+    fGain(SkScalarToFloat(gain)),
+    fBias(SkScalarToFloat(bias) / 255.0f),
+    fTileMode(tileMode),
+    fConvolveAlpha(convolveAlpha) {
+    fKernel = new float[kernelSize.width() * kernelSize.height()];
+    for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) {
+        fKernel[i] = SkScalarToFloat(kernel[i]);
+    }
+    fKernelOffset[0] = static_cast<float>(kernelOffset.x());
+    fKernelOffset[1] = static_cast<float>(kernelOffset.y());
+    this->setWillNotUseInputColor();
+}
+
+GrMatrixConvolutionEffect::~GrMatrixConvolutionEffect() {
+    delete[] fKernel;
+}
+
+const GrBackendEffectFactory& GrMatrixConvolutionEffect::getFactory() const {
+    return GrTBackendEffectFactory<GrMatrixConvolutionEffect>::getInstance();
+}
+
+bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const {
+    const GrMatrixConvolutionEffect& s = CastEffect<GrMatrixConvolutionEffect>(sBase);
+    return this->texture(0) == s.texture(0) &&
+           fKernelSize == s.kernelSize() &&
+           !memcmp(fKernel, s.kernel(),
+                   fKernelSize.width() * fKernelSize.height() * sizeof(float)) &&
+           fGain == s.gain() &&
+           fBias == s.bias() &&
+           fKernelOffset == s.kernelOffset() &&
+           fTileMode == s.tileMode() &&
+           fConvolveAlpha == s.convolveAlpha();
+}
+
+GR_DEFINE_EFFECT_TEST(GrMatrixConvolutionEffect);
+
+GrEffect* GrMatrixConvolutionEffect::TestCreate(SkRandom* random,
+                                                GrContext* context,
+                                                const GrDrawTargetCaps&,
+                                                GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
+                                      GrEffectUnitTest::kAlphaTextureIdx;
+    int width = random->nextRangeU(1, MAX_KERNEL_SIZE);
+    int height = random->nextRangeU(1, MAX_KERNEL_SIZE / width);
+    SkISize kernelSize = SkISize::Make(width, height);
+    SkAutoTDeleteArray<SkScalar> kernel(new SkScalar[width * height]);
+    for (int i = 0; i < width * height; i++) {
+        kernel.get()[i] = random->nextSScalar1();
+    }
+    SkScalar gain = random->nextSScalar1();
+    SkScalar bias = random->nextSScalar1();
+    SkIPoint kernelOffset = SkIPoint::Make(random->nextRangeU(0, kernelSize.width()),
+                                           random->nextRangeU(0, kernelSize.height()));
+    SkIRect bounds = SkIRect::MakeXYWH(random->nextRangeU(0, textures[texIdx]->width()),
+                                       random->nextRangeU(0, textures[texIdx]->height()),
+                                       random->nextRangeU(0, textures[texIdx]->width()),
+                                       random->nextRangeU(0, textures[texIdx]->height()));
+    TileMode tileMode = static_cast<TileMode>(random->nextRangeU(0, 2));
+    bool convolveAlpha = random->nextBool();
+    return GrMatrixConvolutionEffect::Create(textures[texIdx],
+                                             bounds,
+                                             kernelSize,
+                                             kernel.get(),
+                                             gain,
+                                             bias,
+                                             kernelOffset,
+                                             tileMode,
+                                             convolveAlpha);
+}
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.h b/src/gpu/effects/GrMatrixConvolutionEffect.h
new file mode 100644
index 0000000..6fdd85b
--- /dev/null
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrMatrixConvolutionEffect_DEFINED
+#define GrMatrixConvolutionEffect_DEFINED
+
+#include "GrSingleTextureEffect.h"
+
+// A little bit less than the minimum # uniforms required by DX9SM2 (32).
+// Allows for a 5x5 kernel (or 25x1, for that matter).
+#define MAX_KERNEL_SIZE 25
+
+class GrGLMatrixConvolutionEffect;
+
+class GrMatrixConvolutionEffect : public GrSingleTextureEffect {
+public:
+    /*! \enum TileMode */
+    enum TileMode {
+        kClamp_TileMode = 0,         /*!< Clamp to the image's edge pixels. */
+        kRepeat_TileMode,        /*!< Wrap around to the image's opposite edge. */
+        kClampToBlack_TileMode,  /*!< Fill with transparent black. */
+        kMax_TileMode = kClampToBlack_TileMode
+    };
+
+    typedef GrMatrixConvolutionEffect::TileMode TileMode;
+    static GrEffect* Create(GrTexture* texture,
+                            const SkIRect& bounds,
+                            const SkISize& kernelSize,
+                            const SkScalar* kernel,
+                            SkScalar gain,
+                            SkScalar bias,
+                            const SkIPoint& kernelOffset,
+                            TileMode tileMode,
+                            bool convolveAlpha) {
+        return SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
+                                                      bounds,
+                                                      kernelSize,
+                                                      kernel,
+                                                      gain,
+                                                      bias,
+                                                      kernelOffset,
+                                                      tileMode,
+                                                      convolveAlpha));
+    }
+    virtual ~GrMatrixConvolutionEffect();
+
+    virtual void getConstantColorComponents(GrColor* color,
+                                            uint32_t* validFlags) const SK_OVERRIDE {
+        // TODO: Try to do better?
+        *validFlags = 0;
+    }
+
+    static const char* Name() { return "MatrixConvolution"; }
+    const SkIRect& bounds() const { return fBounds; }
+    const SkISize& kernelSize() const { return fKernelSize; }
+    const float* kernelOffset() const { return fKernelOffset; }
+    const float* kernel() const { return fKernel; }
+    float gain() const { return fGain; }
+    float bias() const { return fBias; }
+    TileMode tileMode() const { return fTileMode; }
+    bool convolveAlpha() const { return fConvolveAlpha; }
+
+    typedef GrGLMatrixConvolutionEffect GLEffect;
+
+    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
+
+private:
+    GrMatrixConvolutionEffect(GrTexture*,
+                              const SkIRect& bounds,
+                              const SkISize& kernelSize,
+                              const SkScalar* kernel,
+                              SkScalar gain,
+                              SkScalar bias,
+                              const SkIPoint& kernelOffset,
+                              TileMode tileMode,
+                              bool convolveAlpha);
+
+    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+
+    SkIRect  fBounds;
+    SkISize  fKernelSize;
+    float   *fKernel;
+    float    fGain;
+    float    fBias;
+    float    fKernelOffset[2];
+    TileMode fTileMode;
+    bool     fConvolveAlpha;
+
+    GR_DECLARE_EFFECT_TEST;
+
+    typedef GrSingleTextureEffect INHERITED;
+};
+
+#endif
