Make analysis optional to GrPipeline::init().
authorBrian Salomon <bsalomon@google.com>
Wed, 29 Mar 2017 18:25:04 +0000 (14:25 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 29 Mar 2017 19:05:06 +0000 (19:05 +0000)
GrXPFactory::createXferProcessor now takes GrPipelineAnalysisColor and GrPipelineAnalysisCoverage rather than GrProcessorSet::FragmentProcessorAnalysis.

This will make it so ops do not have to retain the analysis or rerun it to create pipelines at flush time.

Change-Id: Ib28ba65de425b20c2647329275f209aec168c3df
Reviewed-on: https://skia-review.googlesource.com/10474
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
19 files changed:
src/gpu/GrPipeline.cpp
src/gpu/GrPipeline.h
src/gpu/GrPipelineAnalysis.h
src/gpu/GrProcessorSet.cpp
src/gpu/GrProcessorSet.h
src/gpu/GrRenderTargetContext.cpp
src/gpu/GrXferProcessor.cpp
src/gpu/GrXferProcessor.h
src/gpu/effects/GrCoverageSetOpXP.cpp
src/gpu/effects/GrCoverageSetOpXP.h
src/gpu/effects/GrCustomXfermode.cpp
src/gpu/effects/GrDisableColorXP.cpp
src/gpu/effects/GrDisableColorXP.h
src/gpu/effects/GrPorterDuffXferProcessor.cpp
src/gpu/effects/GrPorterDuffXferProcessor.h
src/gpu/instanced/InstancedRendering.cpp
src/gpu/ops/GrDrawPathOp.cpp
tests/GpuSampleLocationsTest.cpp
tests/GrPorterDuffTest.cpp

index 0a4a36c..82d938e 100644 (file)
 #include "ops/GrOp.h"
 
 void GrPipeline::init(const InitArgs& args) {
-    SkASSERT(args.fAnalysis);
+    if (args.fAnalysis) {
+        SkASSERT(args.fAnalysis->outputColor() == args.fInputColor);
+        SkASSERT(args.fAnalysis->outputCoverage() == args.fInputCoverage);
+    }
     SkASSERT(args.fRenderTarget);
 
     fRenderTarget.reset(args.fRenderTarget);
@@ -58,27 +61,33 @@ void GrPipeline::init(const InitArgs& args) {
         sk_sp<GrXferProcessor> xferProcessor;
         const GrXPFactory* xpFactory = args.fProcessors->xpFactory();
         if (xpFactory) {
-            xferProcessor.reset(xpFactory->createXferProcessor(*args.fAnalysis, hasMixedSamples,
+            xferProcessor.reset(xpFactory->createXferProcessor(args.fInputColor,
+                                                               args.fInputCoverage, hasMixedSamples,
                                                                &args.fDstTexture, *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.fAnalysis, hasMixedSamples, &args.fDstTexture));
+                    *args.fCaps, args.fInputColor, args.fInputCoverage, hasMixedSamples,
+                    &args.fDstTexture));
         }
         fXferProcessor.reset(xferProcessor.get());
     }
 
-    // This is for the legacy GrPipeline creation in GrMeshDrawOp where analysis does not
-    // eliminate fragment processors from GrProcessorSet.
-    GrColor overrideColor = GrColor_ILLEGAL;
-    int colorFPsToEliminate =
-            args.fAnalysis->getInputColorOverrideAndColorProcessorEliminationCount(&overrideColor);
-    colorFPsToEliminate = SkTMax(colorFPsToEliminate, 0);
-    if (args.fAnalysis->isInputColorIgnored()) {
-        // No need to have an override color if it isn't even going to be used.
-        overrideColor = GrColor_ILLEGAL;
-        colorFPsToEliminate = args.fProcessors->numColorFragmentProcessors();
+    // This is for the legacy GrPipeline creation in GrMeshDrawOp where analysis does not eliminate
+    // fragment processors from GrProcessorSet.
+    int colorFPsToEliminate = 0;
+    if (args.fAnalysis) {
+        GrColor overrideColor = GrColor_ILLEGAL;
+        colorFPsToEliminate =
+                args.fAnalysis->getInputColorOverrideAndColorProcessorEliminationCount(
+                        &overrideColor);
+        colorFPsToEliminate = SkTMax(colorFPsToEliminate, 0);
+        if (args.fAnalysis->isInputColorIgnored()) {
+            // No need to have an override color if it isn't even going to be used.
+            overrideColor = GrColor_ILLEGAL;
+            colorFPsToEliminate = args.fProcessors->numColorFragmentProcessors();
+        }
     }
 
     // Copy GrFragmentProcessors from GrPipelineBuilder to Pipeline, possibly removing some of the
index 7c861b2..3802faa 100644 (file)
@@ -57,7 +57,10 @@ public:
         uint32_t fFlags = 0;
         GrDrawFace fDrawFace = GrDrawFace::kBoth;
         const GrProcessorSet* fProcessors = nullptr;
-        const GrProcessorSet::FragmentProcessorAnalysis* fAnalysis;
+        GrPipelineAnalysisColor fInputColor;
+        GrPipelineAnalysisCoverage fInputCoverage = GrPipelineAnalysisCoverage::kNone;
+        // This is only used for GrMeshDrawOp's legacy pipeline creation system.
+        const GrProcessorSet::FragmentProcessorAnalysis* fAnalysis = nullptr;
         const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
         const GrAppliedClip* fAppliedClip = nullptr;
         GrRenderTarget* fRenderTarget = nullptr;
index d55ff0a..5f4699e 100644 (file)
@@ -51,6 +51,13 @@ public:
         return false;
     }
 
+    bool operator==(const GrPipelineAnalysisColor& that) const {
+        if (fFlags != that.fFlags) {
+            return false;
+        }
+        return (kColorIsKnown_Flag & fFlags) ? fColor == that.fColor : true;
+    }
+
 private:
     enum Flags {
         kColorIsKnown_Flag = 0x1,
index 0350ba5..b47a026 100644 (file)
@@ -119,8 +119,7 @@ void GrProcessorSet::FragmentProcessorAnalysis::internalInit(
 
     GrPipelineAnalysisColor outputColor = colorInfo.outputColor();
     if (outputColor.isConstant(&fKnownOutputColor)) {
-        fOutputColorType = static_cast<unsigned>(outputColor.isOpaque() ? ColorType::kOpaqueConstant
-                                                                        : ColorType::kConstant);
+        fOutputColorType = static_cast<unsigned>(ColorType::kConstant);
     } else if (outputColor.isOpaque()) {
         fOutputColorType = static_cast<unsigned>(ColorType::kOpaque);
     } else {
index e584a94..4f9a1c3 100644 (file)
@@ -128,27 +128,24 @@ public:
         }
         bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
         bool isInputColorIgnored() const { return fIgnoresInputColor; }
-        bool isOutputColorOpaque() const {
-            return ColorType::kOpaque == this->outputColorType() ||
-                   ColorType::kOpaqueConstant == this->outputColorType();
-        }
-        bool hasKnownOutputColor(GrColor* color = nullptr) const {
-            bool constant = ColorType::kConstant == this->outputColorType() ||
-                            ColorType::kOpaqueConstant == this->outputColorType();
-            if (constant && color) {
-                *color = fKnownOutputColor;
-            }
-            return constant;
-        }
-        GrPipelineAnalysisCoverage outputCoverageType() const {
+        GrPipelineAnalysisCoverage outputCoverage() const {
             return static_cast<GrPipelineAnalysisCoverage>(fOutputCoverageType);
         }
-        bool hasCoverage() const {
-            return this->outputCoverageType() != GrPipelineAnalysisCoverage::kNone;
+        GrPipelineAnalysisColor outputColor() const {
+            switch (this->outputColorType()) {
+                case ColorType::kConstant:
+                    return fKnownOutputColor;
+                case ColorType::kOpaque:
+                    return GrPipelineAnalysisColor::Opaque::kYes;
+                case ColorType::kUnknown:
+                    return GrPipelineAnalysisColor::Opaque::kNo;
+            }
+            SkFAIL("Unexpected color type");
+            return GrPipelineAnalysisColor::Opaque::kNo;
         }
 
     private:
-        enum class ColorType : unsigned { kUnknown, kOpaqueConstant, kConstant, kOpaque };
+        enum class ColorType : unsigned { kUnknown, kConstant, kOpaque };
 
         ColorType outputColorType() const { return static_cast<ColorType>(fOutputColorType); }
 
index 79ae757..babdb1a 100644 (file)
@@ -1742,6 +1742,8 @@ uint32_t GrRenderTargetContext::addMeshDrawOp(const GrPipelineBuilder& pipelineB
     args.fRenderTarget = rt;
     args.fCaps = this->caps();
     args.fAnalysis = &analysis;
+    args.fInputColor = analysis.outputColor();
+    args.fInputCoverage = analysis.outputCoverage();
 
     if (analysis.requiresDstTexture()) {
         this->setupDstTexture(rt, clip, bounds, &args.fDstTexture);
index f206028..fb90051 100644 (file)
@@ -189,21 +189,11 @@ GrXPFactory::AnalysisProperties GrXPFactory::GetAnalysisProperties(
     return result;
 }
 
-GrXferProcessor* GrXPFactory::createXferProcessor(const FragmentProcessorAnalysis& analysis,
+GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineAnalysisColor& color,
+                                                  GrPipelineAnalysisCoverage coverage,
                                                   bool hasMixedSamples,
                                                   const DstTexture* dstTexture,
                                                   const GrCaps& caps) const {
-#ifdef SK_DEBUG
-    if (analysis.requiresDstTexture()) {
-        if (!caps.shaderCaps()->dstReadInShaderSupport()) {
-            SkASSERT(dstTexture && dstTexture->texture());
-        } else {
-            SkASSERT(!dstTexture || !dstTexture->texture());
-        }
-    } else {
-        SkASSERT(!dstTexture || !dstTexture->texture());
-    }
     SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport());
-#endif
-    return this->onCreateXferProcessor(caps, analysis, hasMixedSamples, dstTexture);
+    return this->onCreateXferProcessor(caps, color, coverage, hasMixedSamples, dstTexture);
 }
index 2898d7f..2033aea 100644 (file)
@@ -268,7 +268,8 @@ public:
 
     typedef GrXferProcessor::DstTexture DstTexture;
 
-    GrXferProcessor* createXferProcessor(const FragmentProcessorAnalysis&,
+    GrXferProcessor* createXferProcessor(const GrPipelineAnalysisColor&,
+                                         GrPipelineAnalysisCoverage,
                                          bool hasMixedSamples,
                                          const DstTexture*,
                                          const GrCaps& caps) const;
@@ -293,7 +294,8 @@ protected:
 
 private:
     virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
-                                                   const FragmentProcessorAnalysis&,
+                                                   const GrPipelineAnalysisColor&,
+                                                   GrPipelineAnalysisCoverage,
                                                    bool hasMixedSamples,
                                                    const DstTexture*) const = 0;
 
index 84219ae..4d514fb 100644 (file)
@@ -218,11 +218,11 @@ const GrXPFactory* GrCoverageSetOpXPFactory::Get(SkRegion::Op regionOp, bool inv
     return nullptr;
 }
 
-GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(
-        const GrCaps& caps,
-        const FragmentProcessorAnalysis& analysis,
-        bool hasMixedSamples,
-        const DstTexture* dst) const {
+GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps,
+                                                                 const GrPipelineAnalysisColor&,
+                                                                 GrPipelineAnalysisCoverage,
+                                                                 bool hasMixedSamples,
+                                                                 const DstTexture*) 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.
index b7239f3..16ccf20 100644 (file)
@@ -30,9 +30,8 @@ public:
 private:
     constexpr GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage);
 
-    GrXferProcessor* onCreateXferProcessor(const GrCaps&,
-                                           const FragmentProcessorAnalysis&,
-                                           bool hasMixedSamples,
+    GrXferProcessor* onCreateXferProcessor(const GrCaps&, const GrPipelineAnalysisColor&,
+                                           GrPipelineAnalysisCoverage, bool hasMixedSamples,
                                            const DstTexture*) const override;
 
     AnalysisProperties analysisProperties(const GrPipelineAnalysisColor&,
index 55b73e0..04718d4 100644 (file)
@@ -213,9 +213,8 @@ public:
             : fMode(mode), fHWBlendEquation(hw_blend_equation(mode)) {}
 
 private:
-    GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
-                                           const FragmentProcessorAnalysis&,
-                                           bool hasMixedSamples,
+    GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysisColor&,
+                                           GrPipelineAnalysisCoverage, bool hasMixedSamples,
                                            const DstTexture*) const override;
 
     AnalysisProperties analysisProperties(const GrPipelineAnalysisColor&,
@@ -234,11 +233,12 @@ private:
 #endif
 
 GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps,
-                                                        const FragmentProcessorAnalysis& analysis,
+                                                        const GrPipelineAnalysisColor&,
+                                                        GrPipelineAnalysisCoverage coverage,
                                                         bool hasMixedSamples,
                                                         const DstTexture* dstTexture) const {
     SkASSERT(GrCustomXfermode::IsSupportedMode(fMode));
-    if (can_use_hw_blend_equation(fHWBlendEquation, analysis.outputCoverageType(), caps)) {
+    if (can_use_hw_blend_equation(fHWBlendEquation, coverage, caps)) {
         SkASSERT(!dstTexture || !dstTexture->texture());
         return new CustomXP(fMode, fHWBlendEquation);
     }
index 2268097..71a50eb 100644 (file)
@@ -81,11 +81,11 @@ void DisableColorXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(
-        const GrCaps& caps,
-        const FragmentProcessorAnalysis& analysis,
-        bool hasMixedSamples,
-        const DstTexture* dst) const {
+GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps,
+                                                                const GrPipelineAnalysisColor&,
+                                                                GrPipelineAnalysisCoverage,
+                                                                bool hasMixedSamples,
+                                                                const DstTexture* dst) const {
     return DisableColorXP::Create();
 }
 
index 9a829ed..85ddb61 100644 (file)
@@ -31,9 +31,8 @@ private:
                AnalysisProperties::kIgnoresInputColor;
     }
 
-    GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
-                                           const FragmentProcessorAnalysis&,
-                                           bool hasMixedSamples,
+    GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysisColor&,
+                                           GrPipelineAnalysisCoverage, bool hasMixedSamples,
                                            const DstTexture* dstTexture) const override;
 
     GR_DECLARE_XP_FACTORY_TEST;
index 98268a2..f2b3d7c 100644 (file)
@@ -521,7 +521,7 @@ GrGLSLXferProcessor* ShaderPDXferProcessor::createGLSLInstance() const {
 
 class PDLCDXferProcessor : public GrXferProcessor {
 public:
-    static GrXferProcessor* Create(SkBlendMode xfermode, const FragmentProcessorAnalysis& analysis);
+    static GrXferProcessor* Create(SkBlendMode xfermode, const GrPipelineAnalysisColor& inputColor);
 
     ~PDLCDXferProcessor() override;
 
@@ -603,12 +603,12 @@ PDLCDXferProcessor::PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha)
 }
 
 GrXferProcessor* PDLCDXferProcessor::Create(SkBlendMode xfermode,
-                                            const FragmentProcessorAnalysis& analysis) {
+                                            const GrPipelineAnalysisColor& color) {
     if (SkBlendMode::kSrcOver != xfermode) {
         return nullptr;
     }
     GrColor blendConstant;
-    if (!analysis.hasKnownOutputColor(&blendConstant)) {
+    if (!color.isConstant(&blendConstant)) {
         return nullptr;
     }
     blendConstant = GrUnpremulColor(blendConstant);
@@ -698,25 +698,26 @@ const GrXPFactory* GrPorterDuffXPFactory::Get(SkBlendMode blendMode) {
     }
 }
 
-GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(
-        const GrCaps& caps,
-        const FragmentProcessorAnalysis& analysis,
-        bool hasMixedSamples,
-        const DstTexture* dstTexture) const {
+GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
+                                                              const GrPipelineAnalysisColor& color,
+                                                              GrPipelineAnalysisCoverage coverage,
+                                                              bool hasMixedSamples,
+                                                              const DstTexture* dstTexture) const {
     BlendFormula blendFormula;
-    if (analysis.outputCoverageType() == GrPipelineAnalysisCoverage::kLCD) {
-        if (SkBlendMode::kSrcOver == fBlendMode && analysis.hasKnownOutputColor() &&
+    if (coverage == GrPipelineAnalysisCoverage::kLCD) {
+        if (SkBlendMode::kSrcOver == fBlendMode && color.isConstant() &&
             !caps.shaderCaps()->dualSourceBlendingSupport() &&
             !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.
             SkASSERT(!dstTexture || !dstTexture->texture());
-            return PDLCDXferProcessor::Create(fBlendMode, analysis);
+            return PDLCDXferProcessor::Create(fBlendMode, color);
         }
         blendFormula = get_lcd_blend_formula(fBlendMode);
     } else {
-        blendFormula = get_blend_formula(analysis.isOutputColorOpaque(), analysis.hasCoverage(),
-                                         hasMixedSamples, fBlendMode);
+        blendFormula =
+                get_blend_formula(color.isOpaque(), GrPipelineAnalysisCoverage::kNone != coverage,
+                                  hasMixedSamples, fBlendMode);
     }
 
     if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
@@ -809,15 +810,15 @@ const GrXferProcessor& GrPorterDuffXPFactory::SimpleSrcOverXP() {
 
 GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
         const GrCaps& caps,
-        const FragmentProcessorAnalysis& analysis,
+        const GrPipelineAnalysisColor& color,
+        GrPipelineAnalysisCoverage coverage,
         bool hasMixedSamples,
         const GrXferProcessor::DstTexture* dstTexture) {
-
     // 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
     // color to src-mode, which allows disabling of blending.
-    if (analysis.outputCoverageType() != GrPipelineAnalysisCoverage::kLCD) {
+    if (coverage != GrPipelineAnalysisCoverage::kLCD) {
         // We return nullptr here, which our caller interprets as meaning "use SimpleSrcOverXP".
         // We don't simply return the address of that XP here because our caller would have to unref
         // it and since it is a global object and GrProgramElement's ref-cnting system is not thread
@@ -825,13 +826,13 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
         return nullptr;
     }
 
-    if (analysis.hasKnownOutputColor() && !caps.shaderCaps()->dualSourceBlendingSupport() &&
+    if (color.isConstant() && !caps.shaderCaps()->dualSourceBlendingSupport() &&
         !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.
         SkASSERT(!dstTexture || !dstTexture->texture());
-        return PDLCDXferProcessor::Create(SkBlendMode::kSrcOver, analysis);
+        return PDLCDXferProcessor::Create(SkBlendMode::kSrcOver, color);
     }
 
     BlendFormula blendFormula;
index 81e8261..0d671a3 100644 (file)
@@ -24,7 +24,8 @@ public:
     /** 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 FragmentProcessorAnalysis&,
+                                                       const GrPipelineAnalysisColor& color,
+                                                       GrPipelineAnalysisCoverage coverage,
                                                        bool hasMixedSamples,
                                                        const GrXferProcessor::DstTexture*);
 
@@ -42,9 +43,8 @@ public:
 private:
     constexpr GrPorterDuffXPFactory(SkBlendMode);
 
-    GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
-                                           const FragmentProcessorAnalysis&,
-                                           bool hasMixedSamples,
+    GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysisColor&,
+                                           GrPipelineAnalysisCoverage, bool hasMixedSamples,
                                            const DstTexture*) const override;
 
     AnalysisProperties analysisProperties(const GrPipelineAnalysisColor&,
index d75af35..2550f9d 100644 (file)
@@ -466,6 +466,7 @@ void InstancedRendering::Op::onExecute(GrOpFlushState* state) {
 
     state->gpu()->handleDirtyContext();
 
+    // TODO: Don't reanalyze the processors.
     GrProcessorSet::FragmentProcessorAnalysis analysis;
     GrPipelineAnalysisCoverage coverageInput;
     if (GrAAType::kCoverage == fInfo.aaType() ||
@@ -485,7 +486,8 @@ void InstancedRendering::Op::onExecute(GrOpFlushState* state) {
 
     GrPipeline pipeline;
     GrPipeline::InitArgs args;
-    args.fAnalysis = &analysis;
+    args.fInputColor = analysis.outputColor();
+    args.fInputCoverage = analysis.outputCoverage();
     args.fAppliedClip = clip;
     args.fCaps = &state->caps();
     args.fProcessors = &fProcessors;
index 8a989b0..8bc1f83 100644 (file)
@@ -38,6 +38,7 @@ void GrDrawPathOpBase::initPipeline(const GrOpFlushState& state, GrPipeline* pip
                     0xffff>()
     };
     GrPipeline::InitArgs args;
+    auto analysis = this->fragmentProcessorAnalysis();
     args.fProcessors = &this->processors();
     args.fFlags = GrAA::kYes == fAA ? GrPipeline::kHWAntialias_Flag : 0;
     args.fUserStencil = &kCoverPass;
@@ -45,8 +46,8 @@ void GrDrawPathOpBase::initPipeline(const GrOpFlushState& state, GrPipeline* pip
     args.fRenderTarget = state.drawOpArgs().fRenderTarget;
     args.fCaps = &state.caps();
     args.fDstTexture = state.drawOpArgs().fDstTexture;
-    args.fAnalysis =
-            &this->doFragmentProcessorAnalysis(state.caps(), state.drawOpArgs().fAppliedClip);
+    args.fInputColor = analysis.outputColor();
+    args.fInputCoverage = analysis.outputCoverage();
 
     return pipeline->init(args);
 }
index 5cb9b60..75fa6fc 100644 (file)
@@ -96,11 +96,9 @@ static void construct_dummy_pipeline(GrRenderTargetContext* dc, GrPipeline* pipe
     GrScissorState dummyScissor;
     GrWindowRectsState dummyWindows;
 
-    GrProcessorSet::FragmentProcessorAnalysis analysis;
     GrPipeline::InitArgs args;
     dummyBuilder.getPipelineInitArgs(&args);
     args.fRenderTarget = dc->accessRenderTarget();
-    args.fAnalysis = &analysis;
     args.fCaps = dc->caps();
     args.fDstTexture = GrXferProcessor::DstTexture();
     pipeline->init(args);
index 0170488..9268dd4 100644 (file)
@@ -66,7 +66,8 @@ public:
             fCompatibleWithCoverageAsAlpha = analysis.isCompatibleWithCoverageAsAlpha();
             fCanCombineOverlappedStencilAndCover = analysis.canCombineOverlappedStencilAndCover();
             fIgnoresInputColor = analysis.isInputColorIgnored();
-            sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps));
+            sk_sp<GrXferProcessor> xp(
+                    xpf->createXferProcessor(inputColor, inputCoverage, false, nullptr, caps));
             TEST_ASSERT(!analysis.requiresDstTexture());
             GetXPOutputTypes(xp.get(), &fPrimaryOutputType, &fSecondaryOutputType);
             xp->getBlendInfo(&fBlendInfo);
@@ -987,39 +988,12 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
 }
 
 static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const GrCaps& caps) {
-    class TestLCDCoverageOp : public GrMeshDrawOp {
-    public:
-        DEFINE_OP_CLASS_ID
-
-        TestLCDCoverageOp() : INHERITED(ClassID()) {}
-
-        const char* name() const override { return "Test LCD Text Op"; }
-
-    private:
-        void getFragmentProcessorAnalysisInputs(
-                GrPipelineAnalysisColor* color,
-                GrPipelineAnalysisCoverage* coverage) const override {
-            color->setToConstant(GrColorPackRGBA(123, 45, 67, 221));
-            *coverage = GrPipelineAnalysisCoverage::kLCD;
-        }
-
-        void applyPipelineOptimizations(const PipelineOptimizations&) override {}
-        bool onCombineIfPossible(GrOp*, const GrCaps&) override { return false; }
-        void onPrepareDraws(Target*) const override {}
-
-        typedef GrMeshDrawOp INHERITED;
-    } testLCDCoverageOp;
-
-    GrProcessorSet::FragmentProcessorAnalysis analysis;
-    testLCDCoverageOp.analyzeProcessors(&analysis, GrProcessorSet(GrPaint()), nullptr, caps);
-
-    SkASSERT(analysis.hasKnownOutputColor());
-    SkASSERT(analysis.outputCoverageType() == GrPipelineAnalysisCoverage::kLCD);
-
-    TEST_ASSERT(!analysis.requiresDstTexture());
-
     const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(SkBlendMode::kSrcOver);
-    sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps));
+    GrPipelineAnalysisColor color = GrColorPackRGBA(123, 45, 67, 221);
+    GrPipelineAnalysisCoverage coverage = GrPipelineAnalysisCoverage::kLCD;
+    SkASSERT(!(GrXPFactory::GetAnalysisProperties(xpf, color, coverage, caps) &
+               GrXPFactory::AnalysisProperties::kRequiresDstTexture));
+    sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(color, coverage, false, nullptr, caps));
     if (!xp) {
         ERRORF(reporter, "Failed to create an XP with LCD coverage.");
         return;
@@ -1072,8 +1046,8 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) {
                                                                      caps);
                 GrXferProcessor::DstTexture* dstTexture =
                         analysis.requiresDstTexture() ? &fakeDstTexture : nullptr;
-                sk_sp<GrXferProcessor> xp(
-                        xpf->createXferProcessor(analysis, false, dstTexture, caps));
+                sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(colorInput, coverageType, false,
+                                                                   dstTexture, caps));
                 if (!xp) {
                     ERRORF(reporter, "Failed to create an XP without dual source blending.");
                     return;