diff options
51 files changed, 479 insertions, 429 deletions
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp index e2b76f8ab4..4121549a7b 100644 --- a/src/gpu/GrPipeline.cpp +++ b/src/gpu/GrPipeline.cpp @@ -21,6 +21,7 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args, GrPipelineOptimizations* optimizations) { + SkASSERT(args.fAnalysis); GrRenderTarget* rt = args.fRenderTargetContext->accessRenderTarget(); if (!rt) { return nullptr; @@ -59,8 +60,8 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args, const GrXPFactory* xpFactory = args.fProcessors->xpFactory(); sk_sp<GrXferProcessor> xferProcessor; if (xpFactory) { - xferProcessor.reset(xpFactory->createXferProcessor( - args.fAnalysis, hasMixedSamples, &args.fDstTexture, *args.fCaps)); + xferProcessor.reset(xpFactory->createXferProcessor(*args.fAnalysis, hasMixedSamples, + &args.fDstTexture, *args.fCaps)); if (!xferProcessor) { pipeline->~GrPipeline(); return nullptr; @@ -68,17 +69,17 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args, } else { // This may return nullptr in the common case of src-over implemented using hw blending. xferProcessor.reset(GrPorterDuffXPFactory::CreateSrcOverXferProcessor( - *args.fCaps, args.fAnalysis, hasMixedSamples, &args.fDstTexture)); + *args.fCaps, *args.fAnalysis, hasMixedSamples, &args.fDstTexture)); } GrColor overrideColor = GrColor_ILLEGAL; - int colorFPsToEliminate = args.fAnalysis.fColorPOI.initialProcessorsToEliminate(&overrideColor); + int colorFPsToEliminate = args.fAnalysis->initialColorProcessorsToEliminate(&overrideColor); GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags; const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() : &GrPorterDuffXPFactory::SimpleSrcOverXP(); optFlags = xpForOpts->getOptimizations( - args.fAnalysis, args.fUserStencil->doesWrite(args.fAppliedClip->hasStencilClip()), + *args.fAnalysis, args.fUserStencil->doesWrite(args.fAppliedClip->hasStencilClip()), &overrideColor, *args.fCaps); // When path rendering the stencil settings are not always set on the GrPipelineBuilder @@ -144,8 +145,7 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args, optimizations->fFlags |= GrPipelineOptimizations::kCanTweakAlphaForCoverage_Flag; } - if (GrXPFactory::WillReadDst(xpFactory, args.fAnalysis.fColorPOI, - args.fAnalysis.fCoveragePOI)) { + if (GrXPFactory::WillReadDst(xpFactory, *args.fAnalysis)) { optimizations->fFlags |= GrPipelineOptimizations::kXPReadsDst_Flag; } diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h index 11de747b04..8fca37e6fa 100644 --- a/src/gpu/GrPipeline.h +++ b/src/gpu/GrPipeline.h @@ -14,13 +14,13 @@ #include "GrPendingProgramElement.h" #include "GrPrimitiveProcessor.h" #include "GrProcOptInfo.h" +#include "GrProcessorSet.h" #include "GrProgramDesc.h" #include "GrScissorState.h" #include "GrUserStencilSettings.h" #include "GrWindowRectsState.h" #include "SkMatrix.h" #include "SkRefCnt.h" - #include "effects/GrCoverageSetOpXP.h" #include "effects/GrDisableColorXP.h" #include "effects/GrPorterDuffXferProcessor.h" @@ -33,36 +33,6 @@ class GrPipelineBuilder; class GrRenderTargetContext; /** - * This Describes aspects of the GrPrimitiveProcessor produced by a GrDrawOp that are used in - * pipeline analysis. - */ -class GrPipelineAnalysisDrawOpInput { -public: - GrPipelineAnalysisDrawOpInput(GrPipelineInput* color, GrPipelineInput* coverage) - : fColorInput(color), fCoverageInput(coverage) {} - GrPipelineInput* pipelineColorInput() { return fColorInput; } - GrPipelineInput* pipelineCoverageInput() { return fCoverageInput; } - - void setUsesPLSDstRead() { fUsesPLSDstRead = true; } - - bool usesPLSDstRead() const { return fUsesPLSDstRead; } - -private: - GrPipelineInput* fColorInput; - GrPipelineInput* fCoverageInput; - bool fUsesPLSDstRead = false; -}; - -/** This is used to track pipeline analysis through the color and coverage fragment processors. */ -struct GrPipelineAnalysis { - GrProcOptInfo fColorPOI; - GrProcOptInfo fCoveragePOI; - bool fUsesPLSDstRead = false; -}; - -class GrProcessorSet; - -/** * Class that holds an optimized version of a GrPipelineBuilder. It is meant to be an immutable * class, and contains all data needed to set the state for a gpu draw. */ @@ -89,11 +59,11 @@ public: uint32_t fFlags = 0; GrDrawFace fDrawFace = GrDrawFace::kBoth; const GrProcessorSet* fProcessors = nullptr; + const GrProcessorSet::FragmentProcessorAnalysis* fAnalysis; const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused; GrAppliedClip* fAppliedClip = nullptr; GrRenderTargetContext* fRenderTargetContext = nullptr; const GrCaps* fCaps = nullptr; - GrPipelineAnalysis fAnalysis; GrXferProcessor::DstTexture fDstTexture; }; diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index 4e4861a5c1..294f409b96 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -18,7 +18,6 @@ class GrCaps; class GrDrawOp; class GrPaint; -struct GrPipelineAnalysis; class GrTexture; class GrPipelineBuilder : private SkNoncopyable { @@ -62,9 +61,7 @@ public: return fProcessors.coverageFragmentProcessor(idx); } - void analyzeFragmentProcessors(GrPipelineAnalysis* analysis) const { - fProcessors.analyzeFragmentProcessors(analysis); - } + const GrProcessorSet& processors() const { return fProcessors; } /// @} @@ -75,11 +72,9 @@ public: /** * Checks whether the xp will need destination in a texture to correctly blend. */ - bool willXPNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) const { - if (fProcessors.xpFactory()) { - return fProcessors.xpFactory()->willNeedDstTexture(caps, analysis); - } - return GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(caps, analysis); + bool willXPNeedDstTexture(const GrCaps& caps, + const GrProcessorSet::FragmentProcessorAnalysis& analysis) const { + return GrXPFactory::WillNeedDstTexture(fProcessors.xpFactory(), caps, analysis); } /// @} diff --git a/src/gpu/GrPipelineInput.h b/src/gpu/GrPipelineInput.h index a0826ec4fb..7079f36c63 100644 --- a/src/gpu/GrPipelineInput.h +++ b/src/gpu/GrPipelineInput.h @@ -20,10 +20,10 @@ struct GrPipelineInput { kYes, }; - explicit GrPipelineInput(Opaque opaque = Opaque::kNo) + GrPipelineInput(Opaque opaque = Opaque::kNo) : fFlags(opaque == Opaque::kYes ? kIsOpaque_Flag : 0) {} - explicit GrPipelineInput(GrColor color) : fFlags(kColorIsKnown_Flag), fColor(color) {} + GrPipelineInput(GrColor color) : fFlags(kColorIsKnown_Flag), fColor(color) {} void setToConstant(GrColor color) { fColor = color; @@ -53,6 +53,8 @@ struct GrPipelineInput { bool isOpaque() const { return SkToBool(kIsOpaque_Flag & fFlags); } + bool isSolidWhite() const { return (kColorIsKnown_Flag & fFlags) && GrColor_WHITE == fColor; } + bool isConstant(GrColor* color) const { if (kColorIsKnown_Flag & fFlags) { *color = fColor; diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h index 47564d9862..b9fe7b2c8b 100644 --- a/src/gpu/GrPrimitiveProcessor.h +++ b/src/gpu/GrPrimitiveProcessor.h @@ -24,7 +24,8 @@ * GrPrimitiveProcessor. These loops run on the CPU and to determine known properties of the final * color and coverage inputs to the GrXferProcessor in order to perform optimizations that preserve * correctness. The GrDrawOp seeds these loops with initial color and coverage, in its - * getPipelineAnalysisInput implementation. These seed values are processed by the subsequent + * getFragmentProcessorAnalysisInputs implementation. These seed values are processed by the + * subsequent * stages of the rendering pipeline and the output is then fed back into the GrDrawOp in * the applyPipelineOptimizations call, where the op can use the information to inform decisions * about GrPrimitiveProcessor creation. diff --git a/src/gpu/GrProcOptInfo.h b/src/gpu/GrProcOptInfo.h index ac3cb36966..304abae2b5 100644 --- a/src/gpu/GrProcOptInfo.h +++ b/src/gpu/GrProcOptInfo.h @@ -25,7 +25,6 @@ public: GrProcOptInfo() = default; GrProcOptInfo(const GrPipelineInput& input) : GrProcOptInfo() { - fIsLCDCoverage = input.isLCDCoverage(); fAllProcessorsCompatibleWithCoverageAsAlpha = !input.isLCDCoverage(); fIsOpaque = input.isOpaque(); GrColor color; @@ -35,12 +34,6 @@ public: } } - void resetToLCDCoverage() { - *this = GrProcOptInfo(); - fIsLCDCoverage = true; - fAllProcessorsCompatibleWithCoverageAsAlpha = false; - } - void reset(const GrPipelineInput& input) { *this = GrProcOptInfo(input); } /** @@ -49,15 +42,10 @@ public: */ void analyzeProcessors(const GrFragmentProcessor* const* processors, int cnt); - bool isSolidWhite() const { - return fProcessorsVisitedWithKnownOutput == fTotalProcessorsVisited && - fLastKnownOutputColor == GrColor4f::OpaqueWhite(); - } bool isOpaque() const { return fIsOpaque; } bool allProcessorsCompatibleWithCoverageAsAlpha() const { return fAllProcessorsCompatibleWithCoverageAsAlpha; } - bool isLCDCoverage() const { return fIsLCDCoverage; } /** * If we detected that the result after the first N processors is a known color then we @@ -72,6 +60,7 @@ public: } return SkTMax(0, fProcessorsVisitedWithKnownOutput); } + int initialProcessorsToEliminate(GrColor4f* newPipelineInputColor) const { if (fProcessorsVisitedWithKnownOutput > 0) { *newPipelineInputColor = fLastKnownOutputColor; @@ -93,7 +82,6 @@ private: int fTotalProcessorsVisited = 0; // negative one means even the color is unknown before adding the first processor. int fProcessorsVisitedWithKnownOutput = -1; - bool fIsLCDCoverage = false; bool fIsOpaque = false; bool fAllProcessorsCompatibleWithCoverageAsAlpha = true; GrColor4f fLastKnownOutputColor; diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp index 595d05cc45..179456209f 100644 --- a/src/gpu/GrProcessorSet.cpp +++ b/src/gpu/GrProcessorSet.cpp @@ -6,6 +6,9 @@ */ #include "GrProcessorSet.h" +#include "GrAppliedClip.h" +#include "GrCaps.h" +#include "GrProcOptInfo.h" GrProcessorSet::GrProcessorSet(GrPaint&& paint) { fXPFactory = paint.fXPFactory; @@ -29,3 +32,72 @@ GrProcessorSet::GrProcessorSet(GrPaint&& paint) { fFlags |= kAllowSRGBInputs_Flag; } } + +////////////////////////////////////////////////////////////////////////////// + +void GrProcessorSet::FragmentProcessorAnalysis::internalReset(const GrPipelineInput& colorInput, + const GrPipelineInput coverageInput, + const GrProcessorSet& processors, + bool usesPLSDstRead, + const GrFragmentProcessor* clipFP, + const GrCaps& caps) { + GrProcOptInfo colorInfo(colorInput); + fUsesPLSDstRead = usesPLSDstRead; + fCompatibleWithCoverageAsAlpha = !coverageInput.isLCDCoverage(); + + const GrFragmentProcessor* const* fps = processors.fFragmentProcessors.get(); + colorInfo.analyzeProcessors(fps, processors.fColorFragmentProcessorCnt); + fCompatibleWithCoverageAsAlpha &= colorInfo.allProcessorsCompatibleWithCoverageAsAlpha(); + fps += processors.fColorFragmentProcessorCnt; + int n = processors.numCoverageFragmentProcessors(); + bool hasCoverageFP = n > 0; + for (int i = 0; i < n && fCompatibleWithCoverageAsAlpha; ++i) { + if (!fps[i]->compatibleWithCoverageAsAlpha()) { + fCompatibleWithCoverageAsAlpha = false; + // Other than tests that exercise atypical behavior we expect all coverage FPs to be + // compatible with the coverage-as-alpha optimization. + GrCapsDebugf(&caps, "Coverage FP is not compatible with coverage as alpha.\n"); + break; + } + } + + if (clipFP) { + fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha(); + hasCoverageFP = true; + } + fInitialColorProcessorsToEliminate = + colorInfo.initialProcessorsToEliminate(&fOverrideInputColor); + + bool opaque = colorInfo.isOpaque(); + if (colorInfo.hasKnownOutputColor(&fKnownOutputColor)) { + fColorType = opaque ? ColorType::kOpaqueConstant : ColorType::kConstant; + } else if (opaque) { + fColorType = ColorType::kOpaque; + } else { + fColorType = ColorType::kUnknown; + } + + if (coverageInput.isLCDCoverage()) { + fCoverageType = CoverageType::kLCD; + } else { + fCoverageType = hasCoverageFP || !coverageInput.isSolidWhite() + ? CoverageType::kSingleChannel + : CoverageType::kNone; + } +} + +void GrProcessorSet::FragmentProcessorAnalysis::reset(const GrPipelineInput& colorInput, + const GrPipelineInput coverageInput, + const GrProcessorSet& processors, + bool usesPLSDstRead, + const GrAppliedClip& appliedClip, + const GrCaps& caps) { + this->internalReset(colorInput, coverageInput, processors, usesPLSDstRead, + appliedClip.clipCoverageFragmentProcessor(), caps); +} + +GrProcessorSet::FragmentProcessorAnalysis::FragmentProcessorAnalysis( + const GrPipelineInput& colorInput, const GrPipelineInput coverageInput, const GrCaps& caps) + : FragmentProcessorAnalysis() { + this->internalReset(colorInput, coverageInput, GrProcessorSet(GrPaint()), false, nullptr, caps); +} diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h index 19c3b225d5..bd78dc927e 100644 --- a/src/gpu/GrProcessorSet.h +++ b/src/gpu/GrProcessorSet.h @@ -10,9 +10,10 @@ #include "GrFragmentProcessor.h" #include "GrPaint.h" -#include "GrPipeline.h" +#include "GrPipelineInput.h" #include "SkTemplates.h" +class GrAppliedClip; class GrXPFactory; class GrProcessorSet : private SkNoncopyable { @@ -43,19 +44,65 @@ public: const GrXPFactory* xpFactory() const { return fXPFactory; } - void analyzeFragmentProcessors(GrPipelineAnalysis* analysis) const { - const GrFragmentProcessor* const* fps = fFragmentProcessors.get(); - analysis->fColorPOI.analyzeProcessors(fps, fColorFragmentProcessorCnt); - fps += fColorFragmentProcessorCnt; - analysis->fCoveragePOI.analyzeProcessors(fps, this->numCoverageFragmentProcessors()); - } - bool usesDistanceVectorField() const { return SkToBool(fFlags & kUseDistanceVectorField_Flag); } bool disableOutputConversionToSRGB() const { return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag); } bool allowSRGBInputs() const { return SkToBool(fFlags & kAllowSRGBInputs_Flag); } + /** + * This is used to track analysis of color and coverage values through the fragment processors. + */ + class FragmentProcessorAnalysis { + public: + FragmentProcessorAnalysis() = default; + // This version is used by a unit test that assumes no clip, no processors, and no PLS. + FragmentProcessorAnalysis(const GrPipelineInput& colorInput, + const GrPipelineInput coverageInput, const GrCaps&); + + void reset(const GrPipelineInput& colorInput, const GrPipelineInput coverageInput, + const GrProcessorSet&, bool usesPLSDstRead, const GrAppliedClip&, const GrCaps&); + + int initialColorProcessorsToEliminate(GrColor* newInputColor) const { + if (fInitialColorProcessorsToEliminate > 0) { + *newInputColor = fOverrideInputColor; + } + return fInitialColorProcessorsToEliminate; + } + + bool usesPLSDstRead() const { return fUsesPLSDstRead; } + bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; } + bool isOutputColorOpaque() const { + return ColorType::kOpaque == fColorType || ColorType::kOpaqueConstant == fColorType; + } + bool hasKnownOutputColor(GrColor* color = nullptr) const { + bool constant = + ColorType::kConstant == fColorType || ColorType::kOpaqueConstant == fColorType; + if (constant && color) { + *color = fKnownOutputColor; + } + return constant; + } + bool hasCoverage() const { return CoverageType::kNone != fCoverageType; } + bool hasLCDCoverage() const { return CoverageType::kLCD == fCoverageType; } + + private: + void internalReset(const GrPipelineInput& colorInput, const GrPipelineInput coverageInput, + const GrProcessorSet&, bool usesPLSDstRead, + const GrFragmentProcessor* clipFP, const GrCaps&); + + enum class ColorType { kUnknown, kOpaqueConstant, kConstant, kOpaque }; + enum class CoverageType { kNone, kSingleChannel, kLCD }; + + bool fUsesPLSDstRead = false; + bool fCompatibleWithCoverageAsAlpha = true; + CoverageType fCoverageType = CoverageType::kNone; + ColorType fColorType = ColorType::kUnknown; + int fInitialColorProcessorsToEliminate = 0; + GrColor fOverrideInputColor; + GrColor fKnownOutputColor; + }; + private: const GrXPFactory* fXPFactory = nullptr; SkAutoSTArray<4, const GrFragmentProcessor*> fFragmentProcessors; diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp index 361d10e2de..cd22541b93 100644 --- a/src/gpu/GrRenderTargetOpList.cpp +++ b/src/gpu/GrRenderTargetOpList.cpp @@ -286,13 +286,16 @@ void GrRenderTargetOpList::addDrawOp(const GrPipelineBuilder& pipelineBuilder, } } + GrProcessorSet::FragmentProcessorAnalysis analysis; + op->analyzeProcessors(&analysis, pipelineBuilder.processors(), appliedClip, *this->caps()); + GrPipeline::CreateArgs args; pipelineBuilder.initPipelineCreateArgs(&args); args.fAppliedClip = &appliedClip; args.fRenderTargetContext = renderTargetContext; args.fCaps = this->caps(); - op->initPipelineAnalysis(&args.fAnalysis); - if (args.fAnalysis.fUsesPLSDstRead || fClipOpToBounds) { + args.fAnalysis = &analysis; + if (analysis.usesPLSDstRead() || fClipOpToBounds) { GrGLIRect viewport; viewport.fLeft = 0; viewport.fBottom = 0; @@ -311,24 +314,12 @@ void GrRenderTargetOpList::addDrawOp(const GrPipelineBuilder& pipelineBuilder, return; } } - pipelineBuilder.analyzeFragmentProcessors(&args.fAnalysis); - if (const GrFragmentProcessor* clipFP = appliedClip.clipCoverageFragmentProcessor()) { - args.fAnalysis.fCoveragePOI.analyzeProcessors(&clipFP, 1); - } -#ifdef SK_DEBUG - // Other than tests that exercise atypical behavior we expect all coverage FPs to be compatible - // with the coverage-as-alpha optimization. - if (!args.fAnalysis.fCoveragePOI.allProcessorsCompatibleWithCoverageAsAlpha() && - !args.fAnalysis.fCoveragePOI.isLCDCoverage()) { - GrCapsDebugf(this->caps(), "Coverage FP is not compatible with coverage as alpha.\n"); - } -#endif if (!renderTargetContext->accessRenderTarget()) { return; } - if (pipelineBuilder.willXPNeedDstTexture(*this->caps(), args.fAnalysis)) { + if (pipelineBuilder.willXPNeedDstTexture(*this->caps(), analysis)) { this->setupDstTexture(renderTargetContext->accessRenderTarget(), clip, op->bounds(), &args.fDstTexture); if (!args.fDstTexture.texture()) { diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp index 0d93079d2c..56653b5eb1 100644 --- a/src/gpu/GrXferProcessor.cpp +++ b/src/gpu/GrXferProcessor.cpp @@ -30,10 +30,11 @@ GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture, } } -GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(const GrPipelineAnalysis& analysis, - bool doesStencilWrite, - GrColor* overrideColor, - const GrCaps& caps) const { +GrXferProcessor::OptFlags GrXferProcessor::getOptimizations( + const FragmentProcessorAnalysis& analysis, + bool doesStencilWrite, + GrColor* overrideColor, + const GrCaps& caps) const { GrXferProcessor::OptFlags flags = this->onGetOptimizations(analysis, doesStencilWrite, overrideColor, caps); return flags; @@ -180,48 +181,36 @@ SkString GrXferProcessor::BlendInfo::dump() const { /////////////////////////////////////////////////////////////////////////////// -using ColorType = GrXPFactory::ColorType; -using CoverageType = GrXPFactory::CoverageType; - -ColorType analysis_color_type(const GrPipelineAnalysis& analysis) { - if (analysis.fColorPOI.hasKnownOutputColor()) { - return analysis.fColorPOI.isOpaque() ? ColorType::kOpaqueConstant : ColorType::kConstant; - } - if (analysis.fColorPOI.isOpaque()) { - return ColorType::kOpaque; - } - return ColorType::kUnknown; -} - -CoverageType analysis_coverage_type(const GrPipelineAnalysis& analysis) { - if (analysis.fCoveragePOI.isSolidWhite()) { - return CoverageType::kNone; - } - if (analysis.fCoveragePOI.isLCDCoverage()) { - return CoverageType::kLCD; +bool GrXPFactory::WillReadDst(const GrXPFactory* factory, + const GrProcessorSet::FragmentProcessorAnalysis& analysis) { + if (factory) { + return factory->willReadsDst(analysis); } - return CoverageType::kSingleChannel; + return GrPorterDuffXPFactory::WillSrcOverReadDst(analysis); } -bool GrXPFactory::WillReadDst(const GrXPFactory* factory, const GrProcOptInfo& colorInput, - const GrProcOptInfo& coverageInput) { +bool GrXPFactory::WillNeedDstTexture(const GrXPFactory* factory, const GrCaps& caps, + const GrProcessorSet::FragmentProcessorAnalysis& analysis) { + bool result; if (factory) { - return factory->willReadsDst(colorInput, coverageInput); + result = !analysis.usesPLSDstRead() && !caps.shaderCaps()->dstReadInShaderSupport() && + factory->willReadDstInShader(caps, analysis); + } else { + result = GrPorterDuffXPFactory::WillSrcOverNeedDstTexture(caps, analysis); } - return GrPorterDuffXPFactory::WillSrcOverReadDst(colorInput, coverageInput); + SkASSERT(!(result && !WillReadDst(factory, analysis))); + return result; } bool GrXPFactory::willReadDstInShader(const GrCaps& caps, - const GrPipelineAnalysis& analysis) const { - if (analysis.fUsesPLSDstRead) { + const FragmentProcessorAnalysis& analysis) const { + if (analysis.usesPLSDstRead()) { return true; } - ColorType colorType = analysis_color_type(analysis); - CoverageType coverageType = analysis_coverage_type(analysis); - return this->willReadDstInShader(caps, colorType, coverageType); + return this->onWillReadDstInShader(caps, analysis); } -GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineAnalysis& analysis, +GrXferProcessor* GrXPFactory::createXferProcessor(const FragmentProcessorAnalysis& analysis, bool hasMixedSamples, const DstTexture* dstTexture, const GrCaps& caps) const { @@ -239,8 +228,3 @@ GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineAnalysis& anal #endif return this->onCreateXferProcessor(caps, analysis, hasMixedSamples, dstTexture); } - -bool GrXPFactory::willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) const { - return !analysis.fUsesPLSDstRead && !caps.shaderCaps()->dstReadInShaderSupport() && - this->willReadDstInShader(caps, analysis); -} diff --git a/src/gpu/GrXferProcessor.h b/src/gpu/GrXferProcessor.h index 9cb7189133..5ce06571a2 100644 --- a/src/gpu/GrXferProcessor.h +++ b/src/gpu/GrXferProcessor.h @@ -11,13 +11,13 @@ #include "GrBlend.h" #include "GrColor.h" #include "GrProcessor.h" +#include "GrProcessorSet.h" #include "GrTexture.h" #include "GrTypes.h" class GrShaderCaps; class GrGLSLXferProcessor; class GrProcOptInfo; -struct GrPipelineAnalysis; /** * Barriers for blending. When a shader reads the dst directly, an Xfer barrier is sometimes @@ -49,6 +49,8 @@ GR_STATIC_ASSERT(SkToBool(kNone_GrXferBarrierType) == false); */ class GrXferProcessor : public GrProcessor { public: + using FragmentProcessorAnalysis = GrProcessorSet::FragmentProcessorAnalysis; + /** * A texture that contains the dst pixel values and an integer coord offset from device space * to the space of the texture. Depending on GPU capabilities a DstTexture may be used by a @@ -131,11 +133,11 @@ public: * the draw with this xfer processor. If this function is called, the xfer processor may change * its state to reflected the given blend optimizations. If the XP needs to see a specific input * color to blend correctly, it will set the OverrideColor flag and the output parameter - * overrideColor will be the required value that should be passed into the XP. + * overrideColor will be the required value that should be passed into the XP. * A caller who calls this function on a XP is required to honor the returned OptFlags * and color values for its draw. */ - OptFlags getOptimizations(const GrPipelineAnalysis&, + OptFlags getOptimizations(const FragmentProcessorAnalysis&, bool doesStencilWrite, GrColor* overrideColor, const GrCaps& caps) const; @@ -231,7 +233,7 @@ protected: private: void notifyRefCntIsZero() const final {} - virtual OptFlags onGetOptimizations(const GrPipelineAnalysis&, + virtual OptFlags onGetOptimizations(const FragmentProcessorAnalysis&, bool doesStencilWrite, GrColor* overrideColor, const GrCaps& caps) const = 0; @@ -306,18 +308,11 @@ GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags); #endif class GrXPFactory { public: - typedef GrXferProcessor::DstTexture DstTexture; - - /** Describes known properties of a draw's color input to the GrXferProcessor. */ - enum class ColorType { kUnknown, kOpaqueConstant, kConstant, kOpaque }; + using FragmentProcessorAnalysis = GrProcessorSet::FragmentProcessorAnalysis; - /** - * Indicates whether a draw's coverage input to the GrXferProcessor is solid, single channel - * or LCD (four channel coverage). - */ - enum class CoverageType { kNone, kSingleChannel, kLCD }; + typedef GrXferProcessor::DstTexture DstTexture; - GrXferProcessor* createXferProcessor(const GrPipelineAnalysis&, + GrXferProcessor* createXferProcessor(const FragmentProcessorAnalysis&, bool hasMixedSamples, const DstTexture*, const GrCaps& caps) const; @@ -325,44 +320,36 @@ public: /** * Is the destination color required either in the shader or fixed function blending. */ - static bool WillReadDst(const GrXPFactory*, const GrProcOptInfo& colorInput, - const GrProcOptInfo& coverageInput); + static bool WillReadDst(const GrXPFactory*, const FragmentProcessorAnalysis&); - /** - * 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. - */ - bool willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) 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&); protected: constexpr GrXPFactory() {} - static bool ColorTypeIsOpaque(ColorType type) { - return ColorType::kOpaqueConstant == type || ColorType::kOpaque == type; - } - - static bool ColorTypeIsConstant(ColorType type) { - return ColorType::kOpaqueConstant == type || ColorType::kConstant == type; - } - private: /** Subclass-specific implementation of WillReadDst(). */ - virtual bool willReadsDst(const GrProcOptInfo& colorInput, - const GrProcOptInfo& coverageInput) const = 0; + virtual bool willReadsDst(const FragmentProcessorAnalysis& pipelineAnalysis) const = 0; virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, - const GrPipelineAnalysis&, + const FragmentProcessorAnalysis&, bool hasMixedSamples, const DstTexture*) const = 0; - bool willReadDstInShader(const GrCaps& caps, const GrPipelineAnalysis& analysis) const; + bool willReadDstInShader(const GrCaps& caps, const FragmentProcessorAnalysis& analysis) const; /** * Returns true if the XP generated by this factory will explicitly read dst in the fragment * shader. This will not be called for draws that read from PLS since the dst color is always * available in such draws. */ - virtual bool willReadDstInShader(const GrCaps&, ColorType, CoverageType) const = 0; + virtual bool onWillReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const = 0; }; #if defined(__GNUC__) || defined(__clang) #pragma GCC diagnostic pop diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp index 9cf994f07a..d8eb0d950f 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.cpp +++ b/src/gpu/effects/GrCoverageSetOpXP.cpp @@ -34,7 +34,7 @@ public: private: CoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage); - GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis& analysis, + GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis& analysis, bool doesStencilWrite, GrColor* color, const GrCaps& caps) const override; @@ -107,10 +107,11 @@ GrGLSLXferProcessor* CoverageSetOpXP::createGLSLInstance() const { return new GLCoverageSetOpXP(*this); } -GrXferProcessor::OptFlags CoverageSetOpXP::onGetOptimizations(const GrPipelineAnalysis& analysis, - bool doesStencilWrite, - GrColor* color, - const GrCaps& caps) const { +GrXferProcessor::OptFlags CoverageSetOpXP::onGetOptimizations( + const FragmentProcessorAnalysis& analysis, + bool doesStencilWrite, + GrColor* color, + const GrCaps& caps) const { // We never look at the color input return GrXferProcessor::kIgnoreColor_OptFlag; } @@ -167,7 +168,7 @@ public: bool invertCoverage() const { return fInvertCoverage; } private: - GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&, bool, GrColor*, + GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&, bool, GrColor*, const GrCaps&) const override { // We never look at the color input return GrXferProcessor::kIgnoreColor_OptFlag; @@ -321,10 +322,11 @@ const GrXPFactory* GrCoverageSetOpXPFactory::Get(SkRegion::Op regionOp, bool inv return nullptr; } -GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps, - const GrPipelineAnalysis& analysis, - bool hasMixedSamples, - const DstTexture* dst) const { +GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor( + const GrCaps& caps, + const FragmentProcessorAnalysis& analysis, + bool hasMixedSamples, + const DstTexture* dst) const { // We don't support inverting coverage with mixed samples. We don't expect to ever want this in // the future, however we could at some point make this work using an inverted coverage // modulation table. Note that an inverted table still won't work if there are coverage procs. @@ -333,7 +335,7 @@ GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& c return nullptr; } - if (analysis.fUsesPLSDstRead) { + if (analysis.usesPLSDstRead()) { return new ShaderCSOXferProcessor(dst, hasMixedSamples, fRegionOp, fInvertCoverage); } return CoverageSetOpXP::Create(fRegionOp, fInvertCoverage); diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h index 7c9f909978..ed6b9aa9f0 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.h +++ b/src/gpu/effects/GrCoverageSetOpXP.h @@ -32,16 +32,16 @@ public: private: constexpr GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage); - bool willReadsDst(const GrProcOptInfo&, const GrProcOptInfo&) const override { + bool willReadsDst(const FragmentProcessorAnalysis&) const override { return fRegionOp != SkRegion::kReplace_Op; } GrXferProcessor* onCreateXferProcessor(const GrCaps&, - const GrPipelineAnalysis&, + const FragmentProcessorAnalysis&, bool hasMixedSamples, const DstTexture*) const override; - bool willReadDstInShader(const GrCaps&, ColorType, CoverageType) const override { + bool onWillReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override { return false; } diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index 43042e2366..a33d2925ca 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -103,7 +103,7 @@ public: } private: - GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&, + GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&, bool doesStencilWrite, GrColor* overrideColor, const GrCaps& caps) const override; @@ -197,7 +197,7 @@ bool CustomXP::onIsEqual(const GrXferProcessor& other) const { return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation; } -GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const GrPipelineAnalysis& analysis, +GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const FragmentProcessorAnalysis& analysis, bool doesStencilWrite, GrColor* overrideColor, const GrCaps& caps) const { @@ -300,8 +300,7 @@ GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const GrPipelineAnalysis& */ OptFlags flags = kNone_OptFlags; - if (analysis.fColorPOI.allProcessorsCompatibleWithCoverageAsAlpha() && - analysis.fCoveragePOI.allProcessorsCompatibleWithCoverageAsAlpha()) { + if (analysis.isCompatibleWithCoverageAsAlpha()) { flags |= kCanTweakAlphaForCoverage_OptFlag; } return flags; @@ -334,13 +333,13 @@ public: private: GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, - const GrPipelineAnalysis&, + const FragmentProcessorAnalysis&, bool hasMixedSamples, const DstTexture*) const override; - bool willReadsDst(const GrProcOptInfo&, const GrProcOptInfo&) const override { return true; } + bool willReadsDst(const FragmentProcessorAnalysis&) const override { return true; } - bool willReadDstInShader(const GrCaps&, ColorType, CoverageType) const override; + bool onWillReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override; GR_DECLARE_XP_FACTORY_TEST; @@ -354,24 +353,24 @@ private: #endif GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps, - const GrPipelineAnalysis& analysis, + const FragmentProcessorAnalysis& analysis, bool hasMixedSamples, const DstTexture* dstTexture) const { SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); - if (can_use_hw_blend_equation(fHWBlendEquation, analysis.fUsesPLSDstRead, - analysis.fCoveragePOI.isLCDCoverage(), caps)) { + if (can_use_hw_blend_equation(fHWBlendEquation, analysis.usesPLSDstRead(), + analysis.hasLCDCoverage(), caps)) { SkASSERT(!dstTexture || !dstTexture->texture()); return new CustomXP(fMode, fHWBlendEquation); } return new CustomXP(dstTexture, hasMixedSamples, fMode); } -bool CustomXPFactory::willReadDstInShader(const GrCaps& caps, ColorType colorType, - CoverageType coverageType) const { +bool CustomXPFactory::onWillReadDstInShader(const GrCaps& caps, + const FragmentProcessorAnalysis& analysis) const { // This should not be called if we're using PLS dst read. static constexpr bool kUsesPLSRead = false; - return !can_use_hw_blend_equation(fHWBlendEquation, kUsesPLSRead, - CoverageType::kLCD == coverageType, caps); + return !can_use_hw_blend_equation(fHWBlendEquation, kUsesPLSRead, analysis.hasLCDCoverage(), + caps); } GR_DEFINE_XP_FACTORY_TEST(CustomXPFactory); diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp index 7323331a67..9c0228fae9 100644 --- a/src/gpu/effects/GrDisableColorXP.cpp +++ b/src/gpu/effects/GrDisableColorXP.cpp @@ -29,7 +29,7 @@ public: private: DisableColorXP(); - GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&, + GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&, bool doesStencilWrite, GrColor* color, const GrCaps& caps) const override { @@ -88,11 +88,12 @@ void DisableColorXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const } /////////////////////////////////////////////////////////////////////////////// -GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps, - const GrPipelineAnalysis& analysis, - bool hasMixedSamples, - const DstTexture* dst) const { - SkASSERT(!analysis.fUsesPLSDstRead); +GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor( + const GrCaps& caps, + const FragmentProcessorAnalysis& analysis, + bool hasMixedSamples, + const DstTexture* dst) const { + SkASSERT(!analysis.usesPLSDstRead()); return DisableColorXP::Create(); } diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h index e6a8d595e8..b4cd00a599 100644 --- a/src/gpu/effects/GrDisableColorXP.h +++ b/src/gpu/effects/GrDisableColorXP.h @@ -24,19 +24,16 @@ public: static const GrXPFactory* Get(); private: - bool willReadsDst(const GrProcOptInfo& colorInput, - const GrProcOptInfo& coverageInput) const override { - return false; - } + bool willReadsDst(const FragmentProcessorAnalysis&) const override { return false; } constexpr GrDisableColorXPFactory() {} - bool willReadDstInShader(const GrCaps&, ColorType, CoverageType) const override { + bool onWillReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) const override { return false; } GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, - const GrPipelineAnalysis&, + const FragmentProcessorAnalysis&, bool hasMixedSamples, const DstTexture* dstTexture) const override; diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index 1554b0cce0..4803c2d6ac 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -350,7 +350,7 @@ public: BlendFormula getBlendFormula() const { return fBlendFormula; } private: - GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&, + GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&, bool doesStencilWrite, GrColor* overrideColor, const GrCaps&) const override; @@ -450,7 +450,7 @@ GrGLSLXferProcessor* PorterDuffXferProcessor::createGLSLInstance() const { } GrXferProcessor::OptFlags PorterDuffXferProcessor::onGetOptimizations( - const GrPipelineAnalysis& analysis, + const FragmentProcessorAnalysis& analysis, bool doesStencilWrite, GrColor* overrideColor, const GrCaps& caps) const { @@ -465,8 +465,7 @@ GrXferProcessor::OptFlags PorterDuffXferProcessor::onGetOptimizations( if (!fBlendFormula.usesInputColor()) { optFlags |= GrXferProcessor::kIgnoreColor_OptFlag; } - if (analysis.fColorPOI.allProcessorsCompatibleWithCoverageAsAlpha() && - analysis.fCoveragePOI.allProcessorsCompatibleWithCoverageAsAlpha() && + if (analysis.isCompatibleWithCoverageAsAlpha() && fBlendFormula.canTweakAlphaForCoverage()) { optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag; } @@ -493,7 +492,7 @@ public: SkBlendMode getXfermode() const { return fXfermode; } private: - GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&, bool, GrColor*, + GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&, bool, GrColor*, const GrCaps&) const override { return kNone_OptFlags; } @@ -557,7 +556,7 @@ GrGLSLXferProcessor* ShaderPDXferProcessor::createGLSLInstance() const { class PDLCDXferProcessor : public GrXferProcessor { public: - static GrXferProcessor* Create(SkBlendMode xfermode, const GrProcOptInfo& colorPOI); + static GrXferProcessor* Create(SkBlendMode xfermode, const FragmentProcessorAnalysis& analysis); ~PDLCDXferProcessor() override; @@ -568,7 +567,7 @@ public: private: PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha); - GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&, + GrXferProcessor::OptFlags onGetOptimizations(const FragmentProcessorAnalysis&, bool doesStencilWrite, GrColor* overrideColor, const GrCaps&) const override; @@ -628,12 +627,13 @@ PDLCDXferProcessor::PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha) this->initClassID<PDLCDXferProcessor>(); } -GrXferProcessor* PDLCDXferProcessor::Create(SkBlendMode xfermode, const GrProcOptInfo& colorPOI) { +GrXferProcessor* PDLCDXferProcessor::Create(SkBlendMode xfermode, + const FragmentProcessorAnalysis& analysis) { if (SkBlendMode::kSrcOver != xfermode) { return nullptr; } GrColor blendConstant; - if (!colorPOI.hasKnownOutputColor(&blendConstant)) { + if (!analysis.hasKnownOutputColor(&blendConstant)) { return nullptr; } uint8_t alpha = GrColorUnpackA(blendConstant); @@ -653,7 +653,7 @@ GrGLSLXferProcessor* PDLCDXferProcessor::createGLSLInstance() const { return new GLPDLCDXferProcessor(*this); } -GrXferProcessor::OptFlags PDLCDXferProcessor::onGetOptimizations(const GrPipelineAnalysis&, +GrXferProcessor::OptFlags PDLCDXferProcessor::onGetOptimizations(const FragmentProcessorAnalysis&, bool doesStencilWrite, GrColor* overrideColor, const GrCaps& caps) const { @@ -734,28 +734,28 @@ const GrXPFactory* GrPorterDuffXPFactory::Get(SkBlendMode blendMode) { } } -GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, - const GrPipelineAnalysis& analysis, - bool hasMixedSamples, - const DstTexture* dstTexture) const { - if (analysis.fUsesPLSDstRead) { +GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor( + const GrCaps& caps, + const FragmentProcessorAnalysis& analysis, + bool hasMixedSamples, + const DstTexture* dstTexture) const { + if (analysis.usesPLSDstRead()) { return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fBlendMode); } BlendFormula blendFormula; - if (analysis.fCoveragePOI.isLCDCoverage()) { - if (SkBlendMode::kSrcOver == fBlendMode && analysis.fColorPOI.hasKnownOutputColor() && + if (analysis.hasLCDCoverage()) { + if (SkBlendMode::kSrcOver == fBlendMode && analysis.hasKnownOutputColor() && !caps.shaderCaps()->dualSourceBlendingSupport() && !caps.shaderCaps()->dstReadInShaderSupport()) { // If we don't have dual source blending or in shader dst reads, we fall back to this // trick for rendering SrcOver LCD text instead of doing a dst copy. SkASSERT(!dstTexture || !dstTexture->texture()); - return PDLCDXferProcessor::Create(fBlendMode, analysis.fColorPOI); + return PDLCDXferProcessor::Create(fBlendMode, analysis); } blendFormula = get_lcd_blend_formula(fBlendMode); } else { - blendFormula = get_blend_formula(analysis.fColorPOI.isOpaque(), - !analysis.fCoveragePOI.isSolidWhite(), hasMixedSamples, - fBlendMode); + blendFormula = get_blend_formula(analysis.isOutputColorOpaque(), analysis.hasCoverage(), + hasMixedSamples, fBlendMode); } if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) { @@ -766,15 +766,14 @@ GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps return new PorterDuffXferProcessor(blendFormula); } -bool GrPorterDuffXPFactory::willReadsDst(const GrProcOptInfo& colorInput, - const GrProcOptInfo& coverageInput) const { - BlendFormula colorFormula = gBlendTable[colorInput.isOpaque()][0][(int)fBlendMode]; +bool GrPorterDuffXPFactory::willReadsDst(const FragmentProcessorAnalysis& analysis) const { + BlendFormula colorFormula = gBlendTable[analysis.isOutputColorOpaque()][0][(int)fBlendMode]; SkASSERT(kAdd_GrBlendEquation == colorFormula.fBlendEquation); - return (colorFormula.usesDstColor() || !coverageInput.isSolidWhite()); + return (colorFormula.usesDstColor() || analysis.hasCoverage()); } -bool GrPorterDuffXPFactory::willReadDstInShader(const GrCaps& caps, ColorType colorType, - CoverageType coverageType) const { +bool GrPorterDuffXPFactory::onWillReadDstInShader(const GrCaps& caps, + const FragmentProcessorAnalysis& analysis) const { if (caps.shaderCaps()->dualSourceBlendingSupport()) { return false; } @@ -782,8 +781,8 @@ bool GrPorterDuffXPFactory::willReadDstInShader(const GrCaps& caps, ColorType co // 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 (CoverageType::kLCD == coverageType) { - if (SkBlendMode::kSrcOver == fBlendMode && ColorTypeIsConstant(colorType) && + if (analysis.hasLCDCoverage()) { + if (SkBlendMode::kSrcOver == fBlendMode && analysis.hasKnownOutputColor() && !caps.shaderCaps()->dstReadInShaderSupport()) { return false; } @@ -794,9 +793,8 @@ bool GrPorterDuffXPFactory::willReadDstInShader(const GrCaps& caps, ColorType co // 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(ColorTypeIsOpaque(colorType), - CoverageType::kSingleChannel == coverageType, kHasMixedSamples, - fBlendMode); + auto formula = get_blend_formula(analysis.isOutputColorOpaque(), analysis.hasCoverage(), + kHasMixedSamples, fBlendMode); return formula.hasSecondaryOutput(); } @@ -833,10 +831,10 @@ const GrXferProcessor& GrPorterDuffXPFactory::SimpleSrcOverXP() { GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor( const GrCaps& caps, - const GrPipelineAnalysis& analysis, + const FragmentProcessorAnalysis& analysis, bool hasMixedSamples, const GrXferProcessor::DstTexture* dstTexture) { - if (analysis.fUsesPLSDstRead) { + if (analysis.usesPLSDstRead()) { return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkBlendMode::kSrcOver); } @@ -844,7 +842,7 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor( // doing lcd blending we will just use our global SimpleSrcOverXP. This slightly differs from // the general case where we convert a src-over blend that has solid coverage and an opaque // color to src-mode, which allows disabling of blending. - if (!analysis.fCoveragePOI.isLCDCoverage()) { + if (!analysis.hasLCDCoverage()) { // We return nullptr here, which our caller interprets as meaning "use SimpleSrcOverXP". // We don't simply return the address of that XP here because our caller would have to unref // it and since it is a global object and GrProgramElement's ref-cnting system is not thread @@ -852,14 +850,13 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor( return nullptr; } - if (analysis.fColorPOI.hasKnownOutputColor() && - !caps.shaderCaps()->dualSourceBlendingSupport() && + if (analysis.hasKnownOutputColor() && !caps.shaderCaps()->dualSourceBlendingSupport() && !caps.shaderCaps()->dstReadInShaderSupport()) { // If we don't have dual source blending or in shader dst reads, we fall // back to this trick for rendering SrcOver LCD text instead of doing a // dst copy. SkASSERT(!dstTexture || !dstTexture->texture()); - return PDLCDXferProcessor::Create(SkBlendMode::kSrcOver, analysis.fColorPOI); + return PDLCDXferProcessor::Create(SkBlendMode::kSrcOver, analysis); } BlendFormula blendFormula; @@ -877,9 +874,8 @@ sk_sp<GrXferProcessor> GrPorterDuffXPFactory::CreateNoCoverageXP(SkBlendMode ble return sk_make_sp<PorterDuffXferProcessor>(formula); } -bool GrPorterDuffXPFactory::WillSrcOverReadDst(const GrProcOptInfo& colorInput, - const GrProcOptInfo& coverageInput) { - return !coverageInput.isSolidWhite() || !colorInput.isOpaque(); +bool GrPorterDuffXPFactory::WillSrcOverReadDst(const FragmentProcessorAnalysis& analysis) { + return analysis.hasCoverage() || !analysis.isOutputColorOpaque(); } bool GrPorterDuffXPFactory::IsSrcOverPreCoverageBlendedColorConstant( @@ -890,8 +886,8 @@ bool GrPorterDuffXPFactory::IsSrcOverPreCoverageBlendedColorConstant( return colorInput.hasKnownOutputColor(color); } -bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps, - const GrPipelineAnalysis& analysis) { +bool GrPorterDuffXPFactory::WillSrcOverNeedDstTexture(const GrCaps& caps, + const FragmentProcessorAnalysis& analysis) { if (caps.shaderCaps()->dstReadInShaderSupport() || caps.shaderCaps()->dualSourceBlendingSupport()) { return false; @@ -900,9 +896,8 @@ bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps, // 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.fCoveragePOI.isLCDCoverage()) { - if (analysis.fColorPOI.hasKnownOutputColor() && - !caps.shaderCaps()->dstReadInShaderSupport()) { + if (analysis.hasLCDCoverage()) { + if (analysis.hasKnownOutputColor() && !caps.shaderCaps()->dstReadInShaderSupport()) { return false; } auto formula = get_lcd_blend_formula(SkBlendMode::kSrcOver); @@ -912,8 +907,8 @@ bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps, // 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.fColorPOI.isOpaque(); - bool hasCoverage = !analysis.fCoveragePOI.isSolidWhite(); + 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); diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.h b/src/gpu/effects/GrPorterDuffXferProcessor.h index e6e676d6cc..6d7dc90fcf 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.h +++ b/src/gpu/effects/GrPorterDuffXferProcessor.h @@ -26,7 +26,7 @@ public: /** Because src-over is so common we special case it for performance reasons. If this returns null then the SimpleSrcOverXP() below should be used. */ static GrXferProcessor* CreateSrcOverXferProcessor(const GrCaps& caps, - const GrPipelineAnalysis&, + const FragmentProcessorAnalysis&, bool hasMixedSamples, const GrXferProcessor::DstTexture*); @@ -37,24 +37,22 @@ public: by reference because it is global and its ref-cnting methods are not thread safe. */ static const GrXferProcessor& SimpleSrcOverXP(); - static bool WillSrcOverReadDst(const GrProcOptInfo& colorInput, - const GrProcOptInfo& coverageInput); + static bool WillSrcOverReadDst(const FragmentProcessorAnalysis& analysis); static bool IsSrcOverPreCoverageBlendedColorConstant(const GrProcOptInfo& colorInput, GrColor* color); - - static bool SrcOverWillNeedDstTexture(const GrCaps&, const GrPipelineAnalysis&); + static bool WillSrcOverNeedDstTexture(const GrCaps&, const FragmentProcessorAnalysis&); private: constexpr GrPorterDuffXPFactory(SkBlendMode); - bool willReadsDst(const GrProcOptInfo&, const GrProcOptInfo&) const override; + bool willReadsDst(const FragmentProcessorAnalysis&) const override; GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, - const GrPipelineAnalysis&, + const FragmentProcessorAnalysis&, bool hasMixedSamples, const DstTexture*) const override; - bool willReadDstInShader(const GrCaps&, ColorType, CoverageType) const override; + bool onWillReadDstInShader(const GrCaps&, const FragmentProcessorAnalysis&) 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 66d454e1bd..245d6d8281 100644 --- a/src/gpu/instanced/InstancedRendering.cpp +++ b/src/gpu/instanced/InstancedRendering.cpp @@ -340,15 +340,16 @@ void InstancedRendering::Op::appendParamsTexel(SkScalar x, SkScalar y, SkScalar fInfo.fHasParams = true; } -void InstancedRendering::Op::getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const { - input->pipelineColorInput()->setToConstant(this->getSingleInstance().fColor); +void InstancedRendering::Op::getFragmentProcessorAnalysisInputs( + FragmentProcessorAnalysisInputs* input) const { + input->colorInput()->setToConstant(this->getSingleInstance().fColor); if (AntialiasMode::kCoverage == fInfo.fAntialiasMode || (AntialiasMode::kNone == fInfo.fAntialiasMode && !fInfo.isSimpleRects() && fInfo.fCannotDiscard)) { - input->pipelineCoverageInput()->setToUnknown(); + input->coverageInput()->setToUnknown(); } else { - input->pipelineCoverageInput()->setToSolidCoverage(); + input->coverageInput()->setToSolidCoverage(); } } diff --git a/src/gpu/instanced/InstancedRendering.h b/src/gpu/instanced/InstancedRendering.h index 1defcc7816..03fe242345 100644 --- a/src/gpu/instanced/InstancedRendering.h +++ b/src/gpu/instanced/InstancedRendering.h @@ -154,7 +154,8 @@ protected: Draw* fTailDraw; private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override; + void getFragmentProcessorAnalysisInputs( + FragmentProcessorAnalysisInputs* input) const override; void applyPipelineOptimizations(const GrPipelineOptimizations&) override; bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override; void onPrepare(GrOpFlushState*) override {} diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp index 15a5beda27..b98b5c869b 100644 --- a/src/gpu/ops/GrAAConvexPathRenderer.cpp +++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp @@ -747,9 +747,9 @@ private: this->setTransformedBounds(path.getBounds(), viewMatrix, HasAABloat::kYes, IsZeroArea::kNo); } - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp index c5842c0913..7ed14ba7de 100644 --- a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp +++ b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp @@ -177,9 +177,9 @@ private: this->setTransformedBounds(shape.bounds(), viewMatrix, HasAABloat::kYes, IsZeroArea::kNo); } - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fShapes[0].fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fShapes[0].fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrAAFillRectOp.cpp b/src/gpu/ops/GrAAFillRectOp.cpp index 2d47ec007f..c66e7ee2c0 100644 --- a/src/gpu/ops/GrAAFillRectOp.cpp +++ b/src/gpu/ops/GrAAFillRectOp.cpp @@ -203,9 +203,9 @@ public: } private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(this->first()->color()); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(this->first()->color()); + input->coverageInput()->setToUnknown(); } void onPrepareDraws(Target* target) const override { diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp index 820cf3db5f..6e244839ec 100644 --- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp @@ -716,9 +716,9 @@ private: IsZeroArea::kYes); } - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp index af193256e0..f0ff12be5e 100644 --- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp +++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp @@ -172,9 +172,9 @@ private: this->setTransformedBounds(bounds, viewMatrix, HasAABloat::kYes, IsZeroArea::kNo); } - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fPaths[0].fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fPaths[0].fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrAAStrokeRectOp.cpp b/src/gpu/ops/GrAAStrokeRectOp.cpp index 2b18fe85da..207b95f6b2 100644 --- a/src/gpu/ops/GrAAStrokeRectOp.cpp +++ b/src/gpu/ops/GrAAStrokeRectOp.cpp @@ -166,9 +166,9 @@ public: private: AAStrokeRectOp() : INHERITED(ClassID()) {} - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fRects[0].fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fRects[0].fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations&) override; void onPrepareDraws(Target*) const override; diff --git a/src/gpu/ops/GrAnalyticRectOp.cpp b/src/gpu/ops/GrAnalyticRectOp.cpp index ca19f9a6de..711ce33327 100644 --- a/src/gpu/ops/GrAnalyticRectOp.cpp +++ b/src/gpu/ops/GrAnalyticRectOp.cpp @@ -269,9 +269,9 @@ public: } private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fGeoData[0].fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fGeoData[0].fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp index 6b498af0db..be320ce545 100644 --- a/src/gpu/ops/GrAtlasTextOp.cpp +++ b/src/gpu/ops/GrAtlasTextOp.cpp @@ -45,23 +45,24 @@ SkString GrAtlasTextOp::dumpInfo() const { return str; } -void GrAtlasTextOp::getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const { +void GrAtlasTextOp::getFragmentProcessorAnalysisInputs( + FragmentProcessorAnalysisInputs* input) const { if (kColorBitmapMask_MaskType == fMaskType) { - input->pipelineColorInput()->setToUnknown(); + input->colorInput()->setToUnknown(); } else { - input->pipelineColorInput()->setToConstant(fColor); + input->colorInput()->setToConstant(fColor); } switch (fMaskType) { case kGrayscaleDistanceField_MaskType: case kGrayscaleCoverageMask_MaskType: - input->pipelineCoverageInput()->setToUnknown(); + input->coverageInput()->setToUnknown(); break; case kLCDCoverageMask_MaskType: case kLCDDistanceField_MaskType: - input->pipelineCoverageInput()->setToLCDCoverage(); + input->coverageInput()->setToLCDCoverage(); break; case kColorBitmapMask_MaskType: - input->pipelineCoverageInput()->setToSolidCoverage(); + input->coverageInput()->setToSolidCoverage(); } } diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h index 2a8c30b352..01736fc687 100644 --- a/src/gpu/ops/GrAtlasTextOp.h +++ b/src/gpu/ops/GrAtlasTextOp.h @@ -99,7 +99,7 @@ public: SkString dumpInfo() const override; private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput*) const override; + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs*) const override; void applyPipelineOptimizations(const GrPipelineOptimizations&) override; struct FlushInfo { diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp index 6efdfb7851..d91e86b6ad 100644 --- a/src/gpu/ops/GrDashOp.cpp +++ b/src/gpu/ops/GrDashOp.cpp @@ -296,9 +296,9 @@ private: this->setTransformedBounds(bounds, combinedMatrix, aaBloat, zeroArea); } - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp index 12513bd5b5..41ec8fb85e 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.cpp +++ b/src/gpu/ops/GrDefaultPathRenderer.cpp @@ -132,9 +132,9 @@ private: isHairline ? IsZeroArea::kYes : IsZeroArea::kNo); } - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fColor); - input->pipelineCoverageInput()->setToScalar(this->coverage()); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fColor); + input->coverageInput()->setToScalar(this->coverage()); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrDrawAtlasOp.h b/src/gpu/ops/GrDrawAtlasOp.h index 90fe07fda2..d6a211d939 100644 --- a/src/gpu/ops/GrDrawAtlasOp.h +++ b/src/gpu/ops/GrDrawAtlasOp.h @@ -39,13 +39,13 @@ private: GrDrawAtlasOp(GrColor color, const SkMatrix& viewMatrix, int spriteCount, const SkRSXform* xforms, const SkRect* rects, const SkColor* colors); - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { if (this->hasColors()) { - input->pipelineColorInput()->setToUnknown(); + input->colorInput()->setToUnknown(); } else { - input->pipelineColorInput()->setToConstant(fGeoData[0].fColor); + input->colorInput()->setToConstant(fGeoData[0].fColor); } - input->pipelineCoverageInput()->setToSolidCoverage(); + input->coverageInput()->setToSolidCoverage(); } void onPrepareDraws(Target*) const override; diff --git a/src/gpu/ops/GrDrawOp.cpp b/src/gpu/ops/GrDrawOp.cpp index 1fd2182b2a..e3e14bec82 100644 --- a/src/gpu/ops/GrDrawOp.cpp +++ b/src/gpu/ops/GrDrawOp.cpp @@ -15,16 +15,6 @@ GrDrawOp::~GrDrawOp() { } } -void GrDrawOp::initPipelineAnalysis(GrPipelineAnalysis* analysis) const { - GrPipelineInput color; - GrPipelineInput coverage; - GrPipelineAnalysisDrawOpInput input(&color, &coverage); - this->getPipelineAnalysisInput(&input); - analysis->fColorPOI.reset(color); - analysis->fCoveragePOI.reset(coverage); - analysis->fUsesPLSDstRead = input.usesPLSDstRead(); -} - bool GrDrawOp::installPipeline(const GrPipeline::CreateArgs& args) { GrPipelineOptimizations optimizations; void* location = fPipelineStorage.get(); diff --git a/src/gpu/ops/GrDrawOp.h b/src/gpu/ops/GrDrawOp.h index 447a4ddff6..2c7fbc2879 100644 --- a/src/gpu/ops/GrDrawOp.h +++ b/src/gpu/ops/GrDrawOp.h @@ -57,12 +57,21 @@ public: GrDrawOp(uint32_t classID); ~GrDrawOp() override; + bool installPipeline(const GrPipeline::CreateArgs&); + /** - * Gets the inputs to pipeline analysis from the GrDrawOp. + * Performs analysis of the fragment processors in GrProcessorSet and GrAppliedClip using the + * initial color and coverage from this op's geometry processor. */ - void initPipelineAnalysis(GrPipelineAnalysis*) const; - - bool installPipeline(const GrPipeline::CreateArgs&); + void analyzeProcessors(GrProcessorSet::FragmentProcessorAnalysis* analysis, + const GrProcessorSet& processors, + const GrAppliedClip& appliedClip, + const GrCaps& caps) const { + FragmentProcessorAnalysisInputs input; + this->getFragmentProcessorAnalysisInputs(&input); + analysis->reset(*input.colorInput(), *input.coverageInput(), processors, + input.usesPLSDstRead(), appliedClip, caps); + } protected: static SkString DumpPipelineInfo(const GrPipeline& pipeline) { @@ -101,12 +110,32 @@ protected: return reinterpret_cast<const GrPipeline*>(fPipelineStorage.get()); } + /** + * This describes aspects of the GrPrimitiveProcessor produced by a GrDrawOp that are used in + * pipeline analysis. + */ + class FragmentProcessorAnalysisInputs { + public: + FragmentProcessorAnalysisInputs() = default; + GrPipelineInput* colorInput() { return &fColorInput; } + GrPipelineInput* coverageInput() { return &fCoverageInput; } + + void setUsesPLSDstRead() { fUsesPLSDstRead = true; } + + bool usesPLSDstRead() const { return fUsesPLSDstRead; } + + private: + GrPipelineInput fColorInput; + GrPipelineInput fCoverageInput; + bool fUsesPLSDstRead = false; + }; + private: /** - * Provides information about the GrPrimitiveProccesor that will be used to issue draws by this - * op to GrPipeline analysis. + * Provides information about the GrPrimitiveProccesor color and coverage outputs which become + * inputs to the first color and coverage fragment processors. */ - virtual void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput*) const = 0; + virtual void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs*) const = 0; /** * After GrPipeline analysis is complete this is called so that the op can use the analysis diff --git a/src/gpu/ops/GrDrawPathOp.h b/src/gpu/ops/GrDrawPathOp.h index 4c213a25b8..3e84ffe52d 100644 --- a/src/gpu/ops/GrDrawPathOp.h +++ b/src/gpu/ops/GrDrawPathOp.h @@ -36,9 +36,9 @@ protected: bool xpReadsDst() const { return fXPReadsDst; } private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fColor); - input->pipelineCoverageInput()->setToSolidCoverage(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fColor); + input->coverageInput()->setToSolidCoverage(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp index 3eca0c5eeb..79f7c0a4c9 100644 --- a/src/gpu/ops/GrDrawVerticesOp.cpp +++ b/src/gpu/ops/GrDrawVerticesOp.cpp @@ -105,13 +105,14 @@ GrDrawVerticesOp::GrDrawVerticesOp(sk_sp<SkVertices> vertices, GrPrimitiveType p this->setTransformedBounds(mesh.fVertices->bounds(), viewMatrix, HasAABloat::kNo, zeroArea); } -void GrDrawVerticesOp::getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const { +void GrDrawVerticesOp::getFragmentProcessorAnalysisInputs( + FragmentProcessorAnalysisInputs* input) const { if (this->requiresPerVertexColors()) { - input->pipelineColorInput()->setToUnknown(); + input->colorInput()->setToUnknown(); } else { - input->pipelineColorInput()->setToConstant(fMeshes[0].fColor); + input->colorInput()->setToConstant(fMeshes[0].fColor); } - input->pipelineCoverageInput()->setToSolidCoverage(); + input->coverageInput()->setToSolidCoverage(); } void GrDrawVerticesOp::applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) { diff --git a/src/gpu/ops/GrDrawVerticesOp.h b/src/gpu/ops/GrDrawVerticesOp.h index 1cd3334396..2ce9bdcbcc 100644 --- a/src/gpu/ops/GrDrawVerticesOp.h +++ b/src/gpu/ops/GrDrawVerticesOp.h @@ -65,7 +65,7 @@ private: GrRenderTargetContext::ColorArrayType, const SkMatrix& viewMatrix, uint32_t flags = 0); - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override; + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override; void applyPipelineOptimizations(const GrPipelineOptimizations&) override; void onPrepareDraws(Target*) const override; diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp index 8e7049cc93..531a64679c 100644 --- a/src/gpu/ops/GrLatticeOp.cpp +++ b/src/gpu/ops/GrLatticeOp.cpp @@ -61,9 +61,9 @@ public: } private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToUnknown(); - input->pipelineCoverageInput()->setToSolidCoverage(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToUnknown(); + input->coverageInput()->setToSolidCoverage(); } void applyPipelineOptimizations(const GrPipelineOptimizations& analysioptimizations) override { diff --git a/src/gpu/ops/GrMSAAPathRenderer.cpp b/src/gpu/ops/GrMSAAPathRenderer.cpp index e8fb4987a1..ca760e81d4 100644 --- a/src/gpu/ops/GrMSAAPathRenderer.cpp +++ b/src/gpu/ops/GrMSAAPathRenderer.cpp @@ -259,9 +259,9 @@ private: this->setBounds(devBounds, HasAABloat::kNo, IsZeroArea::kNo); } - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fPaths[0].fColor); - input->pipelineCoverageInput()->setToSolidCoverage(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fPaths[0].fColor); + input->coverageInput()->setToSolidCoverage(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrNonAAFillRectOp.cpp b/src/gpu/ops/GrNonAAFillRectOp.cpp index 9fa6342882..871eecebfd 100644 --- a/src/gpu/ops/GrNonAAFillRectOp.cpp +++ b/src/gpu/ops/GrNonAAFillRectOp.cpp @@ -110,9 +110,9 @@ public: private: NonAAFillRectOp() : INHERITED(ClassID()) {} - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fRects[0].fColor); - input->pipelineCoverageInput()->setToSolidCoverage(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fRects[0].fColor); + input->coverageInput()->setToSolidCoverage(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrNonAAFillRectPerspectiveOp.cpp b/src/gpu/ops/GrNonAAFillRectPerspectiveOp.cpp index f4d5bcb473..5a0f81fa79 100644 --- a/src/gpu/ops/GrNonAAFillRectPerspectiveOp.cpp +++ b/src/gpu/ops/GrNonAAFillRectPerspectiveOp.cpp @@ -130,9 +130,9 @@ public: private: NonAAFillRectPerspectiveOp() : INHERITED(ClassID()) {} - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fRects[0].fColor); - input->pipelineCoverageInput()->setToSolidCoverage(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fRects[0].fColor); + input->coverageInput()->setToSolidCoverage(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrNonAAStrokeRectOp.cpp b/src/gpu/ops/GrNonAAStrokeRectOp.cpp index 2743ffc188..bcab4e0352 100644 --- a/src/gpu/ops/GrNonAAStrokeRectOp.cpp +++ b/src/gpu/ops/GrNonAAStrokeRectOp.cpp @@ -102,9 +102,9 @@ public: private: NonAAStrokeRectOp() : INHERITED(ClassID()) {} - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fColor); - input->pipelineCoverageInput()->setToSolidCoverage(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fColor); + input->coverageInput()->setToSolidCoverage(); } void onPrepareDraws(Target* target) const override { diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp index f1c8f9aec2..bf27f5aa7e 100644 --- a/src/gpu/ops/GrOvalOpFactory.cpp +++ b/src/gpu/ops/GrOvalOpFactory.cpp @@ -805,9 +805,9 @@ public: private: CircleOp() : INHERITED(ClassID()) {} - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fGeoData[0].fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fGeoData[0].fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { @@ -1256,9 +1256,9 @@ public: private: EllipseOp() : INHERITED(ClassID()) {} - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fGeoData[0].fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fGeoData[0].fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { @@ -1470,9 +1470,9 @@ public: private: DIEllipseOp() : INHERITED(ClassID()) {} - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fGeoData[0].fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fGeoData[0].fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { @@ -1785,9 +1785,9 @@ public: } private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fGeoData[0].fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fGeoData[0].fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { @@ -2147,9 +2147,9 @@ public: private: EllipticalRRectOp() : INHERITED(ClassID()) {} - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fGeoData[0].fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fGeoData[0].fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrPLSPathRenderer.cpp b/src/gpu/ops/GrPLSPathRenderer.cpp index e6022d306d..ac2f4fcf2b 100644 --- a/src/gpu/ops/GrPLSPathRenderer.cpp +++ b/src/gpu/ops/GrPLSPathRenderer.cpp @@ -781,9 +781,9 @@ private: IsZeroArea::kNo); } - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fColor); + input->coverageInput()->setToUnknown(); input->setUsesPLSDstRead(); } diff --git a/src/gpu/ops/GrRegionOp.cpp b/src/gpu/ops/GrRegionOp.cpp index c5d56338d8..e80a687212 100644 --- a/src/gpu/ops/GrRegionOp.cpp +++ b/src/gpu/ops/GrRegionOp.cpp @@ -77,9 +77,9 @@ public: } private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fRegions[0].fColor); - input->pipelineCoverageInput()->setToSolidCoverage(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fRegions[0].fColor); + input->coverageInput()->setToSolidCoverage(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp index 0431622484..6a848b8332 100644 --- a/src/gpu/ops/GrShadowRRectOp.cpp +++ b/src/gpu/ops/GrShadowRRectOp.cpp @@ -149,9 +149,9 @@ public: private: ShadowCircleOp() : INHERITED(ClassID()) {} - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fCircles[0].fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fCircles[0].fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { @@ -583,9 +583,9 @@ public: } private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fGeoData[0].fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fGeoData[0].fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp index 3acb091e17..7ecaf28245 100644 --- a/src/gpu/ops/GrTessellatingPathRenderer.cpp +++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp @@ -180,9 +180,9 @@ public: } private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/src/gpu/ops/GrTestMeshDrawOp.h b/src/gpu/ops/GrTestMeshDrawOp.h index 99eee3938c..d78d3e9164 100644 --- a/src/gpu/ops/GrTestMeshDrawOp.h +++ b/src/gpu/ops/GrTestMeshDrawOp.h @@ -33,9 +33,9 @@ protected: bool usesLocalCoords() const { return fUsesLocalCoords; } private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(fColor); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(fColor); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { diff --git a/tests/GpuSampleLocationsTest.cpp b/tests/GpuSampleLocationsTest.cpp index a690400b01..17fbe47f20 100644 --- a/tests/GpuSampleLocationsTest.cpp +++ b/tests/GpuSampleLocationsTest.cpp @@ -98,9 +98,11 @@ static GrPipeline* construct_dummy_pipeline(GrRenderTargetContext* dc, void* sto GrPipelineOptimizations dummyOverrides; GrAppliedClip dummyAppliedClip(SkRect::MakeLargest()); + GrProcessorSet::FragmentProcessorAnalysis analysis; GrPipeline::CreateArgs args; dummyBuilder.initPipelineCreateArgs(&args); args.fRenderTargetContext = dc; + args.fAnalysis = &analysis; args.fCaps = dc->caps(); args.fAppliedClip = &dummyAppliedClip; args.fDstTexture = GrXferProcessor::DstTexture(); diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp index a193162ada..d87e252141 100644 --- a/tests/GrPorterDuffTest.cpp +++ b/tests/GrPorterDuffTest.cpp @@ -9,6 +9,7 @@ #if SK_SUPPORT_GPU +#include "GrAppliedClip.h" #include "GrContextFactory.h" #include "GrContextOptions.h" #include "GrGpu.h" @@ -66,11 +67,11 @@ class GrPorterDuffTest { public: struct XPInfo { XPInfo(skiatest::Reporter* reporter, SkBlendMode xfermode, const GrCaps& caps, - const GrPipelineAnalysis& analysis) { + const GrProcessorSet::FragmentProcessorAnalysis& analysis) { const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(xfermode); - fReadsDst = GrXPFactory::WillReadDst(xpf, analysis.fColorPOI, analysis.fCoveragePOI); + fReadsDst = GrXPFactory::WillReadDst(xpf, analysis); sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps)); - TEST_ASSERT(!xpf->willNeedDstTexture(caps, analysis)); + TEST_ASSERT(!GrXPFactory::WillNeedDstTexture(xpf, caps, analysis)); GrColor ignoredOverrideColor; fOptFlags = xp->getOptimizations(analysis, false, &ignoredOverrideColor, caps); GetXPOutputTypes(xp.get(), &fPrimaryOutputType, &fSecondaryOutputType); @@ -92,14 +93,13 @@ public: }; static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) { - GrPipelineAnalysis analysis; - // Setting the last argument to true will force covPOI to LCD coverage. - analysis.fCoveragePOI.resetToLCDCoverage(); + GrPipelineInput lcdInput; + lcdInput.setToLCDCoverage(); + GrProcessorSet::FragmentProcessorAnalysis analysis(GrPipelineInput(), lcdInput, caps); - SkASSERT(!analysis.fColorPOI.isOpaque()); - SkASSERT(!analysis.fColorPOI.isSolidWhite()); - SkASSERT(!analysis.fCoveragePOI.isSolidWhite()); - SkASSERT(analysis.fCoveragePOI.isLCDCoverage()); + SkASSERT(!analysis.isOutputColorOpaque()); + SkASSERT(!analysis.hasKnownOutputColor()); + SkASSERT(analysis.hasLCDCoverage()); for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); @@ -264,12 +264,12 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) } } static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const GrCaps& caps) { - GrPipelineAnalysis analysis; + GrProcessorSet::FragmentProcessorAnalysis analysis(GrPipelineInput(), GrPipelineInput(), caps); - SkASSERT(!analysis.fColorPOI.isOpaque()); - SkASSERT(!analysis.fColorPOI.isSolidWhite()); - SkASSERT(!analysis.fCoveragePOI.isSolidWhite()); - SkASSERT(!analysis.fCoveragePOI.isLCDCoverage()); + SkASSERT(!analysis.isOutputColorOpaque()); + SkASSERT(!analysis.hasKnownOutputColor()); + SkASSERT(!analysis.hasLCDCoverage()); + SkASSERT(analysis.hasCoverage()); for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); @@ -435,14 +435,12 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const } static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps) { - GrPipelineAnalysis analysis; - analysis.fColorPOI.reset(GrPipelineInput(GrColorPackRGBA(229, 0, 154, 240))); - analysis.fCoveragePOI.reset(GrPipelineInput(GrColorPackA4(255))); + GrProcessorSet::FragmentProcessorAnalysis analysis(GrColorPackRGBA(229, 0, 154, 240), + GrColorPackA4(255), caps); - SkASSERT(!analysis.fColorPOI.isOpaque()); - SkASSERT(!analysis.fColorPOI.isSolidWhite()); - SkASSERT(analysis.fCoveragePOI.isSolidWhite()); - SkASSERT(!analysis.fCoveragePOI.isLCDCoverage()); + SkASSERT(!analysis.isOutputColorOpaque()); + SkASSERT(analysis.hasKnownOutputColor()); + SkASSERT(!analysis.hasCoverage()); for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); @@ -608,13 +606,13 @@ 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) { - GrPipelineAnalysis analysis; - analysis.fColorPOI.reset(GrPipelineInput(GrPipelineInput::Opaque::kYes)); + GrProcessorSet::FragmentProcessorAnalysis analysis(GrPipelineInput::Opaque::kYes, + GrPipelineInput(), caps); - SkASSERT(analysis.fColorPOI.isOpaque()); - SkASSERT(!analysis.fColorPOI.isSolidWhite()); - SkASSERT(!analysis.fCoveragePOI.isSolidWhite()); - SkASSERT(!analysis.fCoveragePOI.isLCDCoverage()); + SkASSERT(analysis.isOutputColorOpaque()); + SkASSERT(!analysis.hasKnownOutputColor()); + SkASSERT(analysis.hasCoverage()); + SkASSERT(!analysis.hasLCDCoverage()); for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); @@ -782,14 +780,12 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const } static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps) { - GrPipelineAnalysis analysis; - analysis.fColorPOI.reset(GrPipelineInput(GrPipelineInput::Opaque::kYes)); - analysis.fCoveragePOI.reset(GrPipelineInput(GrColorPackA4(255))); + GrProcessorSet::FragmentProcessorAnalysis analysis(GrPipelineInput::Opaque::kYes, + GrColorPackA4(255), caps); - SkASSERT(analysis.fColorPOI.isOpaque()); - SkASSERT(!analysis.fColorPOI.isSolidWhite()); - SkASSERT(analysis.fCoveragePOI.isSolidWhite()); - SkASSERT(!analysis.fCoveragePOI.isLCDCoverage()); + SkASSERT(analysis.isOutputColorOpaque()); + SkASSERT(!analysis.hasKnownOutputColor()); + SkASSERT(!analysis.hasCoverage()); for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); @@ -967,9 +963,10 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const const char* name() const override { return "Test LCD Text Op"; } private: - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToConstant(GrColorPackRGBA(123, 45, 67, 221)); - input->pipelineCoverageInput()->setToLCDCoverage(); + void getFragmentProcessorAnalysisInputs( + FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToConstant(GrColorPackRGBA(123, 45, 67, 221)); + input->coverageInput()->setToLCDCoverage(); } void applyPipelineOptimizations(const GrPipelineOptimizations&) override {} @@ -979,19 +976,15 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const typedef GrMeshDrawOp INHERITED; } testLCDCoverageOp; - GrPipelineAnalysis analysis; - testLCDCoverageOp.initPipelineAnalysis(&analysis); - GrProcOptInfo colorPOI = analysis.fColorPOI; - GrProcOptInfo covPOI = analysis.fCoveragePOI; - // Prevent unused var warnings in release. - (void)colorPOI; - (void)covPOI; + GrProcessorSet::FragmentProcessorAnalysis analysis; + GrAppliedClip clip(SkRect::MakeLargest()); + testLCDCoverageOp.analyzeProcessors(&analysis, GrProcessorSet(GrPaint()), clip, caps); - SkASSERT(colorPOI.hasKnownOutputColor()); - SkASSERT(covPOI.isLCDCoverage()); + SkASSERT(analysis.hasKnownOutputColor()); + SkASSERT(analysis.hasLCDCoverage()); const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(SkBlendMode::kSrcOver); - TEST_ASSERT(!xpf->willNeedDstTexture(caps, analysis)); + TEST_ASSERT(!GrXPFactory::WillNeedDstTexture(xpf, caps, analysis)); sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps)); if (!xp) { @@ -999,7 +992,7 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const return; } - TEST_ASSERT(GrXPFactory::WillReadDst(xpf, colorPOI, covPOI)); + TEST_ASSERT(GrXPFactory::WillReadDst(xpf, analysis)); GrColor overrideColor; xp->getOptimizations(analysis, false, &overrideColor, caps); @@ -1041,17 +1034,20 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) { GrPipelineInput(GrColorPackRGBA(0, 82, 17, 255))}; for (const auto& colorInput : colorInputs) { - GrPipelineAnalysis analysis; - analysis.fColorPOI = colorInput; + GrProcessorSet::FragmentProcessorAnalysis analysis; for (bool fractionalCoverage : {true, false}) { - if (!fractionalCoverage) { - analysis.fCoveragePOI.reset(GrPipelineInput(GrColorPackA4(255))); + if (fractionalCoverage) { + analysis = GrProcessorSet::FragmentProcessorAnalysis(colorInput, GrPipelineInput(), + caps); + } else { + analysis = GrProcessorSet::FragmentProcessorAnalysis(colorInput, GrColorPackA4(255), + caps); } for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) { SkBlendMode xfermode = static_cast<SkBlendMode>(m); const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(xfermode); GrXferProcessor::DstTexture* dstTexture = - xpf->willNeedDstTexture(caps, analysis) ? &fakeDstTexture : 0; + GrXPFactory::WillNeedDstTexture(xpf, caps, analysis) ? &fakeDstTexture : 0; sk_sp<GrXferProcessor> xp( xpf->createXferProcessor(analysis, false, dstTexture, caps)); if (!xp) { diff --git a/tests/PrimitiveProcessorTest.cpp b/tests/PrimitiveProcessorTest.cpp index 0b9c368ad3..fc9ccf2816 100644 --- a/tests/PrimitiveProcessorTest.cpp +++ b/tests/PrimitiveProcessorTest.cpp @@ -40,9 +40,9 @@ private: this->setBounds(SkRect::MakeWH(1.f, 1.f), HasAABloat::kNo, IsZeroArea::kNo); } - void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { - input->pipelineColorInput()->setToUnknown(); - input->pipelineCoverageInput()->setToUnknown(); + void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override { + input->colorInput()->setToUnknown(); + input->coverageInput()->setToUnknown(); } void applyPipelineOptimizations(const GrPipelineOptimizations&) override {} |