1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/core/SkBlendModePriv.h" 9cb93a386Sopenharmony_ci#include "src/gpu/GrAppliedClip.h" 10cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrProcessorSet.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrUserStencilSettings.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrXferProcessor.h" 14cb93a386Sopenharmony_ci#include "src/gpu/effects/GrPorterDuffXferProcessor.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ciconst GrProcessorSet& GrProcessorSet::EmptySet() { 17cb93a386Sopenharmony_ci static GrProcessorSet gEmpty(GrProcessorSet::Empty::kEmpty); 18cb93a386Sopenharmony_ci return gEmpty; 19cb93a386Sopenharmony_ci} 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ciGrProcessorSet GrProcessorSet::MakeEmptySet() { 22cb93a386Sopenharmony_ci return GrProcessorSet(GrProcessorSet::Empty::kEmpty); 23cb93a386Sopenharmony_ci} 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ciGrProcessorSet::GrProcessorSet(GrPaint&& paint) : fXP(paint.getXPFactory()) { 26cb93a386Sopenharmony_ci fColorFragmentProcessor = std::move(paint.fColorFragmentProcessor); 27cb93a386Sopenharmony_ci fCoverageFragmentProcessor = std::move(paint.fCoverageFragmentProcessor); 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci SkDEBUGCODE(paint.fAlive = false;) 30cb93a386Sopenharmony_ci} 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ciGrProcessorSet::GrProcessorSet(SkBlendMode mode) : fXP(SkBlendMode_AsXPFactory(mode)) {} 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ciGrProcessorSet::GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP) 35cb93a386Sopenharmony_ci : fXP((const GrXPFactory*)nullptr) { 36cb93a386Sopenharmony_ci SkASSERT(colorFP); 37cb93a386Sopenharmony_ci fColorFragmentProcessor = std::move(colorFP); 38cb93a386Sopenharmony_ci} 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ciGrProcessorSet::GrProcessorSet(GrProcessorSet&& that) 41cb93a386Sopenharmony_ci : fColorFragmentProcessor(std::move(that.fColorFragmentProcessor)) 42cb93a386Sopenharmony_ci , fCoverageFragmentProcessor(std::move(that.fCoverageFragmentProcessor)) 43cb93a386Sopenharmony_ci , fXP(std::move(that.fXP)) 44cb93a386Sopenharmony_ci , fFlags(that.fFlags) {} 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ciGrProcessorSet::~GrProcessorSet() { 47cb93a386Sopenharmony_ci if (this->isFinalized() && this->xferProcessor()) { 48cb93a386Sopenharmony_ci this->xferProcessor()->unref(); 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci} 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci#if GR_TEST_UTILS 53cb93a386Sopenharmony_ciSkString GrProcessorSet::dumpProcessors() const { 54cb93a386Sopenharmony_ci SkString result; 55cb93a386Sopenharmony_ci if (this->hasColorFragmentProcessor()) { 56cb93a386Sopenharmony_ci result.append("Color Fragment Processor:\n"); 57cb93a386Sopenharmony_ci result += this->colorFragmentProcessor()->dumpTreeInfo(); 58cb93a386Sopenharmony_ci } else { 59cb93a386Sopenharmony_ci result.append("No color fragment processor.\n"); 60cb93a386Sopenharmony_ci } 61cb93a386Sopenharmony_ci if (this->hasCoverageFragmentProcessor()) { 62cb93a386Sopenharmony_ci result.append("Coverage Fragment Processor:\n"); 63cb93a386Sopenharmony_ci result += this->coverageFragmentProcessor()->dumpTreeInfo(); 64cb93a386Sopenharmony_ci } else { 65cb93a386Sopenharmony_ci result.append("No coverage fragment processors.\n"); 66cb93a386Sopenharmony_ci } 67cb93a386Sopenharmony_ci if (this->isFinalized()) { 68cb93a386Sopenharmony_ci result.append("Xfer Processor: "); 69cb93a386Sopenharmony_ci if (this->xferProcessor()) { 70cb93a386Sopenharmony_ci result.appendf("%s\n", this->xferProcessor()->name()); 71cb93a386Sopenharmony_ci } else { 72cb93a386Sopenharmony_ci result.append("SrcOver\n"); 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci } else { 75cb93a386Sopenharmony_ci result.append("XP Factory dumping not implemented.\n"); 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci return result; 78cb93a386Sopenharmony_ci} 79cb93a386Sopenharmony_ci#endif 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_cibool GrProcessorSet::operator==(const GrProcessorSet& that) const { 82cb93a386Sopenharmony_ci SkASSERT(this->isFinalized()); 83cb93a386Sopenharmony_ci SkASSERT(that.isFinalized()); 84cb93a386Sopenharmony_ci if (((fFlags ^ that.fFlags) & ~kFinalized_Flag) || 85cb93a386Sopenharmony_ci this->hasColorFragmentProcessor() != that.hasColorFragmentProcessor() || 86cb93a386Sopenharmony_ci this->hasCoverageFragmentProcessor() != that.hasCoverageFragmentProcessor()) { 87cb93a386Sopenharmony_ci return false; 88cb93a386Sopenharmony_ci } 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ci if (this->hasColorFragmentProcessor()) { 91cb93a386Sopenharmony_ci if (!colorFragmentProcessor()->isEqual(*that.colorFragmentProcessor())) { 92cb93a386Sopenharmony_ci return false; 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci if (this->hasCoverageFragmentProcessor()) { 97cb93a386Sopenharmony_ci if (!coverageFragmentProcessor()->isEqual(*that.coverageFragmentProcessor())) { 98cb93a386Sopenharmony_ci return false; 99cb93a386Sopenharmony_ci } 100cb93a386Sopenharmony_ci } 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_ci // Most of the time both of these are null 103cb93a386Sopenharmony_ci if (!this->xferProcessor() && !that.xferProcessor()) { 104cb93a386Sopenharmony_ci return true; 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci const GrXferProcessor& thisXP = this->xferProcessor() 107cb93a386Sopenharmony_ci ? *this->xferProcessor() 108cb93a386Sopenharmony_ci : GrPorterDuffXPFactory::SimpleSrcOverXP(); 109cb93a386Sopenharmony_ci const GrXferProcessor& thatXP = that.xferProcessor() 110cb93a386Sopenharmony_ci ? *that.xferProcessor() 111cb93a386Sopenharmony_ci : GrPorterDuffXPFactory::SimpleSrcOverXP(); 112cb93a386Sopenharmony_ci return thisXP.isEqual(thatXP); 113cb93a386Sopenharmony_ci} 114cb93a386Sopenharmony_ci 115cb93a386Sopenharmony_ciGrProcessorSet::Analysis GrProcessorSet::finalize( 116cb93a386Sopenharmony_ci const GrProcessorAnalysisColor& colorInput, const GrProcessorAnalysisCoverage coverageInput, 117cb93a386Sopenharmony_ci const GrAppliedClip* clip, const GrUserStencilSettings* userStencil, 118cb93a386Sopenharmony_ci const GrCaps& caps, GrClampType clampType, SkPMColor4f* overrideInputColor) { 119cb93a386Sopenharmony_ci SkASSERT(!this->isFinalized()); 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci GrProcessorSet::Analysis analysis; 122cb93a386Sopenharmony_ci analysis.fCompatibleWithCoverageAsAlpha = GrProcessorAnalysisCoverage::kLCD != coverageInput; 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ci GrColorFragmentProcessorAnalysis colorAnalysis(colorInput, &fColorFragmentProcessor, 125cb93a386Sopenharmony_ci this->hasColorFragmentProcessor() ? 1 : 0); 126cb93a386Sopenharmony_ci bool hasCoverageFP = this->hasCoverageFragmentProcessor(); 127cb93a386Sopenharmony_ci bool coverageUsesLocalCoords = false; 128cb93a386Sopenharmony_ci if (hasCoverageFP) { 129cb93a386Sopenharmony_ci if (!fCoverageFragmentProcessor->compatibleWithCoverageAsAlpha()) { 130cb93a386Sopenharmony_ci analysis.fCompatibleWithCoverageAsAlpha = false; 131cb93a386Sopenharmony_ci } 132cb93a386Sopenharmony_ci coverageUsesLocalCoords |= fCoverageFragmentProcessor->usesSampleCoords(); 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci if (clip && clip->hasCoverageFragmentProcessor()) { 135cb93a386Sopenharmony_ci hasCoverageFP = true; 136cb93a386Sopenharmony_ci const GrFragmentProcessor* clipFP = clip->coverageFragmentProcessor(); 137cb93a386Sopenharmony_ci analysis.fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha(); 138cb93a386Sopenharmony_ci coverageUsesLocalCoords |= clipFP->usesSampleCoords(); 139cb93a386Sopenharmony_ci } 140cb93a386Sopenharmony_ci int colorFPsToEliminate = colorAnalysis.initialProcessorsToEliminate(overrideInputColor); 141cb93a386Sopenharmony_ci analysis.fInputColorType = static_cast<Analysis::PackedInputColorType>( 142cb93a386Sopenharmony_ci colorFPsToEliminate ? Analysis::kOverridden_InputColorType 143cb93a386Sopenharmony_ci : Analysis::kOriginal_InputColorType); 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_ci GrProcessorAnalysisCoverage outputCoverage; 146cb93a386Sopenharmony_ci if (GrProcessorAnalysisCoverage::kLCD == coverageInput) { 147cb93a386Sopenharmony_ci outputCoverage = GrProcessorAnalysisCoverage::kLCD; 148cb93a386Sopenharmony_ci } else if (hasCoverageFP || GrProcessorAnalysisCoverage::kSingleChannel == coverageInput) { 149cb93a386Sopenharmony_ci outputCoverage = GrProcessorAnalysisCoverage::kSingleChannel; 150cb93a386Sopenharmony_ci } else { 151cb93a386Sopenharmony_ci outputCoverage = GrProcessorAnalysisCoverage::kNone; 152cb93a386Sopenharmony_ci } 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_ci GrXPFactory::AnalysisProperties props = GrXPFactory::GetAnalysisProperties( 155cb93a386Sopenharmony_ci this->xpFactory(), colorAnalysis.outputColor(), outputCoverage, caps, clampType); 156cb93a386Sopenharmony_ci analysis.fRequiresDstTexture = (props & GrXPFactory::AnalysisProperties::kRequiresDstTexture) || 157cb93a386Sopenharmony_ci colorAnalysis.requiresDstTexture(caps); 158cb93a386Sopenharmony_ci analysis.fCompatibleWithCoverageAsAlpha &= 159cb93a386Sopenharmony_ci SkToBool(props & GrXPFactory::AnalysisProperties::kCompatibleWithCoverageAsAlpha); 160cb93a386Sopenharmony_ci analysis.fRequiresNonOverlappingDraws = 161cb93a386Sopenharmony_ci (props & GrXPFactory::AnalysisProperties::kRequiresNonOverlappingDraws) || 162cb93a386Sopenharmony_ci analysis.fRequiresDstTexture; 163cb93a386Sopenharmony_ci analysis.fUsesNonCoherentHWBlending = 164cb93a386Sopenharmony_ci SkToBool(props & GrXPFactory::AnalysisProperties::kUsesNonCoherentHWBlending); 165cb93a386Sopenharmony_ci analysis.fUnaffectedByDstValue = 166cb93a386Sopenharmony_ci SkToBool(props & GrXPFactory::AnalysisProperties::kUnaffectedByDstValue); 167cb93a386Sopenharmony_ci if (props & GrXPFactory::AnalysisProperties::kIgnoresInputColor) { 168cb93a386Sopenharmony_ci colorFPsToEliminate = this->hasColorFragmentProcessor() ? 1 : 0; 169cb93a386Sopenharmony_ci analysis.fInputColorType = 170cb93a386Sopenharmony_ci static_cast<Analysis::PackedInputColorType>(Analysis::kIgnored_InputColorType); 171cb93a386Sopenharmony_ci analysis.fUsesLocalCoords = coverageUsesLocalCoords; 172cb93a386Sopenharmony_ci } else { 173cb93a386Sopenharmony_ci analysis.fCompatibleWithCoverageAsAlpha &= 174cb93a386Sopenharmony_ci colorAnalysis.allProcessorsCompatibleWithCoverageAsAlpha(); 175cb93a386Sopenharmony_ci analysis.fUsesLocalCoords = coverageUsesLocalCoords || colorAnalysis.usesLocalCoords(); 176cb93a386Sopenharmony_ci } 177cb93a386Sopenharmony_ci if (colorFPsToEliminate) { 178cb93a386Sopenharmony_ci SkASSERT(colorFPsToEliminate == 1); 179cb93a386Sopenharmony_ci fColorFragmentProcessor = nullptr; 180cb93a386Sopenharmony_ci } 181cb93a386Sopenharmony_ci analysis.fHasColorFragmentProcessor = this->hasColorFragmentProcessor(); 182cb93a386Sopenharmony_ci 183cb93a386Sopenharmony_ci auto xp = GrXPFactory::MakeXferProcessor(this->xpFactory(), colorAnalysis.outputColor(), 184cb93a386Sopenharmony_ci outputCoverage, caps, clampType); 185cb93a386Sopenharmony_ci fXP.fProcessor = xp.release(); 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ci fFlags |= kFinalized_Flag; 188cb93a386Sopenharmony_ci analysis.fIsInitialized = true; 189cb93a386Sopenharmony_ci#ifdef SK_DEBUG 190cb93a386Sopenharmony_ci bool hasXferBarrier = 191cb93a386Sopenharmony_ci fXP.fProcessor && 192cb93a386Sopenharmony_ci GrXferBarrierType::kNone_GrXferBarrierType != fXP.fProcessor->xferBarrierType(caps); 193cb93a386Sopenharmony_ci bool needsNonOverlappingDraws = analysis.fRequiresDstTexture || hasXferBarrier; 194cb93a386Sopenharmony_ci SkASSERT(analysis.fRequiresNonOverlappingDraws == needsNonOverlappingDraws); 195cb93a386Sopenharmony_ci#endif 196cb93a386Sopenharmony_ci return analysis; 197cb93a386Sopenharmony_ci} 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_civoid GrProcessorSet::visitProxies(const GrVisitProxyFunc& func) const { 200cb93a386Sopenharmony_ci if (this->hasColorFragmentProcessor()) { 201cb93a386Sopenharmony_ci fColorFragmentProcessor->visitProxies(func); 202cb93a386Sopenharmony_ci } 203cb93a386Sopenharmony_ci if (this->hasCoverageFragmentProcessor()) { 204cb93a386Sopenharmony_ci fCoverageFragmentProcessor->visitProxies(func); 205cb93a386Sopenharmony_ci } 206cb93a386Sopenharmony_ci} 207