Use static XPF for porter duff xp factories.

BUG=skia:

Review URL: https://codereview.chromium.org/776843004
diff --git a/include/gpu/GrXferProcessor.h b/include/gpu/GrXferProcessor.h
index 139ac96..ee3764d 100644
--- a/include/gpu/GrXferProcessor.h
+++ b/include/gpu/GrXferProcessor.h
@@ -43,7 +43,7 @@
  * creates will have. For example, can it create an XP that supports RGB coverage or will the XP
  * blend with the destination color.
  */
-class GrXPFactory : public GrProgramElement {
+class GrXPFactory : public SkRefCnt {
 public:
     virtual const GrXferProcessor* createXferProcessor() const = 0;
 
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index ef44b1e..8350365 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -691,10 +691,17 @@
                                                 GrFragmentProcessor** fp,
                                                 GrXPFactory** xpf,
                                                 Coeff* src, Coeff* dst) {
+    Mode mode;
     if (NULL == xfermode) {
         SkAssertResult(ModeAsCoeff(kSrcOver_Mode, src, dst));
         *xpf = GrPorterDuffXPFactory::Create(*src, *dst);
         return true;
+    } else if (xfermode->asMode(&mode) && mode <= kLastCoeffMode) {
+        *xpf = GrPorterDuffXPFactory::Create(mode);
+        // TODO: This Line will be removed in follow up cl that handles blending and thus we won't
+        // have to set coeffs here.
+        SkAssertResult(ModeAsCoeff(mode, src, dst));
+        return true;
     } else if (xfermode->asCoeff(src, dst)) {
         *xpf = GrPorterDuffXPFactory::Create(*src, *dst);
         return true;
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 0fd0987..db70bfa 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -116,8 +116,7 @@
     fRenderTarget.reset(NULL);
 
     fGeometryProcessor.reset(NULL);
-    fXPFactory.reset(GrPorterDuffXPFactory::Create(kOne_GrBlendCoeff,
-                                                   kZero_GrBlendCoeff));
+    fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
     fColorStages.reset();
     fCoverageStages.reset();
 
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
index bd5b286..443e1c0 100644
--- a/src/gpu/GrPaint.cpp
+++ b/src/gpu/GrPaint.cpp
@@ -52,8 +52,7 @@
 void GrPaint::resetStages() {
     fColorStages.reset();
     fCoverageStages.reset();
-    fXPFactory.reset(GrPorterDuffXPFactory::Create(kOne_GrBlendCoeff,
-                                                   kZero_GrBlendCoeff));
+    fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode));
 }
 
 bool GrPaint::getOpaqueAndKnownColor(GrColor* solidColor,
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index dadf9f2..9059f55 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -475,15 +475,13 @@
         if (fragmentProcessor) {
             SkASSERT(NULL == xpFactory);
             grPaint->addColorProcessor(fragmentProcessor)->unref();
-            xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kOne_Coeff,
-                                                      SkXfermode::kZero_Coeff);
+            xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode);
             sm = SkXfermode::kOne_Coeff;
             dm = SkXfermode::kZero_Coeff;
         }
     } else {
         // Fall back to src-over
-        xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kOne_Coeff,
-                                                  SkXfermode::kISA_Coeff);
+        xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode);
         sm = SkXfermode::kOne_Coeff;
         dm = SkXfermode::kISA_Coeff;
     }
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index fdbcbbe..1f50f9d 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -61,6 +61,88 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode mode) {
+    switch (mode) {
+        case SkXfermode::kClear_Mode: {
+            static GrPorterDuffXPFactory gClearPDXPF(kZero_GrBlendCoeff, kZero_GrBlendCoeff);
+            return SkRef(&gClearPDXPF);
+            break;
+        }
+        case SkXfermode::kSrc_Mode: {
+            static GrPorterDuffXPFactory gSrcPDXPF(kOne_GrBlendCoeff, kZero_GrBlendCoeff);
+            return SkRef(&gSrcPDXPF);
+            break;
+        }
+        case SkXfermode::kDst_Mode: {
+            static GrPorterDuffXPFactory gDstPDXPF(kZero_GrBlendCoeff, kOne_GrBlendCoeff);
+            return SkRef(&gDstPDXPF);
+            break;
+        }
+        case SkXfermode::kSrcOver_Mode: {
+            static GrPorterDuffXPFactory gSrcOverPDXPF(kOne_GrBlendCoeff, kISA_GrBlendCoeff);
+            return SkRef(&gSrcOverPDXPF);
+            break;
+        }
+        case SkXfermode::kDstOver_Mode: {
+            static GrPorterDuffXPFactory gDstOverPDXPF(kIDA_GrBlendCoeff, kOne_GrBlendCoeff);
+            return SkRef(&gDstOverPDXPF);
+            break;
+        }
+        case SkXfermode::kSrcIn_Mode: {
+            static GrPorterDuffXPFactory gSrcInPDXPF(kDA_GrBlendCoeff, kZero_GrBlendCoeff);
+            return SkRef(&gSrcInPDXPF);
+            break;
+        }
+        case SkXfermode::kDstIn_Mode: {
+            static GrPorterDuffXPFactory gDstInPDXPF(kZero_GrBlendCoeff, kSA_GrBlendCoeff);
+            return SkRef(&gDstInPDXPF);
+            break;
+        }
+        case SkXfermode::kSrcOut_Mode: {
+            static GrPorterDuffXPFactory gSrcOutPDXPF(kIDA_GrBlendCoeff, kZero_GrBlendCoeff);
+            return SkRef(&gSrcOutPDXPF);
+            break;
+        }
+        case SkXfermode::kDstOut_Mode: {
+            static GrPorterDuffXPFactory gDstOutPDXPF(kZero_GrBlendCoeff, kISA_GrBlendCoeff);
+            return SkRef(&gDstOutPDXPF);
+            break;
+        }
+        case SkXfermode::kSrcATop_Mode: {
+            static GrPorterDuffXPFactory gSrcATopPDXPF(kDA_GrBlendCoeff, kISA_GrBlendCoeff);
+            return SkRef(&gSrcATopPDXPF);
+            break;
+        }
+        case SkXfermode::kDstATop_Mode: {
+            static GrPorterDuffXPFactory gDstATopPDXPF(kIDA_GrBlendCoeff, kSA_GrBlendCoeff);
+            return SkRef(&gDstATopPDXPF);
+            break;
+        }
+        case SkXfermode::kXor_Mode: {
+            static GrPorterDuffXPFactory gXorPDXPF(kIDA_GrBlendCoeff, kISA_GrBlendCoeff);
+            return SkRef(&gXorPDXPF);
+            break;
+        }
+        case SkXfermode::kPlus_Mode: {
+            static GrPorterDuffXPFactory gPlusPDXPF(kOne_GrBlendCoeff, kOne_GrBlendCoeff);
+            return SkRef(&gPlusPDXPF);
+            break;
+        }
+        case SkXfermode::kModulate_Mode: {
+            static GrPorterDuffXPFactory gModulatePDXPF(kZero_GrBlendCoeff, kSC_GrBlendCoeff);
+            return SkRef(&gModulatePDXPF);
+            break;
+        }
+        case SkXfermode::kScreen_Mode: {
+            static GrPorterDuffXPFactory gScreenPDXPF(kOne_GrBlendCoeff, kISC_GrBlendCoeff);
+            return SkRef(&gScreenPDXPF);
+            break;
+        }
+        default:
+            return NULL;
+    }
+}
+
 const GrXferProcessor* GrPorterDuffXPFactory::createXferProcessor() const {
     return GrPorterDuffXferProcessor::Create(fSrc, fDst);
 }
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.h b/src/gpu/effects/GrPorterDuffXferProcessor.h
index 474285d..d210a81 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.h
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.h
@@ -53,6 +53,8 @@
 
 class GrPorterDuffXPFactory : public GrXPFactory {
 public:
+    static GrXPFactory* Create(SkXfermode::Mode mode); 
+
     static GrXPFactory* Create(SkXfermode::Coeff src, SkXfermode::Coeff dst) {
         return SkNEW_ARGS(GrPorterDuffXPFactory, ((GrBlendCoeff)(src), (GrBlendCoeff)(dst)));
     }