blob: ff2361b156e096fb4ef39ee516f09bdc6f2881ad [file] [log] [blame]
Brian Salomon92ce5942017-01-18 11:01:10 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/core/SkBlendModePriv.h"
9#include "src/gpu/GrAppliedClip.h"
10#include "src/gpu/GrCaps.h"
11#include "src/gpu/GrProcessorSet.h"
12#include "src/gpu/GrUserStencilSettings.h"
13#include "src/gpu/GrXferProcessor.h"
14#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
Brian Salomon92ce5942017-01-18 11:01:10 -050015
Brian Salomon292bf7a2017-05-17 09:43:55 -040016const GrProcessorSet& GrProcessorSet::EmptySet() {
Brian Salomon91326c32017-08-09 16:02:19 -040017 static GrProcessorSet gEmpty(GrProcessorSet::Empty::kEmpty);
Brian Salomon292bf7a2017-05-17 09:43:55 -040018 return gEmpty;
19}
Brian Salomon6d4b65e2017-05-03 17:06:09 -040020
Brian Salomon91326c32017-08-09 16:02:19 -040021GrProcessorSet GrProcessorSet::MakeEmptySet() {
22 return GrProcessorSet(GrProcessorSet::Empty::kEmpty);
23}
24
Brian Salomon48d1b4c2017-04-08 07:38:53 -040025GrProcessorSet::GrProcessorSet(GrPaint&& paint) : fXP(paint.getXPFactory()) {
John Stiles29d3e222020-07-21 17:28:12 -040026 fColorFragmentProcessor = std::move(paint.fColorFragmentProcessor);
27 fCoverageFragmentProcessor = std::move(paint.fCoverageFragmentProcessor);
John Stiles5933d7d2020-07-21 12:28:35 -040028
Mike Klein16885072018-12-11 09:54:31 -050029 SkDEBUGCODE(paint.fAlive = false;)
Brian Salomon92ce5942017-01-18 11:01:10 -050030}
Brian Salomon5298dc82017-02-22 11:52:03 -050031
John Stiles29d3e222020-07-21 17:28:12 -040032GrProcessorSet::GrProcessorSet(SkBlendMode mode) : fXP(SkBlendMode_AsXPFactory(mode)) {}
Brian Salomon477d0ef2017-07-14 10:12:26 -040033
Brian Salomonaff329b2017-08-11 09:40:37 -040034GrProcessorSet::GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP)
John Stiles29d3e222020-07-21 17:28:12 -040035 : fXP((const GrXPFactory*)nullptr) {
Brian Salomon82ddc942017-07-14 12:00:13 -040036 SkASSERT(colorFP);
John Stiles29d3e222020-07-21 17:28:12 -040037 fColorFragmentProcessor = std::move(colorFP);
Brian Salomon82ddc942017-07-14 12:00:13 -040038}
39
Brian Salomon91326c32017-08-09 16:02:19 -040040GrProcessorSet::GrProcessorSet(GrProcessorSet&& that)
John Stiles29d3e222020-07-21 17:28:12 -040041 : fColorFragmentProcessor(std::move(that.fColorFragmentProcessor))
42 , fCoverageFragmentProcessor(std::move(that.fCoverageFragmentProcessor))
43 , fXP(std::move(that.fXP))
44 , fFlags(that.fFlags) {}
Brian Salomon91326c32017-08-09 16:02:19 -040045
Brian Salomon54d212e2017-03-21 14:22:38 -040046GrProcessorSet::~GrProcessorSet() {
Brian Salomon48d1b4c2017-04-08 07:38:53 -040047 if (this->isFinalized() && this->xferProcessor()) {
Brian Salomond61c9d92017-04-10 10:54:25 -040048 this->xferProcessor()->unref();
Brian Salomon54d212e2017-03-21 14:22:38 -040049 }
50}
51
John Stiles8d9bf642020-08-12 15:07:45 -040052#if GR_TEST_UTILS
Brian Salomon82dfd3d2017-06-14 12:30:35 -040053SkString GrProcessorSet::dumpProcessors() const {
54 SkString result;
John Stiles29d3e222020-07-21 17:28:12 -040055 if (this->hasColorFragmentProcessor()) {
56 result.append("Color Fragment Processor:\n");
John Stilesba1879d2020-08-11 13:58:32 -040057 result += this->colorFragmentProcessor()->dumpTreeInfo();
Brian Salomon82dfd3d2017-06-14 12:30:35 -040058 } else {
John Stiles29d3e222020-07-21 17:28:12 -040059 result.append("No color fragment processor.\n");
60 }
John Stilesdf9ed892020-08-12 18:07:26 -040061 if (this->hasCoverageFragmentProcessor()) {
John Stiles29d3e222020-07-21 17:28:12 -040062 result.append("Coverage Fragment Processor:\n");
John Stilesba1879d2020-08-11 13:58:32 -040063 result += this->coverageFragmentProcessor()->dumpTreeInfo();
John Stiles29d3e222020-07-21 17:28:12 -040064 } else {
65 result.append("No coverage fragment processors.\n");
Brian Salomon82dfd3d2017-06-14 12:30:35 -040066 }
67 if (this->isFinalized()) {
68 result.append("Xfer Processor: ");
69 if (this->xferProcessor()) {
70 result.appendf("%s\n", this->xferProcessor()->name());
71 } else {
72 result.append("SrcOver\n");
73 }
74 } else {
Derek Sollenberger08c06292019-01-24 16:30:28 +000075 result.append("XP Factory dumping not implemented.\n");
Brian Salomon82dfd3d2017-06-14 12:30:35 -040076 }
77 return result;
78}
Brian Osman9a390ac2018-11-12 09:47:48 -050079#endif
Brian Salomon82dfd3d2017-06-14 12:30:35 -040080
Brian Salomon54d212e2017-03-21 14:22:38 -040081bool GrProcessorSet::operator==(const GrProcessorSet& that) const {
Brian Salomon48d1b4c2017-04-08 07:38:53 -040082 SkASSERT(this->isFinalized());
83 SkASSERT(that.isFinalized());
John Stiles29d3e222020-07-21 17:28:12 -040084 if (((fFlags ^ that.fFlags) & ~kFinalized_Flag) ||
85 this->hasColorFragmentProcessor() != that.hasColorFragmentProcessor() ||
86 this->hasCoverageFragmentProcessor() != that.hasCoverageFragmentProcessor()) {
Brian Salomon54d212e2017-03-21 14:22:38 -040087 return false;
88 }
Brian Salomon70288c02017-03-24 12:27:17 -040089
John Stiles29d3e222020-07-21 17:28:12 -040090 if (this->hasColorFragmentProcessor()) {
91 if (!colorFragmentProcessor()->isEqual(*that.colorFragmentProcessor())) {
Brian Salomon54d212e2017-03-21 14:22:38 -040092 return false;
93 }
94 }
John Stiles29d3e222020-07-21 17:28:12 -040095
96 if (this->hasCoverageFragmentProcessor()) {
97 if (!coverageFragmentProcessor()->isEqual(*that.coverageFragmentProcessor())) {
98 return false;
99 }
100 }
101
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400102 // Most of the time both of these are null
103 if (!this->xferProcessor() && !that.xferProcessor()) {
104 return true;
Brian Salomon54d212e2017-03-21 14:22:38 -0400105 }
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400106 const GrXferProcessor& thisXP = this->xferProcessor()
107 ? *this->xferProcessor()
108 : GrPorterDuffXPFactory::SimpleSrcOverXP();
109 const GrXferProcessor& thatXP = that.xferProcessor()
110 ? *that.xferProcessor()
111 : GrPorterDuffXPFactory::SimpleSrcOverXP();
112 return thisXP.isEqual(thatXP);
Brian Salomon54d212e2017-03-21 14:22:38 -0400113}
114
Chris Daltonb8fff0d2019-03-05 10:11:58 -0700115GrProcessorSet::Analysis GrProcessorSet::finalize(
116 const GrProcessorAnalysisColor& colorInput, const GrProcessorAnalysisCoverage coverageInput,
Chris Dalton6ce447a2019-06-23 18:07:38 -0600117 const GrAppliedClip* clip, const GrUserStencilSettings* userStencil,
118 bool hasMixedSampledCoverage, const GrCaps& caps, GrClampType clampType,
119 SkPMColor4f* overrideInputColor) {
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400120 SkASSERT(!this->isFinalized());
Brian Salomon5298dc82017-02-22 11:52:03 -0500121
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400122 GrProcessorSet::Analysis analysis;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400123 analysis.fCompatibleWithCoverageAsAlpha = GrProcessorAnalysisCoverage::kLCD != coverageInput;
124
John Stiles29d3e222020-07-21 17:28:12 -0400125 GrColorFragmentProcessorAnalysis colorAnalysis(colorInput, &fColorFragmentProcessor,
126 this->hasColorFragmentProcessor() ? 1 : 0);
127 bool hasCoverageFP = this->hasCoverageFragmentProcessor();
Brian Salomon31853842017-03-28 16:32:05 -0400128 bool coverageUsesLocalCoords = false;
John Stiles29d3e222020-07-21 17:28:12 -0400129 if (hasCoverageFP) {
130 if (!fCoverageFragmentProcessor->compatibleWithCoverageAsAlpha()) {
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400131 analysis.fCompatibleWithCoverageAsAlpha = false;
Brian Salomon5298dc82017-02-22 11:52:03 -0500132 }
John Stiles29d3e222020-07-21 17:28:12 -0400133 coverageUsesLocalCoords |= fCoverageFragmentProcessor->usesVaryingCoords();
Brian Salomon5298dc82017-02-22 11:52:03 -0500134 }
John Stiles59e18dc2020-07-22 18:18:12 -0400135 if (clip && clip->hasCoverageFragmentProcessor()) {
136 hasCoverageFP = true;
137 const GrFragmentProcessor* clipFP = clip->coverageFragmentProcessor();
138 analysis.fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha();
139 coverageUsesLocalCoords |= clipFP->usesVaryingCoords();
Brian Salomon5298dc82017-02-22 11:52:03 -0500140 }
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400141 int colorFPsToEliminate = colorAnalysis.initialProcessorsToEliminate(overrideInputColor);
142 analysis.fInputColorType = static_cast<Analysis::PackedInputColorType>(
143 colorFPsToEliminate ? Analysis::kOverridden_InputColorType
144 : Analysis::kOriginal_InputColorType);
Brian Salomon5298dc82017-02-22 11:52:03 -0500145
Brian Salomona811b122017-03-30 08:21:32 -0400146 GrProcessorAnalysisCoverage outputCoverage;
147 if (GrProcessorAnalysisCoverage::kLCD == coverageInput) {
148 outputCoverage = GrProcessorAnalysisCoverage::kLCD;
149 } else if (hasCoverageFP || GrProcessorAnalysisCoverage::kSingleChannel == coverageInput) {
150 outputCoverage = GrProcessorAnalysisCoverage::kSingleChannel;
Brian Salomon5298dc82017-02-22 11:52:03 -0500151 } else {
Brian Salomona811b122017-03-30 08:21:32 -0400152 outputCoverage = GrProcessorAnalysisCoverage::kNone;
Brian Salomon31853842017-03-28 16:32:05 -0400153 }
Brian Salomon31853842017-03-28 16:32:05 -0400154
155 GrXPFactory::AnalysisProperties props = GrXPFactory::GetAnalysisProperties(
Chris Dalton2833ec62020-12-03 01:43:08 -0700156 this->xpFactory(), colorAnalysis.outputColor(), outputCoverage, hasMixedSampledCoverage,
157 caps, clampType);
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400158 analysis.fRequiresDstTexture =
159 SkToBool(props & GrXPFactory::AnalysisProperties::kRequiresDstTexture);
160 analysis.fCompatibleWithCoverageAsAlpha &=
Brian Osman605c6d52019-03-15 12:10:35 -0400161 SkToBool(props & GrXPFactory::AnalysisProperties::kCompatibleWithCoverageAsAlpha);
John Stiles29d3e222020-07-21 17:28:12 -0400162 analysis.fRequiresNonOverlappingDraws =
163 SkToBool(props & GrXPFactory::AnalysisProperties::kRequiresNonOverlappingDraws);
Greg Daniel9a18b082020-08-14 14:03:50 -0400164 analysis.fUsesNonCoherentHWBlending =
165 SkToBool(props & GrXPFactory::AnalysisProperties::kUsesNonCoherentHWBlending);
Chris Daltonf2fb80f2020-12-03 12:37:59 -0700166 analysis.fUnaffectedByDstValue =
167 SkToBool(props & GrXPFactory::AnalysisProperties::kUnaffectedByDstValue);
Brian Salomon31853842017-03-28 16:32:05 -0400168 if (props & GrXPFactory::AnalysisProperties::kIgnoresInputColor) {
John Stiles29d3e222020-07-21 17:28:12 -0400169 colorFPsToEliminate = this->hasColorFragmentProcessor() ? 1 : 0;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400170 analysis.fInputColorType =
171 static_cast<Analysis::PackedInputColorType>(Analysis::kIgnored_InputColorType);
172 analysis.fUsesLocalCoords = coverageUsesLocalCoords;
Brian Salomon31853842017-03-28 16:32:05 -0400173 } else {
Michael Ludwig0cb2fde2019-05-28 13:14:41 -0400174 analysis.fCompatibleWithCoverageAsAlpha &=
175 colorAnalysis.allProcessorsCompatibleWithCoverageAsAlpha();
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400176 analysis.fUsesLocalCoords = coverageUsesLocalCoords | colorAnalysis.usesLocalCoords();
Brian Salomon5298dc82017-02-22 11:52:03 -0500177 }
John Stiles29d3e222020-07-21 17:28:12 -0400178 if (colorFPsToEliminate) {
179 SkASSERT(colorFPsToEliminate == 1);
180 fColorFragmentProcessor = nullptr;
Brian Salomon5dac9b32017-04-08 02:53:30 +0000181 }
John Stiles29d3e222020-07-21 17:28:12 -0400182 analysis.fHasColorFragmentProcessor = this->hasColorFragmentProcessor();
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400183
184 auto xp = GrXPFactory::MakeXferProcessor(this->xpFactory(), colorAnalysis.outputColor(),
Brian Osman5ced0bf2019-03-15 10:15:29 -0400185 outputCoverage, hasMixedSampledCoverage, caps,
186 clampType);
Brian Salomond61c9d92017-04-10 10:54:25 -0400187 fXP.fProcessor = xp.release();
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400188
Brian Salomond61c9d92017-04-10 10:54:25 -0400189 fFlags |= kFinalized_Flag;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400190 analysis.fIsInitialized = true;
Chris Dalton945ee652019-01-23 09:10:36 -0700191#ifdef SK_DEBUG
192 bool hasXferBarrier =
193 fXP.fProcessor &&
194 GrXferBarrierType::kNone_GrXferBarrierType != fXP.fProcessor->xferBarrierType(caps);
195 bool needsNonOverlappingDraws = analysis.fRequiresDstTexture || hasXferBarrier;
196 SkASSERT(analysis.fRequiresNonOverlappingDraws == needsNonOverlappingDraws);
197#endif
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400198 return analysis;
Brian Salomon70288c02017-03-24 12:27:17 -0400199}
Brian Salomonc241b582019-11-27 08:57:17 -0500200
201void GrProcessorSet::visitProxies(const GrOp::VisitProxyFunc& func) const {
John Stiles29d3e222020-07-21 17:28:12 -0400202 if (this->hasColorFragmentProcessor()) {
203 fColorFragmentProcessor->visitProxies(func);
204 }
205 if (this->hasCoverageFragmentProcessor()) {
206 fCoverageFragmentProcessor->visitProxies(func);
Brian Salomonc241b582019-11-27 08:57:17 -0500207 }
208}