diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp
index d3e29be..41b978b 100644
--- a/src/core/SkComposeShader.cpp
+++ b/src/core/SkComposeShader.cpp
@@ -196,146 +196,8 @@
 
 #if SK_SUPPORT_GPU
 
-#include "SkGr.h"
-#include "GrProcessor.h"
 #include "effects/GrConstColorProcessor.h"
-#include "gl/GrGLBlend.h"
-#include "gl/builders/GrGLProgramBuilder.h"
-
-/////////////////////////////////////////////////////////////////////
-
-class GrComposeEffect : public GrFragmentProcessor {
-public:
-
-    static GrFragmentProcessor* Create(const GrFragmentProcessor* fpA,
-                                       const GrFragmentProcessor* fpB, SkXfermode::Mode mode) {
-        return SkNEW_ARGS(GrComposeEffect, (fpA, fpB, mode));
-    }
-    const char* name() const override { return "ComposeShader"; }
-    void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
-
-    SkXfermode::Mode getMode() const { return fMode; }
-
-protected:
-    bool onIsEqual(const GrFragmentProcessor&) const override;
-    void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
-
-private:
-    GrComposeEffect(const GrFragmentProcessor* fpA, const GrFragmentProcessor* fpB,
-                    SkXfermode::Mode mode)
-        : fMode(mode) {
-        this->initClassID<GrComposeEffect>();
-        SkDEBUGCODE(int shaderAChildIndex = )this->registerChildProcessor(fpA);
-        SkDEBUGCODE(int shaderBChildIndex = )this->registerChildProcessor(fpB);
-        SkASSERT(0 == shaderAChildIndex);
-        SkASSERT(1 == shaderBChildIndex);
-    }
-
-    GrGLFragmentProcessor* onCreateGLInstance() const override;
-
-    SkXfermode::Mode fMode;
-
-    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
-
-    typedef GrFragmentProcessor INHERITED;
-};
-
-/////////////////////////////////////////////////////////////////////
-
-class GrGLComposeEffect : public GrGLFragmentProcessor {
-public:
-    GrGLComposeEffect(const GrProcessor& processor) {}
-
-    void emitCode(EmitArgs&) override;
-
-private:
-    typedef GrGLFragmentProcessor INHERITED;
-};
-
-/////////////////////////////////////////////////////////////////////
-
-GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrComposeEffect);
-
-const GrFragmentProcessor* GrComposeEffect::TestCreate(GrProcessorTestData* d) {
-#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
-    // Create two random frag procs.
-    // For now, we'll prevent either children from being a shader with children to prevent the
-    // possibility of an arbitrarily large tree of procs.
-    SkAutoTUnref<const GrFragmentProcessor> fpA;
-    do {
-        fpA.reset(GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d));
-        SkASSERT(fpA);
-    } while (fpA->numChildProcessors() != 0);
-    SkAutoTUnref<const GrFragmentProcessor> fpB;
-    do {
-        fpB.reset(GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d));
-        SkASSERT(fpB);
-    } while (fpB->numChildProcessors() != 0);
-
-    SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(
-            d->fRandom->nextRangeU(0, SkXfermode::kLastCoeffMode));
-    return SkNEW_ARGS(GrComposeEffect, (fpA, fpB, mode));
-#else
-    SkFAIL("Should not be called if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS");
-    return nullptr;
-#endif
-}
-
-bool GrComposeEffect::onIsEqual(const GrFragmentProcessor& other) const {
-    const GrComposeEffect& cs = other.cast<GrComposeEffect>();
-    return fMode == cs.fMode;
-}
-
-void GrComposeEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
-    inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
-}
-
-void GrComposeEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
-    b->add32(fMode);
-}
-
-GrGLFragmentProcessor* GrComposeEffect::onCreateGLInstance() const{
-    return SkNEW_ARGS(GrGLComposeEffect, (*this));
-}
-
-/////////////////////////////////////////////////////////////////////
-
-void GrGLComposeEffect::emitCode(EmitArgs& args) {
-
-    GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
-    const GrComposeEffect& cs = args.fFp.cast<GrComposeEffect>();
-
-    // Store alpha of input color and un-premultiply the input color by its alpha. We will
-    // re-multiply by this alpha after blending the output colors of the two child procs.
-    // This is because we don't want the paint's alpha to affect either child proc's output
-    // before the blend; we want to apply the paint's alpha AFTER the blend. This mirrors the
-    // software implementation of SkComposeShader.
-    SkString inputAlpha("inputAlpha");
-    fsBuilder->codeAppendf("float %s = %s.a;", inputAlpha.c_str(), args.fInputColor);
-    fsBuilder->codeAppendf("%s /= %s.a;", args.fInputColor, args.fInputColor);
-
-    // declare outputColor and emit the code for each of the two children
-    SkString outputColorA(args.fOutputColor);
-    outputColorA.append("_dst");
-    fsBuilder->codeAppendf("vec4 %s;\n", outputColorA.c_str());
-    this->emitChild(0, args.fInputColor, outputColorA.c_str(), args);
-
-    SkString outputColorB(args.fOutputColor);
-    outputColorB.append("_src");
-    fsBuilder->codeAppendf("vec4 %s;\n", outputColorB.c_str());
-    this->emitChild(1, args.fInputColor, outputColorB.c_str(), args);
-
-    // emit blend code
-    SkXfermode::Mode mode = cs.getMode();
-    fsBuilder->codeAppend("{");
-    fsBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode));
-    GrGLBlend::AppendPorterDuffBlend(fsBuilder, outputColorB.c_str(),
-                                     outputColorA.c_str(), args.fOutputColor, mode);
-    fsBuilder->codeAppend("}");
-
-    // re-multiply the output color by the input color's alpha
-    fsBuilder->codeAppendf("%s *= %s;", args.fOutputColor, inputAlpha.c_str());
-}
+#include "effects/GrXfermodeFragmentProcessor.h"
 
 /////////////////////////////////////////////////////////////////////
 
@@ -349,7 +211,7 @@
     // GrGLBlend::AppendPorterDuffBlend(), which emits the blend code in the shader,
     // only supports those modes.
     SkXfermode::Mode mode;
-    if (!(SkXfermode::AsMode(fMode, &mode) && mode <= SkXfermode::kLastCoeffMode)) {
+    if (!(SkXfermode::AsMode(fMode, &mode) && SkXfermode::kLastCoeffMode >= mode)) {
         return nullptr;
     }
 
@@ -375,7 +237,7 @@
             if (!fpB.get()) {
                 return nullptr;
             }
-            return GrComposeEffect::Create(fpA, fpB, mode);
+            return GrXfermodeFragmentProcessor::CreateFromTwoProcessors(fpB, fpA, mode);
     }
 }
 #endif
diff --git a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
new file mode 100644
index 0000000..aa47541
--- /dev/null
+++ b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
@@ -0,0 +1,168 @@
+/*
+* Copyright 2015 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "effects/GrXfermodeFragmentProcessor.h"
+
+#include "GrFragmentProcessor.h"
+#include "effects/GrConstColorProcessor.h"
+#include "gl/GrGLBlend.h"
+#include "gl/builders/GrGLProgramBuilder.h"
+
+
+class GrComposeTwoFragmentProcessor : public GrFragmentProcessor {
+public:
+    GrComposeTwoFragmentProcessor(const GrFragmentProcessor* src, const GrFragmentProcessor* dst,
+                    SkXfermode::Mode mode)
+        : fMode(mode) {
+        // Only coefficient xfer modes are supported
+        SkASSERT(SkXfermode::kLastCoeffMode >= mode);
+        this->initClassID<GrComposeTwoFragmentProcessor>();
+        SkDEBUGCODE(int shaderAChildIndex = )this->registerChildProcessor(src);
+        SkDEBUGCODE(int shaderBChildIndex = )this->registerChildProcessor(dst);
+        SkASSERT(0 == shaderAChildIndex);
+        SkASSERT(1 == shaderBChildIndex);
+    }
+
+    const char* name() const override { return "ComposeShader"; }
+
+    void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
+        b->add32(fMode);
+    }
+
+    SkXfermode::Mode getMode() const { return fMode; }
+
+protected:
+    bool onIsEqual(const GrFragmentProcessor& other) const override {
+        const GrComposeTwoFragmentProcessor& cs = other.cast<GrComposeTwoFragmentProcessor>();
+        return fMode == cs.fMode;
+    }
+
+    void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
+        inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
+    }
+
+private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
+    SkXfermode::Mode fMode;
+
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
+
+    typedef GrFragmentProcessor INHERITED;
+};
+
+/////////////////////////////////////////////////////////////////////
+
+class GrGLComposeTwoFragmentProcessor : public GrGLFragmentProcessor {
+public:
+    GrGLComposeTwoFragmentProcessor(const GrProcessor& processor) {}
+
+    void emitCode(EmitArgs&) override;
+
+private:
+    typedef GrGLFragmentProcessor INHERITED;
+};
+
+/////////////////////////////////////////////////////////////////////
+
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrComposeTwoFragmentProcessor);
+
+const GrFragmentProcessor* GrComposeTwoFragmentProcessor::TestCreate(GrProcessorTestData* d) {
+#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+    // Create two random frag procs.
+    // For now, we'll prevent either children from being a shader with children to prevent the
+    // possibility of an arbitrarily large tree of procs.
+    SkAutoTUnref<const GrFragmentProcessor> fpA;
+    do {
+        fpA.reset(GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d));
+        SkASSERT(fpA);
+    } while (fpA->numChildProcessors() != 0);
+    SkAutoTUnref<const GrFragmentProcessor> fpB;
+    do {
+        fpB.reset(GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(d));
+        SkASSERT(fpB);
+    } while (fpB->numChildProcessors() != 0);
+
+    SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(
+            d->fRandom->nextRangeU(0, SkXfermode::kLastCoeffMode));
+    return SkNEW_ARGS(GrComposeTwoFragmentProcessor, (fpA, fpB, mode));
+#else
+    SkFAIL("Should not be called if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS");
+    return nullptr;
+#endif
+}
+
+GrGLFragmentProcessor* GrComposeTwoFragmentProcessor::onCreateGLInstance() const{
+    return SkNEW_ARGS(GrGLComposeTwoFragmentProcessor, (*this));
+}
+
+/////////////////////////////////////////////////////////////////////
+
+void GrGLComposeTwoFragmentProcessor::emitCode(EmitArgs& args) {
+
+    GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
+    const GrComposeTwoFragmentProcessor& cs = args.fFp.cast<GrComposeTwoFragmentProcessor>();
+
+    // Store alpha of input color and un-premultiply the input color by its alpha. We will
+    // re-multiply by this alpha after blending the output colors of the two child procs.
+    // This is because we don't want the paint's alpha to affect either child proc's output
+    // before the blend; we want to apply the paint's alpha AFTER the blend. This mirrors the
+    // software implementation of SkComposeShader.
+    SkString inputAlpha("inputAlpha");
+    fsBuilder->codeAppendf("float %s = %s.a;", inputAlpha.c_str(), args.fInputColor);
+    fsBuilder->codeAppendf("%s /= %s.a;", args.fInputColor, args.fInputColor);
+
+    // declare outputColor and emit the code for each of the two children
+    SkString outputColorSrc(args.fOutputColor);
+    outputColorSrc.append("_src");
+    fsBuilder->codeAppendf("vec4 %s;\n", outputColorSrc.c_str());
+    this->emitChild(0, args.fInputColor, outputColorSrc.c_str(), args);
+
+    SkString outputColorDst(args.fOutputColor);
+    outputColorDst.append("_dst");
+    fsBuilder->codeAppendf("vec4 %s;\n", outputColorDst.c_str());
+    this->emitChild(1, args.fInputColor, outputColorDst.c_str(), args);
+
+    // emit blend code
+    SkXfermode::Mode mode = cs.getMode();
+    fsBuilder->codeAppend("{");
+    fsBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode));
+    GrGLBlend::AppendPorterDuffBlend(fsBuilder, outputColorSrc.c_str(),
+                                     outputColorDst.c_str(), args.fOutputColor, mode);
+    fsBuilder->codeAppend("}");
+
+    // re-multiply the output color by the input color's alpha
+    fsBuilder->codeAppendf("%s *= %s;", args.fOutputColor, inputAlpha.c_str());
+}
+
+
+const GrFragmentProcessor* GrXfermodeFragmentProcessor::CreateFromTwoProcessors(
+         const GrFragmentProcessor* src, const GrFragmentProcessor* dst, SkXfermode::Mode mode) {
+    if (SkXfermode::kLastCoeffMode < mode) {
+        return nullptr;
+    }
+    switch (mode) {
+        case SkXfermode::kClear_Mode:
+            SkDebugf("CreateFromTwoProcessors() should not be used with kClear_Mode. "
+                     "Use GrConstColorProcessor.\n");
+            return GrConstColorProcessor::Create(GrColor_TRANS_BLACK,
+                                                 GrConstColorProcessor::kIgnore_InputMode);
+            break;
+        case SkXfermode::kSrc_Mode:
+            SkDebugf("CreateFromTwoProcessors() should not be used with kSrc_Mode. "
+                     "Use the src processor directly.\n");
+            return SkRef(src);
+            break;
+        case SkXfermode::kDst_Mode:
+            SkDebugf("CreateFromTwoProcessors() should not be used with kDst_Mode. "
+                     "Use the dst processor directly.\n");
+            return SkRef(dst);
+            break;
+        default:
+            return new GrComposeTwoFragmentProcessor(src, dst, mode);
+    }
+}
