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