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