diff options
author | 2017-03-28 16:32:05 -0400 | |
---|---|---|
committer | 2017-03-29 13:17:50 +0000 | |
commit | 318538484f99253b6a2acf97d4d1b420e628b289 (patch) | |
tree | a698f31af79a873f16bad8847c50623bb44a19be | |
parent | 02bb6df0819d932a7a7ef8c6fb6914e3c5a0f4a2 (diff) |
Remove GrXferProcessor::getOptimizations.
This replaces GrXferProcessor::getOptimizations with a new function on GrXPFactory. The results are made available via FragmentProcessorAnalysis.
Bug: skia:
Change-Id: I535985458c9d13ad858cac94e957e2fdbe332036
Reviewed-on: https://skia-review.googlesource.com/10218
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
-rw-r--r-- | include/gpu/GrBlend.h | 6 | ||||
-rw-r--r-- | src/gpu/GrPipeline.cpp | 47 | ||||
-rw-r--r-- | src/gpu/GrPipelineAnalysis.h | 6 | ||||
-rw-r--r-- | src/gpu/GrPipelineBuilder.h | 14 | ||||
-rw-r--r-- | src/gpu/GrProcessorSet.cpp | 50 | ||||
-rw-r--r-- | src/gpu/GrProcessorSet.h | 20 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrXferProcessor.cpp | 41 | ||||
-rw-r--r-- | src/gpu/GrXferProcessor.h | 74 | ||||
-rw-r--r-- | src/gpu/effects/GrCoverageSetOpXP.cpp | 8 | ||||
-rw-r--r-- | src/gpu/effects/GrCoverageSetOpXP.h | 7 | ||||
-rw-r--r-- | src/gpu/effects/GrCustomXfermode.cpp | 141 | ||||
-rw-r--r-- | src/gpu/effects/GrDisableColorXP.cpp | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrDisableColorXP.h | 9 | ||||
-rw-r--r-- | src/gpu/effects/GrPorterDuffXferProcessor.cpp | 140 | ||||
-rw-r--r-- | src/gpu/effects/GrPorterDuffXferProcessor.h | 16 | ||||
-rw-r--r-- | src/gpu/instanced/InstancedRendering.cpp | 7 | ||||
-rw-r--r-- | src/gpu/ops/GrDrawPathOp.cpp | 8 | ||||
-rw-r--r-- | src/gpu/ops/GrDrawPathOp.h | 3 | ||||
-rw-r--r-- | tests/GrPorterDuffTest.cpp | 325 |
20 files changed, 441 insertions, 487 deletions
diff --git a/include/gpu/GrBlend.h b/include/gpu/GrBlend.h index 5100bb0539..97a516650e 100644 --- a/include/gpu/GrBlend.h +++ b/include/gpu/GrBlend.h @@ -212,6 +212,9 @@ struct GrTBlendModifiesDst : skstd::bool_constant< * * By inspection we can see this will work as long as dstCoeff has a 1, and any other term in * dstCoeff references S. + * + * Moreover, if the blend doesn't modify the dst at all then it is ok to arbitrarily modify the src + * color so folding in coverage is allowed. */ template<GrBlendEquation Equation, GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff> struct GrTBlendCanTweakAlphaForCoverage : skstd::bool_constant< @@ -220,7 +223,8 @@ struct GrTBlendCanTweakAlphaForCoverage : skstd::bool_constant< !GR_BLEND_COEFF_REFS_SRC(SrcCoeff) && (kOne_GrBlendCoeff == DstCoeff || kISC_GrBlendCoeff == DstCoeff || - kISA_GrBlendCoeff == DstCoeff))> {}; + kISA_GrBlendCoeff == DstCoeff)) || + !GrTBlendModifiesDst<Equation, SrcCoeff, DstCoeff>::value> {}; #define GR_BLEND_CAN_TWEAK_ALPHA_FOR_COVERAGE(EQUATION, SRC_COEFF, DST_COEFF) \ GrTBlendCanTweakAlphaForCoverage<EQUATION, SRC_COEFF, DST_COEFF>::value diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp index adcdd0fe02..d8f7fbdbf8 100644 --- a/src/gpu/GrPipeline.cpp +++ b/src/gpu/GrPipeline.cpp @@ -52,37 +52,32 @@ GrPipelineOptimizations GrPipeline::init(const InitArgs& args) { bool isHWAA = kHWAntialias_Flag & args.fFlags; // Create XferProcessor from DS's XPFactory - bool hasMixedSamples = args.fRenderTarget->isMixedSampled() && (isHWAA || isStencilEnabled()); - const GrXPFactory* xpFactory = args.fProcessors->xpFactory(); - sk_sp<GrXferProcessor> xferProcessor; - if (xpFactory) { - xferProcessor.reset(xpFactory->createXferProcessor(*args.fAnalysis, 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)); + { + 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.fAnalysis, 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)); + } + 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); - - GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags; - - const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() : - &GrPorterDuffXPFactory::SimpleSrcOverXP(); - optFlags = xpForOpts->getOptimizations(*args.fAnalysis); - - // No need to have an override color if it isn't even going to be used. - if (SkToBool(GrXferProcessor::kIgnoreColor_OptFlag & optFlags)) { + if (args.fAnalysis->isInputColorIgnored()) { + // No need to have an override color if it isn't even going to be used. overrideColor = GrColor_ILLEGAL; - } - - fXferProcessor.reset(xferProcessor.get()); - - if ((optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) { colorFPsToEliminate = args.fProcessors->numColorFragmentProcessors(); } @@ -122,7 +117,7 @@ GrPipelineOptimizations GrPipeline::init(const InitArgs& args) { if (args.fAnalysis->usesLocalCoords()) { optimizations.fFlags |= GrPipelineOptimizations::kReadsLocalCoords_Flag; } - if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) { + if (args.fAnalysis->isCompatibleWithCoverageAsAlpha()) { optimizations.fFlags |= GrPipelineOptimizations::kCanTweakAlphaForCoverage_Flag; } return optimizations; diff --git a/src/gpu/GrPipelineAnalysis.h b/src/gpu/GrPipelineAnalysis.h index 4f553b0ce5..d55ff0a34c 100644 --- a/src/gpu/GrPipelineAnalysis.h +++ b/src/gpu/GrPipelineAnalysis.h @@ -41,9 +41,11 @@ public: bool isOpaque() const { return SkToBool(kIsOpaque_Flag & fFlags); } - bool isConstant(GrColor* color) const { + bool isConstant(GrColor* color = nullptr) const { if (kColorIsKnown_Flag & fFlags) { - *color = fColor; + if (color) { + *color = fColor; + } return true; } return false; diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index 17dfe90ddd..7451b655b1 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -65,20 +65,6 @@ public: /// @} - /////////////////////////////////////////////////////////////////////////// - /// @name Blending - //// - - /** - * Checks whether the xp will need destination in a texture to correctly blend. - */ - bool willXPNeedDstTexture(const GrCaps& caps, - const GrProcessorSet::FragmentProcessorAnalysis& analysis) const { - return GrXPFactory::WillNeedDstTexture(fProcessors.xpFactory(), caps, analysis); - } - - /// @} - /////////////////////////////////////////////////////////////////////////// /// @name Stencil diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp index 4a508921b1..0350ba5758 100644 --- a/src/gpu/GrProcessorSet.cpp +++ b/src/gpu/GrProcessorSet.cpp @@ -9,6 +9,7 @@ #include "GrAppliedClip.h" #include "GrCaps.h" #include "GrPipelineAnalysis.h" +#include "GrXferProcessor.h" GrProcessorSet::GrProcessorSet(GrPaint&& paint) { fXPFactory = paint.fXPFactory; @@ -97,7 +98,7 @@ void GrProcessorSet::FragmentProcessorAnalysis::internalInit( fps += processors.fColorFragmentProcessorCnt; int n = processors.numCoverageFragmentProcessors(); bool hasCoverageFP = n > 0; - fUsesLocalCoords = colorInfo.usesLocalCoords(); + bool coverageUsesLocalCoords = false; for (int i = 0; i < n; ++i) { if (!fps[i]->compatibleWithCoverageAsAlpha()) { fCompatibleWithCoverageAsAlpha = false; @@ -105,12 +106,12 @@ void GrProcessorSet::FragmentProcessorAnalysis::internalInit( // compatible with the coverage-as-alpha optimization. GrCapsDebugf(&caps, "Coverage FP is not compatible with coverage as alpha.\n"); } - fUsesLocalCoords |= fps[i]->usesLocalCoords(); + coverageUsesLocalCoords |= fps[i]->usesLocalCoords(); } if (clipFP) { fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha(); - fUsesLocalCoords |= clipFP->usesLocalCoords(); + coverageUsesLocalCoords |= clipFP->usesLocalCoords(); hasCoverageFP = true; } fInitialColorProcessorsToEliminate = colorInfo.initialProcessorsToEliminate(&fInputColor); @@ -126,12 +127,44 @@ void GrProcessorSet::FragmentProcessorAnalysis::internalInit( fOutputColorType = static_cast<unsigned>(ColorType::kUnknown); } + GrPipelineAnalysisCoverage outputCoverage; if (GrPipelineAnalysisCoverage::kLCD == coverageInput) { - fOutputCoverageType = static_cast<unsigned>(GrPipelineAnalysisCoverage::kLCD); + outputCoverage = GrPipelineAnalysisCoverage::kLCD; } else if (hasCoverageFP || GrPipelineAnalysisCoverage::kSingleChannel == coverageInput) { - fOutputCoverageType = static_cast<unsigned>(GrPipelineAnalysisCoverage::kSingleChannel); + outputCoverage = GrPipelineAnalysisCoverage::kSingleChannel; } else { - fOutputCoverageType = static_cast<unsigned>(GrPipelineAnalysisCoverage::kNone); + outputCoverage = GrPipelineAnalysisCoverage::kNone; + } + fOutputCoverageType = static_cast<unsigned>(outputCoverage); + + GrXPFactory::AnalysisProperties props = GrXPFactory::GetAnalysisProperties( + processors.fXPFactory, colorInfo.outputColor(), outputCoverage, caps); + if (!processors.numCoverageFragmentProcessors() && + GrPipelineAnalysisCoverage::kNone == coverageInput) { + fCanCombineOverlappedStencilAndCover = SkToBool( + props & GrXPFactory::AnalysisProperties::kCanCombineOverlappedStencilAndCover); + } else { + // If we have non-clipping coverage processors we don't try to merge stencil steps as its + // unclear whether it will be correct. We don't expect this to happen in practice. + fCanCombineOverlappedStencilAndCover = false; + } + fRequiresDstTexture = SkToBool(props & GrXPFactory::AnalysisProperties::kRequiresDstTexture); + fIgnoresInputColor = SkToBool(props & GrXPFactory::AnalysisProperties::kIgnoresInputColor); + fCompatibleWithCoverageAsAlpha &= + SkToBool(props & GrXPFactory::AnalysisProperties::kCompatibleWithAlphaAsCoverage); + if (props & GrXPFactory::AnalysisProperties::kIgnoresInputColor) { + fInitialColorProcessorsToEliminate = processors.numColorFragmentProcessors(); + // If the output of the last color stage is known then the kIgnoresInputColor optimization + // may depend upon it being the input to the xp. + if (!outputColor.isConstant(&fInputColor)) { + // Otherwise, the only property the XP factory could have relied upon to compute + // kIgnoresInputColor is opaqueness. + fInputColor = GrColor_WHITE; + } + fValidInputColor = true; + fUsesLocalCoords = coverageUsesLocalCoords; + } else { + fUsesLocalCoords = coverageUsesLocalCoords | colorInfo.usesLocalCoords(); } } @@ -149,9 +182,12 @@ void GrProcessorSet::FragmentProcessorAnalysis::init(const GrPipelineAnalysisCol GrProcessorSet::FragmentProcessorAnalysis::FragmentProcessorAnalysis( const GrPipelineAnalysisColor& colorInput, const GrPipelineAnalysisCoverage coverageInput, + const GrXPFactory* factory, const GrCaps& caps) : FragmentProcessorAnalysis() { - this->internalInit(colorInput, coverageInput, GrProcessorSet(GrPaint()), nullptr, caps); + GrPaint paint; + paint.setXPFactory(factory); + this->internalInit(colorInput, coverageInput, GrProcessorSet(std::move(paint)), nullptr, caps); } void GrProcessorSet::analyzeAndEliminateFragmentProcessors( diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h index bfad769a18..e584a94709 100644 --- a/src/gpu/GrProcessorSet.h +++ b/src/gpu/GrProcessorSet.h @@ -79,13 +79,16 @@ public: : fIsInitializedWithProcessorSet(false) , fCompatibleWithCoverageAsAlpha(true) , fValidInputColor(false) + , fRequiresDstTexture(false) + , fCanCombineOverlappedStencilAndCover(true) + , fIgnoresInputColor(false) , fOutputCoverageType(static_cast<unsigned>(GrPipelineAnalysisCoverage::kNone)) , fOutputColorType(static_cast<unsigned>(ColorType::kUnknown)) , fInitialColorProcessorsToEliminate(0) {} - // This version is used by a unit test that assumes no clip, no processors, and no PLS. + // This version is used by a unit test that assumes no clip and no fragment processors. FragmentProcessorAnalysis(const GrPipelineAnalysisColor&, GrPipelineAnalysisCoverage, - const GrCaps&); + const GrXPFactory*, const GrCaps&); void init(const GrPipelineAnalysisColor&, GrPipelineAnalysisCoverage, const GrProcessorSet&, const GrAppliedClip*, const GrCaps&); @@ -119,7 +122,12 @@ public: } bool usesLocalCoords() const { return fUsesLocalCoords; } + bool requiresDstTexture() const { return fRequiresDstTexture; } + bool canCombineOverlappedStencilAndCover() const { + return fCanCombineOverlappedStencilAndCover; + } bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; } + bool isInputColorIgnored() const { return fIgnoresInputColor; } bool isOutputColorOpaque() const { return ColorType::kOpaque == this->outputColorType() || ColorType::kOpaqueConstant == this->outputColorType(); @@ -154,11 +162,17 @@ public: PackedBool fUsesLocalCoords : 1; PackedBool fCompatibleWithCoverageAsAlpha : 1; PackedBool fValidInputColor : 1; + PackedBool fRequiresDstTexture : 1; + PackedBool fCanCombineOverlappedStencilAndCover : 1; + // These could be removed if we created the XP from the XPFactory when doing analysis. + PackedBool fIgnoresInputColor : 1; unsigned fOutputCoverageType : 2; unsigned fOutputColorType : 2; - unsigned fInitialColorProcessorsToEliminate : 32 - 8; + + unsigned fInitialColorProcessorsToEliminate : 32 - 11; GrColor fInputColor; + // This could be removed if we created the XP from the XPFactory when doing analysis. GrColor fKnownOutputColor; friend class GrProcessorSet; diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 70d4485468..79ae757b34 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -1743,7 +1743,7 @@ uint32_t GrRenderTargetContext::addMeshDrawOp(const GrPipelineBuilder& pipelineB args.fCaps = this->caps(); args.fAnalysis = &analysis; - if (pipelineBuilder.willXPNeedDstTexture(*this->caps(), analysis)) { + if (analysis.requiresDstTexture()) { this->setupDstTexture(rt, clip, bounds, &args.fDstTexture); if (!args.fDstTexture.texture()) { return SK_InvalidUniqueID; diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp index bd63a0a40b..45bcc2d595 100644 --- a/src/gpu/GrXferProcessor.cpp +++ b/src/gpu/GrXferProcessor.cpp @@ -29,11 +29,6 @@ GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture, } } -GrXferProcessor::OptFlags GrXferProcessor::getOptimizations( - const FragmentProcessorAnalysis& analysis) const { - return this->onGetOptimizations(analysis); -} - bool GrXferProcessor::hasSecondaryOutput() const { if (!this->willReadDstColor()) { return this->onHasSecondaryOutput(); @@ -175,31 +170,23 @@ SkString GrXferProcessor::BlendInfo::dump() const { /////////////////////////////////////////////////////////////////////////////// -bool GrXPFactory::WillNeedDstTexture(const GrXPFactory* factory, const GrCaps& caps, - const GrProcessorSet::FragmentProcessorAnalysis& analysis) { - bool result; +GrXPFactory::AnalysisProperties GrXPFactory::GetAnalysisProperties( + const GrXPFactory* factory, + const GrPipelineAnalysisColor& color, + const GrPipelineAnalysisCoverage& coverage, + const GrCaps& caps) { + AnalysisProperties result; if (factory) { - result = !caps.shaderCaps()->dstReadInShaderSupport() && - factory->willReadDstInShader(caps, analysis); + result = factory->analysisProperties(color, coverage, caps); } else { - result = GrPorterDuffXPFactory::WillSrcOverNeedDstTexture(caps, analysis); + result = GrPorterDuffXPFactory::SrcOverAnalysisProperties(color, coverage, caps); } - return result; -} - -bool GrXPFactory::CompatibleWithCoverageAsAlpha(const GrXPFactory* factory, bool colorIsOpaque) { - if (factory) { - return factory->compatibleWithCoverageAsAlpha(colorIsOpaque); + SkASSERT(!(result & AnalysisProperties::kRequiresDstTexture)); + if ((result & AnalysisProperties::kReadsDstInShader) && + !caps.shaderCaps()->dstReadInShaderSupport()) { + result |= AnalysisProperties::kRequiresDstTexture; } - return GrPorterDuffXPFactory::SrcOverIsCompatibleWithCoverageAsAlpha(); -} - -bool GrXPFactory::CanCombineOverlappedStencilAndCover(const GrXPFactory* factory, - bool colorIsOpaque) { - if (factory) { - return factory->canCombineOverlappedStencilAndCover(colorIsOpaque); - } - return GrPorterDuffXPFactory::SrcOverCanCombineOverlappedStencilAndCover(colorIsOpaque); + return result; } GrXferProcessor* GrXPFactory::createXferProcessor(const FragmentProcessorAnalysis& analysis, @@ -207,7 +194,7 @@ GrXferProcessor* GrXPFactory::createXferProcessor(const FragmentProcessorAnalysi const DstTexture* dstTexture, const GrCaps& caps) const { #ifdef SK_DEBUG - if (this->willReadDstInShader(caps, analysis)) { + if (analysis.requiresDstTexture()) { if (!caps.shaderCaps()->dstReadInShaderSupport()) { SkASSERT(dstTexture && dstTexture->texture()); } else { diff --git a/src/gpu/GrXferProcessor.h b/src/gpu/GrXferProcessor.h index bdf6f7d50c..54630af750 100644 --- a/src/gpu/GrXferProcessor.h +++ b/src/gpu/GrXferProcessor.h @@ -108,32 +108,6 @@ public: virtual GrGLSLXferProcessor* createGLSLInstance() const = 0; /** - * Optimizations for blending / coverage that an OptDrawState should apply to itself. - */ - enum OptFlags { - /** - * GrXferProcessor will ignore color, thus no need to provide - */ - kIgnoreColor_OptFlag = 0x1, - /** - * Can tweak alpha for coverage. - */ - kCanTweakAlphaForCoverage_OptFlag = 0x2, - }; - - static const OptFlags kNone_OptFlags = (OptFlags)0; - - GR_DECL_BITFIELD_OPS_FRIENDS(OptFlags); - - /** - * Determines which optimizations (as described by the ptFlags above) can be performed by - * the draw with this xfer processor. If this function is called, the xfer processor may change - * its state to reflected the given blend optimizations. Callers are required to honor the - * returned OptFlags. - */ - OptFlags getOptimizations(const FragmentProcessorAnalysis&) const; - - /** * Returns whether this XP will require an Xfer barrier on the given rt. If true, outBarrierType * is updated to contain the type of barrier needed. */ @@ -224,8 +198,6 @@ protected: private: void notifyRefCntIsZero() const final {} - virtual OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const = 0; - /** * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer * processor's GL backend implementation. @@ -265,10 +237,6 @@ private: typedef GrFragmentProcessor INHERITED; }; -GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags); - -/////////////////////////////////////////////////////////////////////////////// - /** * We install a GrXPFactory (XPF) early on in the pipeline before all the final draw information is * known (e.g. whether there is fractional pixel coverage, will coverage be 1 or 4 channel, is the @@ -305,22 +273,20 @@ public: const DstTexture*, const GrCaps& caps) const; - /** - * This will return true if the xfer processor needs the dst color in the shader and the way - * that the color will be made available to the xfer processor is by sampling a texture. - */ - static bool WillNeedDstTexture(const GrXPFactory*, - const GrCaps&, - const FragmentProcessorAnalysis&); + enum class AnalysisProperties : unsigned { + kNone = 0x0, + kReadsDstInShader = 0x1, + kRequiresDstTexture = 0x2, + kCompatibleWithAlphaAsCoverage = 0x4, + kIgnoresInputColor = 0x8, + kCanCombineOverlappedStencilAndCover = 0x10 + }; + GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(AnalysisProperties); - static bool CompatibleWithCoverageAsAlpha(const GrXPFactory*, bool colorIsOpaque); - - /** - * This indicates whether the the xfer processor will produce the same bleneded color result - * if a series of overlapping stencil and cover operations are replaced by a series of stencil - * operations and a single cover. A uniform src color is assumed. - **/ - static bool CanCombineOverlappedStencilAndCover(const GrXPFactory*, bool colorIsOpaque); + static AnalysisProperties GetAnalysisProperties(const GrXPFactory*, + const GrPipelineAnalysisColor&, + const GrPipelineAnalysisCoverage&, + const GrCaps&); protected: constexpr GrXPFactory() {} @@ -332,17 +298,17 @@ private: const DstTexture*) const = 0; /** - * Returns true if the XP generated by this factory will explicitly read dst in the fragment - * shader. + * Subclass analysis implementation. This should not return kNeedsDstInTexture as that will be + * inferred by the base class based on kReadsDstInShader and the caps. */ - virtual bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const = 0; - - virtual bool compatibleWithCoverageAsAlpha(bool colorIsOpaque) const = 0; - virtual bool canCombineOverlappedStencilAndCover(bool colorIsOpaque) const { return false; } + virtual AnalysisProperties analysisProperties(const GrPipelineAnalysisColor&, + const GrPipelineAnalysisCoverage&, + const GrCaps&) const = 0; }; #if defined(__GNUC__) || defined(__clang) #pragma GCC diagnostic pop #endif -#endif +GR_MAKE_BITFIELD_CLASS_OPS(GrXPFactory::AnalysisProperties); +#endif diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp index 1013706842..84219aef11 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.cpp +++ b/src/gpu/effects/GrCoverageSetOpXP.cpp @@ -33,8 +33,6 @@ public: private: CoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage); - GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override; - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override; @@ -103,12 +101,6 @@ GrGLSLXferProcessor* CoverageSetOpXP::createGLSLInstance() const { return new GLCoverageSetOpXP(*this); } -GrXferProcessor::OptFlags CoverageSetOpXP::onGetOptimizations( - const FragmentProcessorAnalysis&) const { - // We never look at the color input - return GrXferProcessor::kIgnoreColor_OptFlag; -} - void CoverageSetOpXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const { switch (fRegionOp) { case SkRegion::kReplace_Op: diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h index a0cb0c518c..b7239f3a19 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.h +++ b/src/gpu/effects/GrCoverageSetOpXP.h @@ -35,11 +35,12 @@ private: bool hasMixedSamples, const DstTexture*) const override; - bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override { - return false; + AnalysisProperties analysisProperties(const GrPipelineAnalysisColor&, + const GrPipelineAnalysisCoverage&, + const GrCaps&) const override { + return AnalysisProperties::kIgnoresInputColor; } - bool compatibleWithCoverageAsAlpha(bool colorIsOpaque) const override { return false; } GR_DECLARE_XP_FACTORY_TEST; diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index 1f2771cb52..2e6d27cdfa 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -98,8 +98,6 @@ public: } private: - GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override; - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; GrXferBarrierType onXferBarrier(const GrRenderTarget*, const GrCaps&) const override; @@ -189,11 +187,68 @@ bool CustomXP::onIsEqual(const GrXferProcessor& other) const { return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation; } -GrXferProcessor::OptFlags CustomXP::onGetOptimizations( - const FragmentProcessorAnalysis& analysis) const { - /* - Most the optimizations we do here are based on tweaking alpha for coverage. +GrXferBarrierType CustomXP::onXferBarrier(const GrRenderTarget* rt, const GrCaps& caps) const { + if (this->hasHWBlendEquation() && !caps.advancedCoherentBlendEquationSupport()) { + return kBlend_GrXferBarrierType; + } + return kNone_GrXferBarrierType; +} +void CustomXP::onGetBlendInfo(BlendInfo* blendInfo) const { + if (this->hasHWBlendEquation()) { + blendInfo->fEquation = this->hwBlendEquation(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +// See the comment above GrXPFactory's definition about this warning suppression. +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#endif +class CustomXPFactory : public GrXPFactory { +public: + constexpr CustomXPFactory(SkBlendMode mode) + : fMode(mode), fHWBlendEquation(hw_blend_equation(mode)) {} + +private: + GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, + const FragmentProcessorAnalysis&, + bool hasMixedSamples, + const DstTexture*) const override; + + AnalysisProperties analysisProperties(const GrPipelineAnalysisColor&, + const GrPipelineAnalysisCoverage&, + const GrCaps&) const override; + + GR_DECLARE_XP_FACTORY_TEST; + + SkBlendMode fMode; + GrBlendEquation fHWBlendEquation; + + typedef GrXPFactory INHERITED; +}; +#if defined(__GNUC__) || defined(__clang) +#pragma GCC diagnostic pop +#endif + +GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps, + const FragmentProcessorAnalysis& analysis, + bool hasMixedSamples, + const DstTexture* dstTexture) const { + SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); + if (can_use_hw_blend_equation(fHWBlendEquation, analysis.outputCoverageType(), caps)) { + SkASSERT(!dstTexture || !dstTexture->texture()); + return new CustomXP(fMode, fHWBlendEquation); + } + return new CustomXP(dstTexture, hasMixedSamples, fMode); +} + +GrXPFactory::AnalysisProperties CustomXPFactory::analysisProperties( + const GrPipelineAnalysisColor&, const GrPipelineAnalysisCoverage& coverage, + const GrCaps& caps) const { + /* The general SVG blend equation is defined in the spec as follows: Dca' = B(Sc, Dc) * Sa * Da + Y * Sca * (1-Da) + Z * Dca * (1-Sa) @@ -287,76 +342,12 @@ GrXferProcessor::OptFlags CustomXP::onGetOptimizations( = f*Sa - f*Sa * Da + Da = f*Sa + Da - f*Sa * Da = blend(f*Sa, Da) - */ - - OptFlags flags = kNone_OptFlags; - if (analysis.isCompatibleWithCoverageAsAlpha()) { - flags |= kCanTweakAlphaForCoverage_OptFlag; + */ + if (can_use_hw_blend_equation(fHWBlendEquation, coverage, caps)) { + return AnalysisProperties::kCompatibleWithAlphaAsCoverage; } - return flags; -} - -GrXferBarrierType CustomXP::onXferBarrier(const GrRenderTarget* rt, const GrCaps& caps) const { - if (this->hasHWBlendEquation() && !caps.advancedCoherentBlendEquationSupport()) { - return kBlend_GrXferBarrierType; - } - return kNone_GrXferBarrierType; -} - -void CustomXP::onGetBlendInfo(BlendInfo* blendInfo) const { - if (this->hasHWBlendEquation()) { - blendInfo->fEquation = this->hwBlendEquation(); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -// See the comment above GrXPFactory's definition about this warning suppression. -#if defined(__GNUC__) || defined(__clang) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#endif -class CustomXPFactory : public GrXPFactory { -public: - constexpr CustomXPFactory(SkBlendMode mode) - : fMode(mode), fHWBlendEquation(hw_blend_equation(mode)) {} - -private: - GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, - const FragmentProcessorAnalysis&, - bool hasMixedSamples, - const DstTexture*) const override; - - bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override; - - bool compatibleWithCoverageAsAlpha(bool colorIsOpaque) const override { return true; } - - GR_DECLARE_XP_FACTORY_TEST; - - SkBlendMode fMode; - GrBlendEquation fHWBlendEquation; - - typedef GrXPFactory INHERITED; -}; -#if defined(__GNUC__) || defined(__clang) -#pragma GCC diagnostic pop -#endif - -GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps, - const FragmentProcessorAnalysis& analysis, - bool hasMixedSamples, - const DstTexture* dstTexture) const { - SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); - if (can_use_hw_blend_equation(fHWBlendEquation, analysis.outputCoverageType(), caps)) { - SkASSERT(!dstTexture || !dstTexture->texture()); - return new CustomXP(fMode, fHWBlendEquation); - } - return new CustomXP(dstTexture, hasMixedSamples, fMode); -} - -bool CustomXPFactory::willReadDstInShader(const GrCaps& caps, - const FragmentProcessorAnalysis& analysis) const { - return !can_use_hw_blend_equation(fHWBlendEquation, analysis.outputCoverageType(), caps); + return AnalysisProperties::kCompatibleWithAlphaAsCoverage | + AnalysisProperties::kReadsDstInShader; } GR_DEFINE_XP_FACTORY_TEST(CustomXPFactory); diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp index f95cd9b81a..226809725c 100644 --- a/src/gpu/effects/GrDisableColorXP.cpp +++ b/src/gpu/effects/GrDisableColorXP.cpp @@ -29,10 +29,6 @@ public: private: DisableColorXP(); - GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override { - return GrXferProcessor::kIgnoreColor_OptFlag; - } - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override; diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h index 821ad2768e..9a829ed5ba 100644 --- a/src/gpu/effects/GrDisableColorXP.h +++ b/src/gpu/effects/GrDisableColorXP.h @@ -24,12 +24,13 @@ public: private: constexpr GrDisableColorXPFactory() {} - bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override { - return false; + AnalysisProperties analysisProperties(const GrPipelineAnalysisColor&, + const GrPipelineAnalysisCoverage&, + const GrCaps&) const override { + return AnalysisProperties::kCompatibleWithAlphaAsCoverage | + AnalysisProperties::kIgnoresInputColor; } - bool compatibleWithCoverageAsAlpha(bool colorIsOpaque) const override { return true; } - GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const FragmentProcessorAnalysis&, bool hasMixedSamples, diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index aa416e0d1b..98268a2c5f 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -83,7 +83,7 @@ public: (SecondaryOut >= kModulate_OutputType && GR_BLEND_COEFF_REFS_SRC2(DstCoeff)) ? kUsesInputColor_Property : 0) | // We assert later that SrcCoeff doesn't ref src2. - (kModulate_OutputType == PrimaryOut && + ((kModulate_OutputType == PrimaryOut || kNone_OutputType == PrimaryOut) && kNone_OutputType == SecondaryOut && GR_BLEND_CAN_TWEAK_ALPHA_FOR_COVERAGE(BlendEquation, SrcCoeff, DstCoeff) ? kCanTweakAlphaForCoverage_Property : 0))> { @@ -349,8 +349,6 @@ public: BlendFormula getBlendFormula() const { return fBlendFormula; } private: - GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override; - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; bool onHasSecondaryOutput() const override { return fBlendFormula.hasSecondaryOutput(); } @@ -445,24 +443,6 @@ GrGLSLXferProcessor* PorterDuffXferProcessor::createGLSLInstance() const { return new GLPorterDuffXferProcessor; } -GrXferProcessor::OptFlags PorterDuffXferProcessor::onGetOptimizations( - const FragmentProcessorAnalysis& analysis) const { - GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags; - if (!fBlendFormula.modifiesDst()) { - optFlags |= (GrXferProcessor::kIgnoreColor_OptFlag | - GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag); - } else { - if (!fBlendFormula.usesInputColor()) { - optFlags |= GrXferProcessor::kIgnoreColor_OptFlag; - } - if (analysis.isCompatibleWithCoverageAsAlpha() && - fBlendFormula.canTweakAlphaForCoverage()) { - optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag; - } - } - return optFlags; -} - /////////////////////////////////////////////////////////////////////////////// class ShaderPDXferProcessor : public GrXferProcessor { @@ -482,10 +462,6 @@ public: SkBlendMode getXfermode() const { return fXfermode; } private: - GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override { - return kNone_OptFlags; - } - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; bool onIsEqual(const GrXferProcessor& xpBase) const override { @@ -558,8 +534,6 @@ public: private: PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha); - GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&) const override; - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { @@ -655,11 +629,6 @@ GrGLSLXferProcessor* PDLCDXferProcessor::createGLSLInstance() const { return new GLPDLCDXferProcessor(*this); } -GrXferProcessor::OptFlags PDLCDXferProcessor::onGetOptimizations( - const FragmentProcessorAnalysis&) const { - return GrXferProcessor::kIgnoreColor_OptFlag; -} - /////////////////////////////////////////////////////////////////////////////// constexpr GrPorterDuffXPFactory::GrPorterDuffXPFactory(SkBlendMode xfermode) @@ -758,42 +727,53 @@ GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor( return new PorterDuffXferProcessor(blendFormula); } -bool GrPorterDuffXPFactory::canCombineOverlappedStencilAndCover(bool colorIsOpaque) const { - // Ignore the effect of coverage here. - BlendFormula colorFormula = gBlendTable[colorIsOpaque][0][(int)fBlendMode]; - SkASSERT(kAdd_GrBlendEquation == colorFormula.fBlendEquation); - return !colorFormula.usesDstColor(); -} - -bool GrPorterDuffXPFactory::willReadDstInShader(const GrCaps& caps, - const FragmentProcessorAnalysis& analysis) const { - if (caps.shaderCaps()->dualSourceBlendingSupport()) { - return false; - } - - // When we have four channel coverage we always need to read the dst in order to correctly - // blend. The one exception is when we are using srcover mode and we know the input color into - // the XP. - if (analysis.outputCoverageType() == GrPipelineAnalysisCoverage::kLCD) { - if (SkBlendMode::kSrcOver == fBlendMode && analysis.hasKnownOutputColor() && - !caps.shaderCaps()->dstReadInShaderSupport()) { - return false; +static inline GrXPFactory::AnalysisProperties analysis_properties( + const GrPipelineAnalysisColor& color, const GrPipelineAnalysisCoverage& coverage, + const GrCaps& caps, SkBlendMode mode) { + using AnalysisProperties = GrXPFactory::AnalysisProperties; + AnalysisProperties props = AnalysisProperties::kNone; + bool hasCoverage = GrPipelineAnalysisCoverage::kNone != coverage; + auto formula = gBlendTable[color.isOpaque()][hasCoverage][(int)mode]; + if (formula.canTweakAlphaForCoverage()) { + props |= AnalysisProperties::kCompatibleWithAlphaAsCoverage; + } + // With dual-source blending we never need the destination color in the shader. + if (!caps.shaderCaps()->dualSourceBlendingSupport()) { + // Mixed samples implicity computes a fractional coverage from sample coverage. This could + // affect the formula used. However, we don't expect to have mixed samples without dual + // source blending. + SkASSERT(!caps.usesMixedSamples()); + if (GrPipelineAnalysisCoverage::kLCD == coverage) { + // Check for special case of srcover with a known color which can be done using the + // blend constant. + if (SkBlendMode::kSrcOver == mode && color.isConstant()) { + props |= AnalysisProperties::kIgnoresInputColor; + } else { + if (get_lcd_blend_formula(mode).hasSecondaryOutput()) { + props |= AnalysisProperties::kReadsDstInShader; + } + } + } else if (formula.hasSecondaryOutput()) { + props |= AnalysisProperties::kReadsDstInShader; } - return get_lcd_blend_formula(fBlendMode).hasSecondaryOutput(); } - - // We fallback on the shader XP when the blend formula would use dual source blending but we - // don't have support for it. - static const bool kHasMixedSamples = false; - SkASSERT(!caps.usesMixedSamples()); // We never use mixed samples without dual source blending. - auto formula = get_blend_formula(analysis.isOutputColorOpaque(), analysis.hasCoverage(), - kHasMixedSamples, fBlendMode); - return formula.hasSecondaryOutput(); + if (!formula.modifiesDst() || !formula.usesInputColor()) { + props |= AnalysisProperties::kIgnoresInputColor; + } + // Ignore the effect of coverage here for overlap stencil and cover property + auto colorFormula = gBlendTable[color.isOpaque()][0][(int)mode]; + SkASSERT(kAdd_GrBlendEquation == colorFormula.fBlendEquation); + if (!colorFormula.usesDstColor()) { + props |= AnalysisProperties::kCanCombineOverlappedStencilAndCover; + } + return props; } -bool GrPorterDuffXPFactory::compatibleWithCoverageAsAlpha(bool colorIsOpaque) const { - // We assume we have coverage (or else this doesn't matter). - return gBlendTable[colorIsOpaque][1][(int)fBlendMode].canTweakAlphaForCoverage(); +GrXPFactory::AnalysisProperties GrPorterDuffXPFactory::analysisProperties( + const GrPipelineAnalysisColor& color, + const GrPipelineAnalysisCoverage& coverage, + const GrCaps& caps) const { + return analysis_properties(color, coverage, caps, fBlendMode); } GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); @@ -869,31 +849,9 @@ sk_sp<GrXferProcessor> GrPorterDuffXPFactory::CreateNoCoverageXP(SkBlendMode ble return sk_make_sp<PorterDuffXferProcessor>(formula); } -bool GrPorterDuffXPFactory::WillSrcOverNeedDstTexture(const GrCaps& caps, - const FragmentProcessorAnalysis& analysis) { - if (caps.shaderCaps()->dstReadInShaderSupport() || - caps.shaderCaps()->dualSourceBlendingSupport()) { - return false; - } - - // When we have four channel coverage we always need to read the dst in order to correctly - // blend. The one exception is when we are using srcover mode and we know the input color - // into the XP. - if (analysis.outputCoverageType() == GrPipelineAnalysisCoverage::kLCD) { - if (analysis.hasKnownOutputColor() && !caps.shaderCaps()->dstReadInShaderSupport()) { - return false; - } - auto formula = get_lcd_blend_formula(SkBlendMode::kSrcOver); - return formula.hasSecondaryOutput(); - } - - // We fallback on the shader XP when the blend formula would use dual source blending but we - // don't have support for it. - static const bool kHasMixedSamples = false; - bool isOpaque = analysis.isOutputColorOpaque(); - bool hasCoverage = analysis.hasCoverage(); - SkASSERT(!caps.usesMixedSamples()); // We never use mixed samples without dual source blending. - auto formula = - get_blend_formula(isOpaque, hasCoverage, kHasMixedSamples, SkBlendMode::kSrcOver); - return formula.hasSecondaryOutput(); +GrXPFactory::AnalysisProperties GrPorterDuffXPFactory::SrcOverAnalysisProperties( + const GrPipelineAnalysisColor& color, + const GrPipelineAnalysisCoverage& coverage, + const GrCaps& caps) { + return analysis_properties(color, coverage, caps, SkBlendMode::kSrcOver); } diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.h b/src/gpu/effects/GrPorterDuffXferProcessor.h index 23f1e9c5c5..81e8261724 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.h +++ b/src/gpu/effects/GrPorterDuffXferProcessor.h @@ -35,25 +35,21 @@ public: by reference because it is global and its ref-cnting methods are not thread safe. */ static const GrXferProcessor& SimpleSrcOverXP(); - static bool WillSrcOverNeedDstTexture(const GrCaps&, const FragmentProcessorAnalysis&); - static bool SrcOverIsCompatibleWithCoverageAsAlpha() { return true; } - static bool SrcOverCanCombineOverlappedStencilAndCover(bool colorIsOpaque) { - return colorIsOpaque; - } + static AnalysisProperties SrcOverAnalysisProperties(const GrPipelineAnalysisColor&, + const GrPipelineAnalysisCoverage&, + const GrCaps&); private: constexpr GrPorterDuffXPFactory(SkBlendMode); - bool canCombineOverlappedStencilAndCover(bool colorIsOpaque) const override; - GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const FragmentProcessorAnalysis&, bool hasMixedSamples, const DstTexture*) const override; - bool willReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override; - - bool compatibleWithCoverageAsAlpha(bool colorIsOpaque) const override; + AnalysisProperties analysisProperties(const GrPipelineAnalysisColor&, + const GrPipelineAnalysisCoverage&, + const GrCaps&) const override; GR_DECLARE_XP_FACTORY_TEST; static void TestGetXPOutputTypes(const GrXferProcessor*, int* outPrimary, int* outSecondary); diff --git a/src/gpu/instanced/InstancedRendering.cpp b/src/gpu/instanced/InstancedRendering.cpp index e67a8be977..d75af35dab 100644 --- a/src/gpu/instanced/InstancedRendering.cpp +++ b/src/gpu/instanced/InstancedRendering.cpp @@ -367,13 +367,10 @@ bool InstancedRendering::Op::xpRequiresDstTexture(const GrCaps& caps, const GrAp SkASSERT(State::kRecordingDraws == fInstancedRendering->fState); this->getSingleDraw().fInstance.fColor = overrideColor; } - fInfo.fCannotTweakAlphaForCoverage = - !analysis.isCompatibleWithCoverageAsAlpha() || - !GrXPFactory::CompatibleWithCoverageAsAlpha(fProcessors.xpFactory(), - analysis.isOutputColorOpaque()); + fInfo.fCannotTweakAlphaForCoverage = !analysis.isCompatibleWithCoverageAsAlpha(); fInfo.fUsesLocalCoords = analysis.usesLocalCoords(); - return GrXPFactory::WillNeedDstTexture(fProcessors.xpFactory(), caps, analysis); + return analysis.requiresDstTexture(); } void InstancedRendering::Op::wasRecorded() { diff --git a/src/gpu/ops/GrDrawPathOp.cpp b/src/gpu/ops/GrDrawPathOp.cpp index fa08ae6d54..0a3df45cae 100644 --- a/src/gpu/ops/GrDrawPathOp.cpp +++ b/src/gpu/ops/GrDrawPathOp.cpp @@ -148,13 +148,7 @@ bool GrDrawPathRangeOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) { GrPathRendering::kWinding_FillType != that->fillType()) { return false; } - // If we have non-clipping coverage processors we don't try to merge as its unclear whether it - // will be correct. We don't expect this to happen in practice. - if (this->processors().numCoverageFragmentProcessors()) { - return false; - } - bool opaque = this->fragmentProcessorAnalysis().isOutputColorOpaque(); - if (!GrXPFactory::CanCombineOverlappedStencilAndCover(this->processors().xpFactory(), opaque)) { + if (!this->fragmentProcessorAnalysis().canCombineOverlappedStencilAndCover()) { return false; } fTotalPathCount += that->fTotalPathCount; diff --git a/src/gpu/ops/GrDrawPathOp.h b/src/gpu/ops/GrDrawPathOp.h index b1ce2dfe5a..5650b888ba 100644 --- a/src/gpu/ops/GrDrawPathOp.h +++ b/src/gpu/ops/GrDrawPathOp.h @@ -29,8 +29,7 @@ protected: return FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil; } bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override { - return GrXPFactory::WillNeedDstTexture(fProcessorSet.xpFactory(), caps, - this->doFragmentProcessorAnalysis(caps, clip)); + return this->doFragmentProcessorAnalysis(caps, clip).requiresDstTexture(); } void wasRecorded() override { fProcessorSet.makePendingExecution(); } diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp index ef217010ae..46f9f6e27a 100644 --- a/tests/GrPorterDuffTest.cpp +++ b/tests/GrPorterDuffTest.cpp @@ -21,7 +21,7 @@ //////////////////////////////////////////////////////////////////////////////// static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const GrCaps& caps); -static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps); +static void test_color_not_opaque_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps); static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const GrCaps& caps); static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps); static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps); @@ -35,7 +35,7 @@ DEF_GPUTEST_FOR_NULLGL_CONTEXT(GrPorterDuff, reporter, ctxInfo) { } test_color_unknown_with_coverage(reporter, caps); - test_color_unknown_no_coverage(reporter, caps); + test_color_not_opaque_no_coverage(reporter, caps); test_color_opaque_with_coverage(reporter, caps); test_color_opaque_no_coverage(reporter, caps); test_lcd_coverage(reporter, caps); @@ -55,25 +55,19 @@ enum { kISCModulate_OutputType }; -enum { - kNone_OptFlags = GrXferProcessor::kNone_OptFlags, - kIgnoreColor_OptFlag = GrXferProcessor::kIgnoreColor_OptFlag, - kCanTweakAlphaForCoverage_OptFlag = GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag -}; - class GrPorterDuffTest { public: struct XPInfo { XPInfo(skiatest::Reporter* reporter, SkBlendMode xfermode, const GrCaps& caps, - const GrProcessorSet::FragmentProcessorAnalysis& analysis) { + GrPipelineAnalysisColor inputColor, GrPipelineAnalysisCoverage inputCoverage) { const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(xfermode); - // The GrXPFactory query assumes no coverage. - fCanCombineOverlappedStencilAndCover = - !analysis.hasCoverage() && GrXPFactory::CanCombineOverlappedStencilAndCover( - xpf, analysis.isOutputColorOpaque()); + GrProcessorSet::FragmentProcessorAnalysis analysis(inputColor, inputCoverage, xpf, + caps); + fCompatibleWithCoverageAsAlpha = analysis.isCompatibleWithCoverageAsAlpha(); + fCanCombineOverlappedStencilAndCover = analysis.canCombineOverlappedStencilAndCover(); + fIgnoresInputColor = analysis.isInputColorIgnored(); sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps)); - TEST_ASSERT(!GrXPFactory::WillNeedDstTexture(xpf, caps, analysis)); - fOptFlags = xp->getOptimizations(analysis); + TEST_ASSERT(!analysis.requiresDstTexture()); GetXPOutputTypes(xp.get(), &fPrimaryOutputType, &fSecondaryOutputType); xp->getBlendInfo(&fBlendInfo); TEST_ASSERT(!xp->willReadDstColor()); @@ -81,7 +75,8 @@ public: } bool fCanCombineOverlappedStencilAndCover; - int fOptFlags; + bool fCompatibleWithCoverageAsAlpha; + bool fIgnoresInputColor; int fPrimaryOutputType; int fSecondaryOutputType; GrXferProcessor::BlendInfo fBlendInfo; @@ -93,19 +88,17 @@ public: }; static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) { - GrProcessorSet::FragmentProcessorAnalysis analysis(GrPipelineAnalysisColor(), - GrPipelineAnalysisCoverage::kLCD, caps); - SkASSERT(!analysis.isOutputColorOpaque()); - SkASSERT(!analysis.hasKnownOutputColor()); - SkASSERT(analysis.outputCoverageType() == GrPipelineAnalysisCoverage::kLCD); + GrPipelineAnalysisColor inputColor = GrPipelineAnalysisColor::Opaque::kNo; + GrPipelineAnalysisCoverage inputCoverage = GrPipelineAnalysisCoverage::kLCD; for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); - const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis); + const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, inputColor, inputCoverage); switch (xfermode) { case SkBlendMode::kClear: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kIgnoreColor_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kCoverage_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kReverseSubtract_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -115,7 +108,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kSrc: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -125,8 +119,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kDst: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kIgnoreColor_OptFlag | - kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -136,7 +130,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kSrcOver: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kSAModulate_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -146,7 +141,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kDstOver: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -156,7 +152,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kSrcIn: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -166,7 +163,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kDstIn: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kISAModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kReverseSubtract_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -176,7 +174,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kSrcOut: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -186,7 +185,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kDstOut: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kSAModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -196,7 +196,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kSrcATop: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kSAModulate_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -206,7 +207,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kDstATop: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kISAModulate_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -216,7 +218,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kXor: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kSAModulate_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -226,7 +229,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kPlus: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -236,7 +240,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kModulate: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kISCModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kReverseSubtract_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -246,7 +251,8 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) break; case SkBlendMode::kScreen: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -261,20 +267,17 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) } } static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const GrCaps& caps) { - GrProcessorSet::FragmentProcessorAnalysis analysis( - GrPipelineAnalysisColor(), GrPipelineAnalysisCoverage::kSingleChannel, caps); - - SkASSERT(!analysis.isOutputColorOpaque()); - SkASSERT(!analysis.hasKnownOutputColor()); - SkASSERT(analysis.outputCoverageType() == GrPipelineAnalysisCoverage::kSingleChannel); + GrPipelineAnalysisColor inputColor = GrPipelineAnalysisColor::Opaque::kNo; + GrPipelineAnalysisCoverage inputCoverage = GrPipelineAnalysisCoverage::kSingleChannel; for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); - const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis); + const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, inputColor, inputCoverage); switch (xfermode) { case SkBlendMode::kClear: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kIgnoreColor_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kCoverage_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kReverseSubtract_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -284,7 +287,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kSrc: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -294,8 +298,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kDst: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kIgnoreColor_OptFlag | - kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -305,7 +309,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kSrcOver: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -315,7 +320,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kDstOver: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -325,7 +331,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kSrcIn: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -335,7 +342,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kDstIn: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kISAModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kReverseSubtract_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -345,7 +353,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kSrcOut: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kCoverage_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -355,7 +364,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kDstOut: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -365,7 +375,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kSrcATop: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -375,7 +386,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kDstATop: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kISAModulate_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -385,7 +397,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kXor: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -395,7 +408,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kPlus: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -405,7 +419,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kModulate: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kISCModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kReverseSubtract_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -415,7 +430,8 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kScreen: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -430,21 +446,18 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const } } -static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps) { - GrProcessorSet::FragmentProcessorAnalysis analysis(GrColorPackRGBA(229, 0, 154, 240), - GrPipelineAnalysisCoverage::kNone, caps); - - SkASSERT(!analysis.isOutputColorOpaque()); - SkASSERT(analysis.hasKnownOutputColor()); - SkASSERT(!analysis.hasCoverage()); +static void test_color_not_opaque_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps) { + GrPipelineAnalysisColor inputColor(GrColorPackRGBA(229, 0, 154, 240)); + GrPipelineAnalysisCoverage inputCoverage = GrPipelineAnalysisCoverage::kNone; for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); - const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis); + const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, inputColor, inputCoverage); switch (xfermode) { case SkBlendMode::kClear: TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kIgnoreColor_OptFlag == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -454,7 +467,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kSrc: TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -464,8 +478,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kDst: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kIgnoreColor_OptFlag | - kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -475,7 +489,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kSrcOver: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -485,7 +500,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kDstOver: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -495,7 +511,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kSrcIn: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -505,7 +522,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kDstIn: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -515,7 +533,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kSrcOut: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -525,7 +544,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kDstOut: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -535,7 +555,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kSrcATop: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -545,7 +566,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kDstATop: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -555,7 +577,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kXor: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -565,7 +588,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kPlus: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -575,7 +599,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kModulate: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -585,7 +610,8 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G break; case SkBlendMode::kScreen: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -601,21 +627,17 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G } static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const GrCaps& caps) { - GrProcessorSet::FragmentProcessorAnalysis analysis(GrPipelineAnalysisColor::Opaque::kYes, - GrPipelineAnalysisCoverage::kSingleChannel, - caps); - - SkASSERT(analysis.isOutputColorOpaque()); - SkASSERT(!analysis.hasKnownOutputColor()); - SkASSERT(analysis.outputCoverageType() == GrPipelineAnalysisCoverage::kSingleChannel); + GrPipelineAnalysisColor inputColor = GrPipelineAnalysisColor::Opaque::kYes; + GrPipelineAnalysisCoverage inputCoverage = GrPipelineAnalysisCoverage::kSingleChannel; for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); - const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis); + const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, inputColor, inputCoverage); switch (xfermode) { case SkBlendMode::kClear: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kIgnoreColor_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kCoverage_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kReverseSubtract_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -625,7 +647,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kSrc: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -635,8 +658,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kDst: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kIgnoreColor_OptFlag | - kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -646,7 +669,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kSrcOver: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -656,7 +680,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kDstOver: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -666,7 +691,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kSrcIn: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -676,8 +702,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kDstIn: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kIgnoreColor_OptFlag | - kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -687,7 +713,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kSrcOut: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -697,7 +724,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kDstOut: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kIgnoreColor_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kCoverage_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kReverseSubtract_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -707,7 +735,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kSrcATop: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -717,7 +746,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kDstATop: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -727,7 +757,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kXor: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -737,7 +768,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kPlus: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -747,7 +779,7 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kModulate: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kNone_OptFlags) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); TEST_ASSERT(kISCModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kReverseSubtract_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -757,7 +789,8 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const break; case SkBlendMode::kScreen: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -773,21 +806,18 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const } static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps) { - GrProcessorSet::FragmentProcessorAnalysis analysis(GrPipelineAnalysisColor::Opaque::kYes, - GrPipelineAnalysisCoverage::kNone, caps); - - SkASSERT(analysis.isOutputColorOpaque()); - SkASSERT(!analysis.hasKnownOutputColor()); - SkASSERT(!analysis.hasCoverage()); + GrPipelineAnalysisColor inputColor = GrPipelineAnalysisColor::Opaque::kYes; + GrPipelineAnalysisCoverage inputCoverage = GrPipelineAnalysisCoverage::kNone; for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); - const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis); + const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, inputColor, inputCoverage); switch (xfermode) { case SkBlendMode::kClear: TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kIgnoreColor_OptFlag == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -797,7 +827,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kSrc: TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -807,8 +838,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kDst: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kIgnoreColor_OptFlag | - kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -818,7 +849,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kSrcOver: TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -828,7 +860,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kDstOver: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -838,7 +871,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kSrcIn: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -848,8 +882,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kDstIn: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT((kIgnoreColor_OptFlag | - kCanTweakAlphaForCoverage_OptFlag) == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -859,7 +893,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kSrcOut: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -869,7 +904,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kDstOut: TEST_ASSERT(xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kIgnoreColor_OptFlag == xpi.fOptFlags); + TEST_ASSERT(xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kNone_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -879,7 +915,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kSrcATop: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -889,7 +926,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kDstATop: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -899,7 +937,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kXor: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -909,7 +948,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kPlus: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -919,7 +959,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kModulate: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kNone_OptFlags == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(!xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -929,7 +970,8 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr break; case SkBlendMode::kScreen: TEST_ASSERT(!xpi.fCanCombineOverlappedStencilAndCover); - TEST_ASSERT(kCanTweakAlphaForCoverage_OptFlag == xpi.fOptFlags); + TEST_ASSERT(!xpi.fIgnoresInputColor); + TEST_ASSERT(xpi.fCompatibleWithCoverageAsAlpha); TEST_ASSERT(kModulate_OutputType == xpi.fPrimaryOutputType); TEST_ASSERT(kNone_OutputType == xpi.fSecondaryOutputType); TEST_ASSERT(kAdd_GrBlendEquation == xpi.fBlendInfo.fEquation); @@ -974,17 +1016,15 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const SkASSERT(analysis.hasKnownOutputColor()); SkASSERT(analysis.outputCoverageType() == GrPipelineAnalysisCoverage::kLCD); - const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(SkBlendMode::kSrcOver); - TEST_ASSERT(!GrXPFactory::WillNeedDstTexture(xpf, caps, analysis)); + TEST_ASSERT(!analysis.requiresDstTexture()); + const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(SkBlendMode::kSrcOver); sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps)); if (!xp) { ERRORF(reporter, "Failed to create an XP with LCD coverage."); return; } - xp->getOptimizations(analysis); - GrXferProcessor::BlendInfo blendInfo; xp->getBlendInfo(&blendInfo); TEST_ASSERT(blendInfo.fWriteColor); @@ -1022,15 +1062,16 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) { GrPipelineAnalysisColor(GrColorPackRGBA(0, 82, 17, 255))}; for (const auto& colorInput : colorInputs) { - GrProcessorSet::FragmentProcessorAnalysis analysis; for (GrPipelineAnalysisCoverage coverageType : {GrPipelineAnalysisCoverage::kSingleChannel, GrPipelineAnalysisCoverage::kNone}) { - analysis = GrProcessorSet::FragmentProcessorAnalysis(colorInput, coverageType, caps); for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(xfermode); + GrProcessorSet::FragmentProcessorAnalysis analysis; + analysis = GrProcessorSet::FragmentProcessorAnalysis(colorInput, coverageType, xpf, + caps); GrXferProcessor::DstTexture* dstTexture = - GrXPFactory::WillNeedDstTexture(xpf, caps, analysis) ? &fakeDstTexture : 0; + analysis.requiresDstTexture() ? &fakeDstTexture : nullptr; sk_sp<GrXferProcessor> xp( xpf->createXferProcessor(analysis, false, dstTexture, caps)); if (!xp) { @@ -1038,8 +1079,6 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) { return; } TEST_ASSERT(!xp->hasSecondaryOutput()); - xp->getOptimizations(analysis); - TEST_ASSERT(!xp->hasSecondaryOutput()); } } } |