Use sk_sp with GrXferProcessor and use a static factory to handle the nullptr==srcover case.

Bug: skia:
Change-Id: I9c07069fc2aae24fc2884c18939e3a649afc27e7
Reviewed-on: https://skia-review.googlesource.com/11282
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index f48162c..759f97c 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -54,17 +54,9 @@
     {
         bool hasMixedSamples =
                 args.fRenderTarget->isMixedSampled() && (isHWAA || this->isStencilEnabled());
-        sk_sp<GrXferProcessor> xferProcessor;
-        const GrXPFactory* xpFactory = args.fProcessors->xpFactory();
-        if (xpFactory) {
-            xferProcessor.reset(xpFactory->createXferProcessor(
-                    args.fXPInputColor, args.fXPInputCoverage, hasMixedSamples, *args.fCaps));
-            SkASSERT(xferProcessor);
-        } else {
-            // This may return nullptr in the common case of src-over implemented using hw blending.
-            xferProcessor.reset(GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
-                    *args.fCaps, args.fXPInputColor, args.fXPInputCoverage, hasMixedSamples));
-        }
+        sk_sp<GrXferProcessor> xferProcessor =
+                GrXPFactory::MakeXferProcessor(args.fProcessors->xpFactory(), args.fXPInputColor,
+                                               args.fXPInputCoverage, hasMixedSamples, *args.fCaps);
         fXferProcessor.reset(xferProcessor.get());
     }
     if (args.fDstTexture.texture()) {
diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp
index b04a5cc..bf5bc59 100644
--- a/src/gpu/GrXferProcessor.cpp
+++ b/src/gpu/GrXferProcessor.cpp
@@ -167,10 +167,16 @@
     return result;
 }
 
-GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcessorAnalysisColor& color,
-                                                  GrProcessorAnalysisCoverage coverage,
-                                                  bool hasMixedSamples,
-                                                  const GrCaps& caps) const {
+sk_sp<GrXferProcessor> GrXPFactory::MakeXferProcessor(const GrXPFactory* factory,
+                                                      const GrProcessorAnalysisColor& color,
+                                                      GrProcessorAnalysisCoverage coverage,
+                                                      bool hasMixedSamples,
+                                                      const GrCaps& caps) {
     SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport());
-    return this->onCreateXferProcessor(caps, color, coverage, hasMixedSamples);
+    if (factory) {
+        return factory->makeXferProcessor(color, coverage, hasMixedSamples, caps);
+    } else {
+        return GrPorterDuffXPFactory::MakeSrcOverXferProcessor(color, coverage, hasMixedSamples,
+                                                               caps);
+    }
 }
diff --git a/src/gpu/GrXferProcessor.h b/src/gpu/GrXferProcessor.h
index b65a125..bfc6dd7 100644
--- a/src/gpu/GrXferProcessor.h
+++ b/src/gpu/GrXferProcessor.h
@@ -236,11 +236,6 @@
 public:
     typedef GrXferProcessor::DstTexture DstTexture;
 
-    GrXferProcessor* createXferProcessor(const GrProcessorAnalysisColor&,
-                                         GrProcessorAnalysisCoverage,
-                                         bool hasMixedSamples,
-                                         const GrCaps& caps) const;
-
     enum class AnalysisProperties : unsigned {
         kNone = 0x0,
         /**
@@ -273,6 +268,12 @@
     };
     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(AnalysisProperties);
 
+    static sk_sp<GrXferProcessor> MakeXferProcessor(const GrXPFactory*,
+                                                    const GrProcessorAnalysisColor&,
+                                                    GrProcessorAnalysisCoverage,
+                                                    bool hasMixedSamples,
+                                                    const GrCaps& caps);
+
     static AnalysisProperties GetAnalysisProperties(const GrXPFactory*,
                                                     const GrProcessorAnalysisColor&,
                                                     const GrProcessorAnalysisCoverage&,
@@ -282,10 +283,10 @@
     constexpr GrXPFactory() {}
 
 private:
-    virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
-                                                   const GrProcessorAnalysisColor&,
-                                                   GrProcessorAnalysisCoverage,
-                                                   bool hasMixedSamples) const = 0;
+    virtual sk_sp<GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
+                                                     GrProcessorAnalysisCoverage,
+                                                     bool hasMixedSamples,
+                                                     const GrCaps&) const = 0;
 
     /**
      * Subclass analysis implementation. This should not return kNeedsDstInTexture as that will be
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp
index 4d4b00a..5b54308 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.cpp
+++ b/src/gpu/effects/GrCoverageSetOpXP.cpp
@@ -18,12 +18,11 @@
 
 class CoverageSetOpXP : public GrXferProcessor {
 public:
-    static GrXferProcessor* Create(SkRegion::Op regionOp, bool invertCoverage) {
-        return new CoverageSetOpXP(regionOp, invertCoverage);
+    CoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage)
+            : fRegionOp(regionOp), fInvertCoverage(invertCoverage) {
+        this->initClassID<CoverageSetOpXP>();
     }
 
-    ~CoverageSetOpXP() override;
-
     const char* name() const override { return "Coverage Set Op"; }
 
     GrGLSLXferProcessor* createGLSLInstance() const override;
@@ -31,7 +30,6 @@
     bool invertCoverage() const { return fInvertCoverage; }
 
 private:
-    CoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage);
 
     void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
 
@@ -83,15 +81,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-CoverageSetOpXP::CoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage)
-    : fRegionOp(regionOp)
-    , fInvertCoverage(invertCoverage) {
-    this->initClassID<CoverageSetOpXP>();
-}
-
-CoverageSetOpXP::~CoverageSetOpXP() {
-}
-
 void CoverageSetOpXP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                             GrProcessorKeyBuilder* b) const {
     GLCoverageSetOpXP::GenKey(*this, caps, b);
@@ -218,10 +207,10 @@
     return nullptr;
 }
 
-GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps,
-                                                                 const GrProcessorAnalysisColor&,
-                                                                 GrProcessorAnalysisCoverage,
-                                                                 bool hasMixedSamples) const {
+sk_sp<GrXferProcessor> GrCoverageSetOpXPFactory::makeXferProcessor(const GrProcessorAnalysisColor&,
+                                                                   GrProcessorAnalysisCoverage,
+                                                                   bool hasMixedSamples,
+                                                                   const GrCaps& caps) const {
     // We don't support inverting coverage with mixed samples. We don't expect to ever want this in
     // the future, however we could at some point make this work using an inverted coverage
     // modulation table. Note that an inverted table still won't work if there are coverage procs.
@@ -230,7 +219,7 @@
         return nullptr;
     }
 
-    return CoverageSetOpXP::Create(fRegionOp, fInvertCoverage);
+    return sk_sp<GrXferProcessor>(new CoverageSetOpXP(fRegionOp, fInvertCoverage));
 }
 
 GR_DEFINE_XP_FACTORY_TEST(GrCoverageSetOpXPFactory);
@@ -239,6 +228,6 @@
 const GrXPFactory* GrCoverageSetOpXPFactory::TestGet(GrProcessorTestData* d) {
     SkRegion::Op regionOp = SkRegion::Op(d->fRandom->nextULessThan(SkRegion::kLastOp + 1));
     bool invertCoverage = !d->fRenderTargetContext->hasMixedSamples() && d->fRandom->nextBool();
-    return GrCoverageSetOpXPFactory::Get(regionOp, invertCoverage);
+    return new GrCoverageSetOpXPFactory(regionOp, invertCoverage);
 }
 #endif
diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h
index a0fe4f9..5de068c 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.h
+++ b/src/gpu/effects/GrCoverageSetOpXP.h
@@ -30,9 +30,9 @@
 private:
     constexpr GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage);
 
-    GrXferProcessor* onCreateXferProcessor(const GrCaps&, const GrProcessorAnalysisColor&,
-                                           GrProcessorAnalysisCoverage,
-                                           bool hasMixedSamples) const override;
+    sk_sp<GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
+                                             GrProcessorAnalysisCoverage, bool hasMixedSamples,
+                                             const GrCaps&) const override;
 
     AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
                                           const GrProcessorAnalysisCoverage&,
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index 8d7c410..2cc8228 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -213,9 +213,10 @@
             : fMode(mode), fHWBlendEquation(hw_blend_equation(mode)) {}
 
 private:
-    GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrProcessorAnalysisColor&,
-                                           GrProcessorAnalysisCoverage,
-                                           bool hasMixedSamples) const override;
+    sk_sp<GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
+                                             GrProcessorAnalysisCoverage,
+                                             bool hasMixedSamples,
+                                             const GrCaps&) const override;
 
     AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
                                           const GrProcessorAnalysisCoverage&,
@@ -232,15 +233,15 @@
 #pragma GCC diagnostic pop
 #endif
 
-GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps,
-                                                        const GrProcessorAnalysisColor&,
-                                                        GrProcessorAnalysisCoverage coverage,
-                                                        bool hasMixedSamples) const {
+sk_sp<GrXferProcessor> CustomXPFactory::makeXferProcessor(const GrProcessorAnalysisColor&,
+                                                          GrProcessorAnalysisCoverage coverage,
+                                                          bool hasMixedSamples,
+                                                          const GrCaps& caps) const {
     SkASSERT(GrCustomXfermode::IsSupportedMode(fMode));
     if (can_use_hw_blend_equation(fHWBlendEquation, coverage, caps)) {
-        return new CustomXP(fMode, fHWBlendEquation);
+        return sk_sp<GrXferProcessor>(new CustomXP(fMode, fHWBlendEquation));
     }
-    return new CustomXP(hasMixedSamples, fMode);
+    return sk_sp<GrXferProcessor>(new CustomXP(hasMixedSamples, fMode));
 }
 
 GrXPFactory::AnalysisProperties CustomXPFactory::analysisProperties(
diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp
index 917f5c8..ca0b134 100644
--- a/src/gpu/effects/GrDisableColorXP.cpp
+++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -18,16 +18,13 @@
  */
 class DisableColorXP : public GrXferProcessor {
 public:
-    static GrXferProcessor* Create() { return new DisableColorXP; }
-
-    ~DisableColorXP() override {}
+    DisableColorXP() { this->initClassID<DisableColorXP>(); }
 
     const char* name() const override { return "Disable Color"; }
 
     GrGLSLXferProcessor* createGLSLInstance() const override;
 
 private:
-    DisableColorXP();
 
     void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
 
@@ -66,10 +63,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-DisableColorXP::DisableColorXP() {
-    this->initClassID<DisableColorXP>();
-}
-
 void DisableColorXP::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
     GLDisableColorXP::GenKey(*this, caps, b);
 }
@@ -81,11 +74,11 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps,
-                                                                const GrProcessorAnalysisColor&,
-                                                                GrProcessorAnalysisCoverage,
-                                                                bool hasMixedSamples) const {
-    return DisableColorXP::Create();
+sk_sp<GrXferProcessor> GrDisableColorXPFactory::makeXferProcessor(const GrProcessorAnalysisColor&,
+                                                                  GrProcessorAnalysisCoverage,
+                                                                  bool hasMixedSamples,
+                                                                  const GrCaps& caps) const {
+    return sk_sp<GrXferProcessor>(new DisableColorXP);
 }
 
 GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory);
diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h
index b3c4677..e6ae134 100644
--- a/src/gpu/effects/GrDisableColorXP.h
+++ b/src/gpu/effects/GrDisableColorXP.h
@@ -31,9 +31,10 @@
                AnalysisProperties::kIgnoresInputColor;
     }
 
-    GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrProcessorAnalysisColor&,
-                                           GrProcessorAnalysisCoverage,
-                                           bool hasMixedSamples) const override;
+    sk_sp<GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
+                                             GrProcessorAnalysisCoverage,
+                                             bool hasMixedSamples,
+                                             const GrCaps&) const override;
 
     GR_DECLARE_XP_FACTORY_TEST;
 
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index da73f4b..e5e2c1c 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -518,8 +518,8 @@
 
 class PDLCDXferProcessor : public GrXferProcessor {
 public:
-    static GrXferProcessor* Create(SkBlendMode xfermode,
-                                   const GrProcessorAnalysisColor& inputColor);
+    static sk_sp<GrXferProcessor> Make(SkBlendMode xfermode,
+                                       const GrProcessorAnalysisColor& inputColor);
 
     ~PDLCDXferProcessor() override;
 
@@ -600,8 +600,8 @@
     this->initClassID<PDLCDXferProcessor>();
 }
 
-GrXferProcessor* PDLCDXferProcessor::Create(SkBlendMode xfermode,
-                                            const GrProcessorAnalysisColor& color) {
+sk_sp<GrXferProcessor> PDLCDXferProcessor::Make(SkBlendMode xfermode,
+                                                const GrProcessorAnalysisColor& color) {
     if (SkBlendMode::kSrcOver != xfermode) {
         return nullptr;
     }
@@ -612,7 +612,7 @@
     blendConstant = GrUnpremulColor(blendConstant);
     uint8_t alpha = GrColorUnpackA(blendConstant);
     blendConstant |= (0xff << GrColor_SHIFT_A);
-    return new PDLCDXferProcessor(blendConstant, alpha);
+    return sk_sp<GrXferProcessor>(new PDLCDXferProcessor(blendConstant, alpha));
 }
 
 PDLCDXferProcessor::~PDLCDXferProcessor() {
@@ -696,10 +696,9 @@
     }
 }
 
-GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
-                                                              const GrProcessorAnalysisColor& color,
-                                                              GrProcessorAnalysisCoverage coverage,
-                                                              bool hasMixedSamples) const {
+sk_sp<GrXferProcessor> GrPorterDuffXPFactory::makeXferProcessor(
+        const GrProcessorAnalysisColor& color, GrProcessorAnalysisCoverage coverage,
+        bool hasMixedSamples, const GrCaps& caps) const {
     BlendFormula blendFormula;
     if (coverage == GrProcessorAnalysisCoverage::kLCD) {
         if (SkBlendMode::kSrcOver == fBlendMode && color.isConstant() &&
@@ -707,7 +706,7 @@
             !caps.shaderCaps()->dstReadInShaderSupport()) {
             // If we don't have dual source blending or in shader dst reads, we fall back to this
             // trick for rendering SrcOver LCD text instead of doing a dst copy.
-            return PDLCDXferProcessor::Create(fBlendMode, color);
+            return PDLCDXferProcessor::Make(fBlendMode, color);
         }
         blendFormula = get_lcd_blend_formula(fBlendMode);
     } else {
@@ -717,9 +716,9 @@
     }
 
     if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
-        return new ShaderPDXferProcessor(hasMixedSamples, fBlendMode);
+        return sk_sp<GrXferProcessor>(new ShaderPDXferProcessor(hasMixedSamples, fBlendMode));
     }
-    return new PorterDuffXferProcessor(blendFormula);
+    return sk_sp<GrXferProcessor>(new PorterDuffXferProcessor(blendFormula));
 }
 
 static inline GrXPFactory::AnalysisProperties analysis_properties(
@@ -802,11 +801,9 @@
     return gSrcOverXP;
 }
 
-GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
-        const GrCaps& caps,
-        const GrProcessorAnalysisColor& color,
-        GrProcessorAnalysisCoverage coverage,
-        bool hasMixedSamples) {
+sk_sp<GrXferProcessor> GrPorterDuffXPFactory::MakeSrcOverXferProcessor(
+        const GrProcessorAnalysisColor& color, GrProcessorAnalysisCoverage coverage,
+        bool hasMixedSamples, const GrCaps& caps) {
     // We want to not make an xfer processor if possible. Thus for the simple case where we are not
     // doing lcd blending we will just use our global SimpleSrcOverXP. This slightly differs from
     // the general case where we convert a src-over blend that has solid coverage and an opaque
@@ -824,15 +821,16 @@
         // If we don't have dual source blending or in shader dst reads, we fall
         // back to this trick for rendering SrcOver LCD text instead of doing a
         // dst copy.
-        return PDLCDXferProcessor::Create(SkBlendMode::kSrcOver, color);
+        return PDLCDXferProcessor::Make(SkBlendMode::kSrcOver, color);
     }
 
     BlendFormula blendFormula;
     blendFormula = get_lcd_blend_formula(SkBlendMode::kSrcOver);
     if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
-        return new ShaderPDXferProcessor(hasMixedSamples, SkBlendMode::kSrcOver);
+        return sk_sp<GrXferProcessor>(
+                new ShaderPDXferProcessor(hasMixedSamples, SkBlendMode::kSrcOver));
     }
-    return new PorterDuffXferProcessor(blendFormula);
+    return sk_sp<GrXferProcessor>(new PorterDuffXferProcessor(blendFormula));
 }
 
 sk_sp<GrXferProcessor> GrPorterDuffXPFactory::CreateNoCoverageXP(SkBlendMode blendmode) {
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.h b/src/gpu/effects/GrPorterDuffXferProcessor.h
index 6effc18..7ec0d58 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.h
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.h
@@ -23,10 +23,9 @@
 
     /** Because src-over is so common we special case it for performance reasons. If this returns
         null then the SimpleSrcOverXP() below should be used. */
-    static GrXferProcessor* CreateSrcOverXferProcessor(const GrCaps& caps,
-                                                       const GrProcessorAnalysisColor& color,
-                                                       GrProcessorAnalysisCoverage coverage,
-                                                       bool hasMixedSamples);
+    static sk_sp<GrXferProcessor> MakeSrcOverXferProcessor(const GrProcessorAnalysisColor&,
+                                                           GrProcessorAnalysisCoverage,
+                                                           bool hasMixedSamples, const GrCaps&);
 
     /** Returns a simple non-LCD porter duff blend XP with no optimizations or coverage. */
     static sk_sp<GrXferProcessor> CreateNoCoverageXP(SkBlendMode);
@@ -42,9 +41,10 @@
 private:
     constexpr GrPorterDuffXPFactory(SkBlendMode);
 
-    GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrProcessorAnalysisColor&,
-                                           GrProcessorAnalysisCoverage,
-                                           bool hasMixedSamples) const override;
+    sk_sp<GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
+                                             GrProcessorAnalysisCoverage,
+                                             bool hasMixedSamples,
+                                             const GrCaps&) const override;
 
     AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
                                           const GrProcessorAnalysisCoverage&,