From aab259ea9ecabb3addcade3fba72d777bc7673e8 Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Tue, 17 Jan 2017 10:44:34 -0500 Subject: Simplify GrProcOptInfo initialization. Removes unused single channel tracking. Makes it so that only the op/gp can initiate lcd coverage. Makes GrProcOptInfo fragment processor analysis continuable. Change-Id: I003a8aa3836bb64d04b230ddee581dc500e613a9 Reviewed-on: https://skia-review.googlesource.com/7039 Reviewed-by: Greg Daniel Commit-Queue: Brian Salomon --- src/gpu/GrFragmentProcessor.cpp | 12 ++--- src/gpu/GrInvariantOutput.cpp | 31 ------------- src/gpu/GrPaint.cpp | 7 ++- src/gpu/GrProcOptInfo.cpp | 27 +---------- src/gpu/GrProcOptInfo.h | 59 +++++++++++++++---------- src/gpu/GrRenderTargetOpList.cpp | 4 +- src/gpu/effects/GrCustomXfermode.cpp | 2 +- src/gpu/effects/GrPorterDuffXferProcessor.cpp | 15 +++---- src/gpu/effects/GrXfermodeFragmentProcessor.cpp | 2 +- src/gpu/ops/GrDrawOp.cpp | 4 +- 10 files changed, 56 insertions(+), 107 deletions(-) delete mode 100644 src/gpu/GrInvariantOutput.cpp (limited to 'src/gpu') diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp index 75b6af7ca7..977974d78d 100644 --- a/src/gpu/GrFragmentProcessor.cpp +++ b/src/gpu/GrFragmentProcessor.cpp @@ -185,7 +185,7 @@ sk_sp GrFragmentProcessor::MulOutputByInputUnpremulColor( return; } - GrInvariantOutput childOutput(GrColor_WHITE, kRGBA_GrColorComponentFlags, false); + GrInvariantOutput childOutput(GrColor_WHITE, kRGBA_GrColorComponentFlags); this->childProcessor(0).computeInvariantOutput(&childOutput); if (0 == GrColorUnpackA(inout->color()) || 0 == GrColorUnpackA(childOutput.color())) { @@ -280,7 +280,7 @@ sk_sp GrFragmentProcessor::OverrideInput(sk_spcomputeInvariantOutput(&childOut); if (childOut.willUseInputColor()) { return sk_sp(new ReplaceInputFragmentProcessor(std::move(fp), color)); @@ -329,9 +329,6 @@ sk_sp GrFragmentProcessor::RunInSeries(sk_spcolor(), inout->validFlags(), false, false); for (int i = 0; i < this->numChildProcessors(); ++i) { this->childProcessor(i).computeInvariantOutput(inout); } @@ -343,9 +340,8 @@ sk_sp GrFragmentProcessor::RunInSeries(sk_spcolorComponentsAllEqual()); - } - } - - // If we claim that we are not using the input color we must not be modulating the input. - SkASSERT(fNonMulStageFound || fWillUseInputColor); -} - -bool GrInvariantOutput::colorComponentsAllEqual() const { - unsigned colorA = GrColorUnpackA(fColor); - return(GrColorUnpackR(fColor) == colorA && - GrColorUnpackG(fColor) == colorA && - GrColorUnpackB(fColor) == colorA); -} - -#endif // end DEBUG diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp index 122d87e338..7143b46b31 100644 --- a/src/gpu/GrPaint.cpp +++ b/src/gpu/GrPaint.cpp @@ -45,10 +45,9 @@ void GrPaint::addCoverageTextureProcessor(GrTexture* texture, } bool GrPaint::internalIsConstantBlendedColor(GrColor paintColor, GrColor* color) const { - GrProcOptInfo colorProcInfo; - colorProcInfo.calcWithInitialValues( - sk_sp_address_as_pointer_address(fColorFragmentProcessors.begin()), - this->numColorFragmentProcessors(), paintColor, kRGBA_GrColorComponentFlags, false); + GrProcOptInfo colorProcInfo(paintColor, kRGBA_GrColorComponentFlags); + colorProcInfo.addProcessors(sk_sp_address_as_pointer_address(fColorFragmentProcessors.begin()), + this->numColorFragmentProcessors()); GrXPFactory::InvariantBlendedColor blendedColor; if (fXPFactory) { diff --git a/src/gpu/GrProcOptInfo.cpp b/src/gpu/GrProcOptInfo.cpp index 5e612546d4..1493206fb4 100644 --- a/src/gpu/GrProcOptInfo.cpp +++ b/src/gpu/GrProcOptInfo.cpp @@ -6,35 +6,10 @@ */ #include "GrProcOptInfo.h" - #include "GrGeometryProcessor.h" - #include "ops/GrDrawOp.h" -void GrProcOptInfo::calcWithInitialValues(const GrFragmentProcessor * const processors[], - int cnt, - GrColor startColor, - GrColorComponentFlags flags, - bool areCoverageStages, - bool isLCD) { - GrPipelineInput out; - out.fIsSingleComponent = areCoverageStages; - out.fColor = startColor; - out.fValidFlags = flags; - out.fIsLCDCoverage = isLCD; - fInOut.reset(out); - this->internalCalc(processors, cnt); -} - -void GrProcOptInfo::completeCalculations(const GrFragmentProcessor * const processors[], int cnt) { - this->internalCalc(processors, cnt); -} - -void GrProcOptInfo::internalCalc(const GrFragmentProcessor* const processors[], int cnt) { - fFirstEffectiveProcessorIndex = 0; - fInputColorIsUsed = true; - fInputColor = fInOut.color(); - +void GrProcOptInfo::addProcessors(const GrFragmentProcessor* const* processors, int cnt) { for (int i = 0; i < cnt; ++i) { const GrFragmentProcessor* processor = processors[i]; fInOut.resetWillUseInputColor(); diff --git a/src/gpu/GrProcOptInfo.h b/src/gpu/GrProcOptInfo.h index d70ec46cc9..8149f2c1c6 100644 --- a/src/gpu/GrProcOptInfo.h +++ b/src/gpu/GrProcOptInfo.h @@ -22,33 +22,35 @@ class GrPrimitiveProcessor; */ class GrProcOptInfo { public: - GrProcOptInfo() - : fInOut(0, static_cast(0), false) - , fFirstEffectiveProcessorIndex(0) - , fInputColorIsUsed(true) - , fInputColor(0) {} + GrProcOptInfo() : fInOut(0, static_cast(0)) {} - void calcWithInitialValues(const GrFragmentProcessor* const *, int cnt, GrColor startColor, - GrColorComponentFlags, bool areCoverageStages, bool isLCD = false); - void initFromPipelineInput(const GrPipelineInput& input) { fInOut.reset(input); } - void completeCalculations(const GrFragmentProcessor * const processors[], int cnt); + GrProcOptInfo(GrColor color, GrColorComponentFlags colorFlags) + : fInOut(color, colorFlags), fInputColor(color) {} + + void resetToLCDCoverage(GrColor color, GrColorComponentFlags colorFlags) { + this->internalReset(color, colorFlags, true); + } + + void reset(GrColor color, GrColorComponentFlags colorFlags) { + this->internalReset(color, colorFlags, false); + } + + void reset(const GrPipelineInput& input) { + this->internalReset(input.fColor, input.fValidFlags, input.fIsLCDCoverage); + } + + /** + * Runs through a series of processors and updates calculated values. This can be called + * repeatedly for cases when the sequence of processors is not in a contiguous array. + */ + void addProcessors(const GrFragmentProcessor* const* processors, int cnt); bool isSolidWhite() const { return fInOut.isSolidWhite(); } bool isOpaque() const { return fInOut.isOpaque(); } - bool isSingleComponent() const { return fInOut.isSingleComponent(); } bool allStagesMultiplyInput() const { return fInOut.allStagesMulInput(); } - - // TODO: Once texture pixel configs quaries are updated, we no longer need this function. - // For now this function will correctly tell us if we are using LCD text or not and should only - // be called when looking at the coverage output. - bool isFourChannelOutput() const { return !fInOut.isSingleComponent() && - fInOut.isLCDCoverage(); } - + bool isLCDCoverage() const { return fIsLCDCoverage; } GrColor color() const { return fInOut.color(); } - - GrColorComponentFlags validFlags() const { - return fInOut.validFlags(); - } + GrColorComponentFlags validFlags() const { return fInOut.validFlags(); } /** * Returns the index of the first effective color processor. If an intermediate processor @@ -74,12 +76,21 @@ public: GrColor inputColorToFirstEffectiveProccesor() const { return fInputColor; } private: + void internalReset(GrColor color, GrColorComponentFlags colorFlags, bool isLCDCoverage) { + fInOut.reset(color, colorFlags); + fFirstEffectiveProcessorIndex = 0; + fInputColorIsUsed = true; + fInputColor = color; + fIsLCDCoverage = isLCDCoverage; + } + void internalCalc(const GrFragmentProcessor* const[], int cnt); GrInvariantOutput fInOut; - int fFirstEffectiveProcessorIndex; - bool fInputColorIsUsed; - GrColor fInputColor; + int fFirstEffectiveProcessorIndex = 0; + bool fInputColorIsUsed = true; + bool fIsLCDCoverage = false; + GrColor fInputColor = 0; }; #endif diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp index 9fb2dcbd1c..780e13bae5 100644 --- a/src/gpu/GrRenderTargetOpList.cpp +++ b/src/gpu/GrRenderTargetOpList.cpp @@ -318,10 +318,10 @@ void GrRenderTargetOpList::addDrawOp(const GrPipelineBuilder& pipelineBuilder, return; } } - args.fAnalysis.fColorPOI.completeCalculations( + args.fAnalysis.fColorPOI.addProcessors( sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessors.begin()), pipelineBuilder.numColorFragmentProcessors()); - args.fAnalysis.fCoveragePOI.completeCalculations( + args.fAnalysis.fCoveragePOI.addProcessors( sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProcessors.begin()), pipelineBuilder.numCoverageFragmentProcessors()); args.fScissor = &appliedClip.scissorState(); diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index d96ab94633..070fa2ffe0 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -62,7 +62,7 @@ static bool can_use_hw_blend_equation(GrBlendEquation equation, if (analysis.fUsesPLSDstRead) { return false; } - if (analysis.fCoveragePOI.isFourChannelOutput()) { + if (analysis.fCoveragePOI.isLCDCoverage()) { return false; // LCD coverage must be applied after the blend equation. } if (caps.canUseAdvancedBlendEquation(equation)) { diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index a813a532cd..7f409065f4 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -325,7 +325,7 @@ static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI, bool hasMixedSamples, SkBlendMode xfermode) { SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode); - SkASSERT(!coveragePOI.isFourChannelOutput()); + SkASSERT(!coveragePOI.isLCDCoverage()); bool conflatesCoverage = !coveragePOI.isSolidWhite() || hasMixedSamples; return gBlendTable[colorPOI.isOpaque()][conflatesCoverage][(int)xfermode]; @@ -334,7 +334,7 @@ static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI, static BlendFormula get_lcd_blend_formula(const GrProcOptInfo& coveragePOI, SkBlendMode xfermode) { SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode); - SkASSERT(coveragePOI.isFourChannelOutput()); + SkASSERT(coveragePOI.isLCDCoverage()); return gLCDBlendTable[(int)xfermode]; } @@ -470,8 +470,7 @@ GrXferProcessor::OptFlags PorterDuffXferProcessor::onGetOptimizations( optFlags |= GrXferProcessor::kIgnoreColor_OptFlag; } if (analysis.fColorPOI.allStagesMultiplyInput() && - fBlendFormula.canTweakAlphaForCoverage() && - !analysis.fCoveragePOI.isFourChannelOutput()) { + fBlendFormula.canTweakAlphaForCoverage() && !analysis.fCoveragePOI.isLCDCoverage()) { optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag; } } @@ -750,7 +749,7 @@ GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fBlendMode); } BlendFormula blendFormula; - if (analysis.fCoveragePOI.isFourChannelOutput()) { + if (analysis.fCoveragePOI.isLCDCoverage()) { if (SkBlendMode::kSrcOver == fBlendMode && kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() && !caps.shaderCaps()->dualSourceBlendingSupport() && @@ -814,7 +813,7 @@ bool GrPorterDuffXPFactory::onWillReadDstColor(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.isFourChannelOutput()) { + if (analysis.fCoveragePOI.isLCDCoverage()) { if (SkBlendMode::kSrcOver == fBlendMode && kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() && !caps.shaderCaps()->dstReadInShaderSupport()) { @@ -875,7 +874,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.isFourChannelOutput()) { + if (!analysis.fCoveragePOI.isLCDCoverage()) { // 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 @@ -913,7 +912,7 @@ 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.isFourChannelOutput()) { + if (analysis.fCoveragePOI.isLCDCoverage()) { if (kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() && !caps.shaderCaps()->dstReadInShaderSupport()) { return false; diff --git a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp index 2954170e20..d3eaee338d 100644 --- a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp +++ b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp @@ -182,7 +182,7 @@ protected: if (SkXfermode::ModeAsCoeff(fMode, &skSrcCoeff, &skDstCoeff)) { GrBlendCoeff srcCoeff = SkXfermodeCoeffToGrBlendCoeff(skSrcCoeff); GrBlendCoeff dstCoeff = SkXfermodeCoeffToGrBlendCoeff(skDstCoeff); - GrInvariantOutput childOutput(0xFFFFFFFF, kRGBA_GrColorComponentFlags, false); + GrInvariantOutput childOutput(0xFFFFFFFF, kRGBA_GrColorComponentFlags); this->childProcessor(0).computeInvariantOutput(&childOutput); GrColor blendColor; GrColorComponentFlags blendFlags; diff --git a/src/gpu/ops/GrDrawOp.cpp b/src/gpu/ops/GrDrawOp.cpp index f778601aba..1fd2182b2a 100644 --- a/src/gpu/ops/GrDrawOp.cpp +++ b/src/gpu/ops/GrDrawOp.cpp @@ -20,8 +20,8 @@ void GrDrawOp::initPipelineAnalysis(GrPipelineAnalysis* analysis) const { GrPipelineInput coverage; GrPipelineAnalysisDrawOpInput input(&color, &coverage); this->getPipelineAnalysisInput(&input); - analysis->fColorPOI.initFromPipelineInput(color); - analysis->fCoveragePOI.initFromPipelineInput(coverage); + analysis->fColorPOI.reset(color); + analysis->fCoveragePOI.reset(coverage); analysis->fUsesPLSDstRead = input.usesPLSDstRead(); } -- cgit v1.2.3