blob: f358a47d146a407f3187c1c76803422b5a9ae0bf [file] [log] [blame]
bsalomonbf877302015-09-22 09:06:13 -07001/*
2* Copyright 2015 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/gpu/GrCoordTransform.h"
9#include "src/gpu/GrFragmentProcessor.h"
10#include "src/gpu/GrPipeline.h"
11#include "src/gpu/GrProcessorAnalysis.h"
12#include "src/gpu/effects/GrXfermodeFragmentProcessor.h"
Brian Osman6f5e9402020-01-22 10:39:31 -050013#include "src/gpu/effects/generated/GrClampFragmentProcessor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/effects/generated/GrConstColorProcessor.h"
15#include "src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
17#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
18#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
19#include "src/gpu/glsl/GrGLSLUniformHandler.h"
bsalomonbf877302015-09-22 09:06:13 -070020
bsalomon7312ff82016-09-12 08:55:38 -070021bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
Brian Salomone782f842018-07-31 13:53:11 -040022 if (this->classID() != that.classID()) {
bsalomonbf877302015-09-22 09:06:13 -070023 return false;
24 }
Brian Salomone782f842018-07-31 13:53:11 -040025 if (this->numTextureSamplers() != that.numTextureSamplers()) {
26 return false;
27 }
28 for (int i = 0; i < this->numTextureSamplers(); ++i) {
29 if (this->textureSampler(i) != that.textureSampler(i)) {
30 return false;
31 }
32 }
bsalomon7312ff82016-09-12 08:55:38 -070033 if (!this->hasSameTransforms(that)) {
bsalomonbf877302015-09-22 09:06:13 -070034 return false;
35 }
36 if (!this->onIsEqual(that)) {
37 return false;
38 }
39 if (this->numChildProcessors() != that.numChildProcessors()) {
40 return false;
41 }
42 for (int i = 0; i < this->numChildProcessors(); ++i) {
bsalomon7312ff82016-09-12 08:55:38 -070043 if (!this->childProcessor(i).isEqual(that.childProcessor(i))) {
bsalomonbf877302015-09-22 09:06:13 -070044 return false;
45 }
46 }
47 return true;
48}
49
Chris Dalton7eb5c0f2019-05-23 15:15:47 -060050void GrFragmentProcessor::visitProxies(const GrOp::VisitProxyFunc& func) {
Brian Salomonc241b582019-11-27 08:57:17 -050051 for (auto [sampler, fp] : FPTextureSamplerRange(*this)) {
52 bool mipped = (GrSamplerState::Filter::kMipMap == sampler.samplerState().filter());
Robert Phillipsbd99c0c2019-12-12 13:26:58 +000053 func(sampler.view().proxy(), GrMipMapped(mipped));
Brian Salomone782f842018-07-31 13:53:11 -040054 }
55}
56
egdaniel57d3b032015-11-13 11:57:27 -080057GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const {
58 GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance();
bsalomonbf877302015-09-22 09:06:13 -070059 glFragProc->fChildProcessors.push_back_n(fChildProcessors.count());
60 for (int i = 0; i < fChildProcessors.count(); ++i) {
egdaniel57d3b032015-11-13 11:57:27 -080061 glFragProc->fChildProcessors[i] = fChildProcessors[i]->createGLSLInstance();
bsalomonbf877302015-09-22 09:06:13 -070062 }
63 return glFragProc;
64}
65
Brian Salomone782f842018-07-31 13:53:11 -040066const GrFragmentProcessor::TextureSampler& GrFragmentProcessor::textureSampler(int i) const {
67 SkASSERT(i >= 0 && i < fTextureSamplerCnt);
68 return this->onTextureSampler(i);
69}
70
Michael Ludwige88320b2020-06-24 09:04:56 -040071int GrFragmentProcessor::numCoordTransforms() const {
Michael Ludwigfbe28592020-06-26 16:02:15 -040072 if (SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag) && !this->isSampledWithExplicitCoords()) {
Michael Ludwige88320b2020-06-24 09:04:56 -040073 // coordTransform(0) will return an implicitly defined coord transform so that varyings are
74 // added for this FP in order to support const/uniform sample matrix lifting.
75 return 1;
76 } else {
Michael Ludwigfbe28592020-06-26 16:02:15 -040077 return 0;
Michael Ludwige88320b2020-06-24 09:04:56 -040078 }
79}
80
81const GrCoordTransform& GrFragmentProcessor::coordTransform(int i) const {
Michael Ludwigfbe28592020-06-26 16:02:15 -040082 SkASSERT(i == 0 && SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag) &&
83 !this->isSampledWithExplicitCoords());
84 // as things stand, matrices only work when there's a coord transform, so we need to add
85 // an identity transform to keep the downstream code happy
86 static const GrCoordTransform kImplicitIdentity;
87 return kImplicitIdentity;
bsalomonbf877302015-09-22 09:06:13 -070088}
89
Ethan Nicholasd3a95c22020-06-03 13:24:46 -040090void GrFragmentProcessor::setSampleMatrix(SkSL::SampleMatrix newMatrix) {
Michael Ludwige88320b2020-06-24 09:04:56 -040091 SkASSERT(!newMatrix.isNoOp());
92 SkASSERT(fMatrix.isNoOp());
93
94 fMatrix = newMatrix;
95 // When an FP is sampled using variable matrix expressions, it is effectively being sampled
96 // explicitly, except that the call site will automatically evaluate the matrix expression to
97 // produce the float2 passed into this FP.
98 if (fMatrix.isVariable()) {
99 this->addAndPushFlagToChildren(kSampledWithExplicitCoords_Flag);
Ethan Nicholas58430122020-04-14 09:54:02 -0400100 }
Michael Ludwige88320b2020-06-24 09:04:56 -0400101 // Push perspective matrix type to children
102 if (fMatrix.fHasPerspective) {
103 this->addAndPushFlagToChildren(kNetTransformHasPerspective_Flag);
Ethan Nicholas58430122020-04-14 09:54:02 -0400104 }
105}
106
Michael Ludwige88320b2020-06-24 09:04:56 -0400107void GrFragmentProcessor::addAndPushFlagToChildren(PrivateFlags flag) {
108 // This propagates down, so if we've already marked it, all our children should have it too
109 if (!(fFlags & flag)) {
110 fFlags |= flag;
111 for (auto& child : fChildProcessors) {
112 child->addAndPushFlagToChildren(flag);
113 }
Michael Ludwig9aba6252020-06-22 14:46:36 -0400114 }
Michael Ludwige88320b2020-06-24 09:04:56 -0400115#ifdef SK_DEBUG
116 for (auto& child : fChildProcessors) {
117 SkASSERT(child->fFlags & flag);
118 }
119#endif
Michael Ludwig9aba6252020-06-22 14:46:36 -0400120}
121
Robert Phillips82774f82019-06-20 14:38:27 -0400122#ifdef SK_DEBUG
123bool GrFragmentProcessor::isInstantiated() const {
Brian Salomone782f842018-07-31 13:53:11 -0400124 for (int i = 0; i < fTextureSamplerCnt; ++i) {
Robert Phillips82774f82019-06-20 14:38:27 -0400125 if (!this->textureSampler(i).isInstantiated()) {
Brian Salomone782f842018-07-31 13:53:11 -0400126 return false;
127 }
Robert Phillipsa91e0b72017-05-01 13:12:20 -0400128 }
129
Robert Phillips9bee2e52017-05-29 12:37:20 -0400130 for (int i = 0; i < this->numChildProcessors(); ++i) {
Robert Phillips82774f82019-06-20 14:38:27 -0400131 if (!this->childProcessor(i).isInstantiated()) {
Robert Phillips9bee2e52017-05-29 12:37:20 -0400132 return false;
133 }
134 }
135
136 return true;
137}
Robert Phillips82774f82019-06-20 14:38:27 -0400138#endif
Robert Phillips9bee2e52017-05-29 12:37:20 -0400139
Michael Ludwig9aba6252020-06-22 14:46:36 -0400140int GrFragmentProcessor::registerChild(std::unique_ptr<GrFragmentProcessor> child,
141 SkSL::SampleMatrix sampleMatrix,
142 bool explicitlySampled) {
Michael Ludwige88320b2020-06-24 09:04:56 -0400143 // The child should not have been attached to another FP already and not had any sampling
144 // strategy set on it.
145 SkASSERT(child && !child->fParent && child->sampleMatrix().isNoOp() &&
146 !child->isSampledWithExplicitCoords() && !child->hasPerspectiveTransform());
147
Michael Ludwig9aba6252020-06-22 14:46:36 -0400148 // Configure child's sampling state first
149 if (explicitlySampled) {
Michael Ludwige88320b2020-06-24 09:04:56 -0400150 child->addAndPushFlagToChildren(kSampledWithExplicitCoords_Flag);
Michael Ludwig9aba6252020-06-22 14:46:36 -0400151 }
152 if (sampleMatrix.fKind != SkSL::SampleMatrix::Kind::kNone) {
Michael Ludwig9aba6252020-06-22 14:46:36 -0400153 child->setSampleMatrix(sampleMatrix);
154 }
155
Michael Ludwige88320b2020-06-24 09:04:56 -0400156 if (child->sampleMatrix().fKind == SkSL::SampleMatrix::Kind::kVariable) {
157 // Since the child is sampled with a variable matrix expression, auto-generated code in
158 // invokeChildWithMatrix() for this FP will refer to the local coordinates.
159 this->setUsesSampleCoordsDirectly();
160 }
161
162 // If the child is not sampled explicitly and not already accessing sample coords directly
163 // (through reference or variable matrix expansion), then mark that this FP tree relies on
164 // coordinates at a lower level. If the child is sampled with explicit coordinates and
165 // there isn't any other direct reference to the sample coords, we halt the upwards propagation
166 // because it means this FP is determining coordinates on its own.
167 if (!child->isSampledWithExplicitCoords()) {
168 if ((child->fFlags & kUsesSampleCoordsDirectly_Flag ||
169 child->fFlags & kUsesSampleCoordsIndirectly_Flag)) {
170 fFlags |= kUsesSampleCoordsIndirectly_Flag;
171 }
172 }
173
Chris Daltond7291ba2019-03-07 14:17:03 -0700174 fRequestedFeatures |= child->fRequestedFeatures;
bsalomonbf877302015-09-22 09:06:13 -0700175
bungeman06ca8ec2016-06-09 08:01:03 -0700176 int index = fChildProcessors.count();
Michael Ludwige88320b2020-06-24 09:04:56 -0400177 // Record that the child is attached to us; this FP is the source of any uniform data needed
178 // to evaluate the child sample matrix.
179 child->fParent = this;
Brian Salomonaff329b2017-08-11 09:40:37 -0400180 fChildProcessors.push_back(std::move(child));
Michael Ludwige88320b2020-06-24 09:04:56 -0400181
182 // Sanity check: our sample strategy comes from a parent we shouldn't have yet.
183 SkASSERT(!this->isSampledWithExplicitCoords() && !this->hasPerspectiveTransform() &&
184 fMatrix.isNoOp() && !fParent);
bsalomonbf877302015-09-22 09:06:13 -0700185 return index;
186}
187
John Stiles3779f442020-06-15 10:48:49 -0400188int GrFragmentProcessor::cloneAndRegisterChildProcessor(const GrFragmentProcessor& fp) {
189 std::unique_ptr<GrFragmentProcessor> clone = fp.clone();
Michael Ludwig9aba6252020-06-22 14:46:36 -0400190 return this->registerChild(std::move(clone), fp.sampleMatrix(),
191 fp.isSampledWithExplicitCoords());
John Stiles3779f442020-06-15 10:48:49 -0400192}
193
John Stiles9ec6b052020-06-15 12:06:10 -0400194void GrFragmentProcessor::cloneAndRegisterAllChildProcessors(const GrFragmentProcessor& src) {
195 for (int i = 0; i < src.numChildProcessors(); ++i) {
196 this->cloneAndRegisterChildProcessor(src.childProcessor(i));
197 }
198}
199
bsalomonbf877302015-09-22 09:06:13 -0700200bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
bsalomona624bf32016-09-20 09:12:47 -0700201 if (this->numCoordTransforms() != that.numCoordTransforms()) {
bsalomonbf877302015-09-22 09:06:13 -0700202 return false;
203 }
bsalomona624bf32016-09-20 09:12:47 -0700204 int count = this->numCoordTransforms();
bsalomonbf877302015-09-22 09:06:13 -0700205 for (int i = 0; i < count; ++i) {
Brian Salomon7d8b3972019-11-26 22:34:44 -0500206 if (!this->coordTransform(i).hasSameEffectiveMatrix(that.coordTransform(i))) {
bsalomonbf877302015-09-22 09:06:13 -0700207 return false;
208 }
209 }
210 return true;
211}
212
Mike Reed28eaed22018-02-01 11:24:53 -0500213std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulChildByInputAlpha(
Brian Salomonaff329b2017-08-11 09:40:37 -0400214 std::unique_ptr<GrFragmentProcessor> fp) {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700215 if (!fp) {
216 return nullptr;
217 }
John Stiles5c57e882020-06-30 14:05:03 -0400218 return GrXfermodeFragmentProcessor::Make(/*src=*/nullptr, std::move(fp), SkBlendMode::kDstIn);
bsalomonbf877302015-09-22 09:06:13 -0700219}
220
Mike Reed28eaed22018-02-01 11:24:53 -0500221std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulInputByChildAlpha(
222 std::unique_ptr<GrFragmentProcessor> fp) {
223 if (!fp) {
224 return nullptr;
225 }
John Stiles5c57e882020-06-30 14:05:03 -0400226 return GrXfermodeFragmentProcessor::Make(/*src=*/nullptr, std::move(fp), SkBlendMode::kSrcIn);
Mike Reed28eaed22018-02-01 11:24:53 -0500227}
228
Brian Osman6f5e9402020-01-22 10:39:31 -0500229std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ClampPremulOutput(
230 std::unique_ptr<GrFragmentProcessor> fp) {
231 if (!fp) {
232 return nullptr;
233 }
John Stiles5a2a7b32020-06-04 10:57:21 -0400234 return GrClampFragmentProcessor::Make(std::move(fp), /*clampToPremul=*/true);
Brian Osman6f5e9402020-01-22 10:39:31 -0500235}
236
Brian Salomonaff329b2017-08-11 09:40:37 -0400237std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(
238 std::unique_ptr<GrFragmentProcessor> fp, const GrSwizzle& swizzle) {
Brian Osmance425512017-03-22 14:37:50 -0400239 class SwizzleFragmentProcessor : public GrFragmentProcessor {
240 public:
John Stileseed56f02020-06-04 13:30:51 -0400241 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp,
242 const GrSwizzle& swizzle) {
243 return std::unique_ptr<GrFragmentProcessor>(
244 new SwizzleFragmentProcessor(std::move(fp), swizzle));
Brian Osmance425512017-03-22 14:37:50 -0400245 }
246
247 const char* name() const override { return "Swizzle"; }
248 const GrSwizzle& swizzle() const { return fSwizzle; }
249
John Stileseed56f02020-06-04 13:30:51 -0400250 std::unique_ptr<GrFragmentProcessor> clone() const override {
251 return Make(this->childProcessor(0).clone(), fSwizzle);
252 }
Brian Salomon216f2e02017-07-25 15:52:51 -0400253
Brian Osmance425512017-03-22 14:37:50 -0400254 private:
John Stileseed56f02020-06-04 13:30:51 -0400255 SwizzleFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp, const GrSwizzle& swizzle)
256 : INHERITED(kSwizzleFragmentProcessor_ClassID, ProcessorOptimizationFlags(fp.get()))
257 , fSwizzle(swizzle) {
Michael Ludwig9aba6252020-06-22 14:46:36 -0400258 this->registerChild(std::move(fp));
John Stileseed56f02020-06-04 13:30:51 -0400259 }
Robert Phillips1c9686b2017-06-30 08:40:28 -0400260
Brian Osmance425512017-03-22 14:37:50 -0400261 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
262 class GLFP : public GrGLSLFragmentProcessor {
263 public:
264 void emitCode(EmitArgs& args) override {
John Stiles0af87fe2020-06-05 13:33:09 -0400265 SkString childColor = this->invokeChild(0, args.fInputColor, args);
John Stileseed56f02020-06-04 13:30:51 -0400266
Brian Osmance425512017-03-22 14:37:50 -0400267 const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>();
268 const GrSwizzle& swizzle = sfp.swizzle();
269 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
270
271 fragBuilder->codeAppendf("%s = %s.%s;",
John Stileseed56f02020-06-04 13:30:51 -0400272 args.fOutputColor, childColor.c_str(), swizzle.asString().c_str());
Brian Osmance425512017-03-22 14:37:50 -0400273 }
274 };
275 return new GLFP;
276 }
277
278 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
279 b->add32(fSwizzle.asKey());
280 }
281
282 bool onIsEqual(const GrFragmentProcessor& other) const override {
283 const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>();
284 return fSwizzle == sfp.fSwizzle;
285 }
286
Brian Osman1d5b5982018-10-01 13:41:39 -0400287 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
Brian Osmance425512017-03-22 14:37:50 -0400288 return fSwizzle.applyTo(input);
289 }
290
291 GrSwizzle fSwizzle;
292
293 typedef GrFragmentProcessor INHERITED;
294 };
295
296 if (!fp) {
297 return nullptr;
298 }
299 if (GrSwizzle::RGBA() == swizzle) {
300 return fp;
301 }
John Stileseed56f02020-06-04 13:30:51 -0400302 return SwizzleFragmentProcessor::Make(std::move(fp), swizzle);
Brian Osmance425512017-03-22 14:37:50 -0400303}
304
Brian Salomonaff329b2017-08-11 09:40:37 -0400305std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput(
306 std::unique_ptr<GrFragmentProcessor> fp) {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700307 class PremulFragmentProcessor : public GrFragmentProcessor {
308 public:
Brian Salomonaff329b2017-08-11 09:40:37 -0400309 static std::unique_ptr<GrFragmentProcessor> Make(
310 std::unique_ptr<GrFragmentProcessor> processor) {
311 return std::unique_ptr<GrFragmentProcessor>(
312 new PremulFragmentProcessor(std::move(processor)));
Robert Phillips1c9686b2017-06-30 08:40:28 -0400313 }
314
315 const char* name() const override { return "Premultiply"; }
316
Brian Salomonaff329b2017-08-11 09:40:37 -0400317 std::unique_ptr<GrFragmentProcessor> clone() const override {
Brian Salomon96271cd2017-07-31 16:27:23 -0400318 return Make(this->childProcessor(0).clone());
Brian Salomon216f2e02017-07-25 15:52:51 -0400319 }
320
Robert Phillips1c9686b2017-06-30 08:40:28 -0400321 private:
Brian Salomonaff329b2017-08-11 09:40:37 -0400322 PremulFragmentProcessor(std::unique_ptr<GrFragmentProcessor> processor)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400323 : INHERITED(kPremulFragmentProcessor_ClassID, OptFlags(processor.get())) {
Michael Ludwig9aba6252020-06-22 14:46:36 -0400324 this->registerChild(std::move(processor));
bsalomonf1b7a1d2015-09-28 06:26:28 -0700325 }
326
egdaniel57d3b032015-11-13 11:57:27 -0800327 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
egdaniel64c47282015-11-13 06:54:19 -0800328 class GLFP : public GrGLSLFragmentProcessor {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700329 public:
bsalomonf1b7a1d2015-09-28 06:26:28 -0700330 void emitCode(EmitArgs& args) override {
cdalton85285412016-02-18 12:37:07 -0800331 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
Brian Osman978693c2020-01-24 14:52:10 -0500332 SkString temp = this->invokeChild(0, args);
Brian Osmancddfc5e2020-01-24 10:24:27 -0500333 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, temp.c_str());
egdaniel4ca2e602015-11-18 08:01:26 -0800334 fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor,
Brian Osmancddfc5e2020-01-24 10:24:27 -0500335 args.fInputColor);
egdaniel4ca2e602015-11-18 08:01:26 -0800336 fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
bsalomonf1b7a1d2015-09-28 06:26:28 -0700337 }
338 };
339 return new GLFP;
340 }
341
Brian Salomon94efbf52016-11-29 13:43:05 -0500342 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
bsalomonf1b7a1d2015-09-28 06:26:28 -0700343
344 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
345
Brian Salomon587e08f2017-01-27 10:59:27 -0500346 static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) {
347 OptimizationFlags flags = kNone_OptimizationFlags;
348 if (inner->preservesOpaqueInput()) {
349 flags |= kPreservesOpaqueInput_OptimizationFlag;
350 }
351 if (inner->hasConstantOutputForConstantInput()) {
352 flags |= kConstantOutputForConstantInput_OptimizationFlag;
353 }
354 return flags;
355 }
bsalomonf1b7a1d2015-09-28 06:26:28 -0700356
Brian Osman1d5b5982018-10-01 13:41:39 -0400357 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
358 SkPMColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
Brian Osmanf28e55d2018-10-03 16:35:54 -0400359 SK_PMColor4fWHITE);
Brian Osman1d5b5982018-10-01 13:41:39 -0400360 SkPMColor4f premulInput = SkColor4f{ input.fR, input.fG, input.fB, input.fA }.premul();
361 return premulInput * childColor;
Brian Salomon587e08f2017-01-27 10:59:27 -0500362 }
363
364 typedef GrFragmentProcessor INHERITED;
bsalomonf1b7a1d2015-09-28 06:26:28 -0700365 };
366 if (!fp) {
367 return nullptr;
368 }
Robert Phillips1c9686b2017-06-30 08:40:28 -0400369 return PremulFragmentProcessor::Make(std::move(fp));
bsalomonf1b7a1d2015-09-28 06:26:28 -0700370}
371
372//////////////////////////////////////////////////////////////////////////////
373
Brian Salomonaff329b2017-08-11 09:40:37 -0400374std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(
Brian Salomonc0d79e52019-04-10 15:02:11 -0400375 std::unique_ptr<GrFragmentProcessor> fp, const SkPMColor4f& color, bool useUniform) {
Robert Phillips1c9686b2017-06-30 08:40:28 -0400376 if (!fp) {
377 return nullptr;
378 }
Brian Salomonc0d79e52019-04-10 15:02:11 -0400379 return GrOverrideInputFragmentProcessor::Make(std::move(fp), color, useUniform);
bsalomonf1b7a1d2015-09-28 06:26:28 -0700380}
bsalomone25eea42015-09-29 06:38:55 -0700381
Brian Salomonaff329b2017-08-11 09:40:37 -0400382std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(
Brian Salomon64f42062020-02-14 10:42:45 -0500383 std::unique_ptr<GrFragmentProcessor> series[], int cnt) {
bsalomone25eea42015-09-29 06:38:55 -0700384 class SeriesFragmentProcessor : public GrFragmentProcessor {
385 public:
Brian Salomonaff329b2017-08-11 09:40:37 -0400386 static std::unique_ptr<GrFragmentProcessor> Make(
387 std::unique_ptr<GrFragmentProcessor>* children, int cnt) {
388 return std::unique_ptr<GrFragmentProcessor>(new SeriesFragmentProcessor(children, cnt));
bsalomone25eea42015-09-29 06:38:55 -0700389 }
390
391 const char* name() const override { return "Series"; }
392
Brian Salomonaff329b2017-08-11 09:40:37 -0400393 std::unique_ptr<GrFragmentProcessor> clone() const override {
394 SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> children(this->numChildProcessors());
Brian Salomon216f2e02017-07-25 15:52:51 -0400395 for (int i = 0; i < this->numChildProcessors(); ++i) {
396 if (!children.push_back(this->childProcessor(i).clone())) {
397 return nullptr;
398 }
399 }
400 return Make(children.begin(), this->numChildProcessors());
401 }
402
403 private:
egdaniel57d3b032015-11-13 11:57:27 -0800404 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
egdaniel64c47282015-11-13 06:54:19 -0800405 class GLFP : public GrGLSLFragmentProcessor {
bsalomone25eea42015-09-29 06:38:55 -0700406 public:
bsalomone25eea42015-09-29 06:38:55 -0700407 void emitCode(EmitArgs& args) override {
dvonbeckca9eeab2016-07-06 12:00:06 -0700408 // First guy's input might be nil.
Brian Osman978693c2020-01-24 14:52:10 -0500409 SkString result = this->invokeChild(0, args.fInputColor, args);
Brian Osmancddfc5e2020-01-24 10:24:27 -0500410 for (int i = 1; i < this->numChildProcessors(); ++i) {
Brian Osman978693c2020-01-24 14:52:10 -0500411 result = this->invokeChild(i, result.c_str(), args);
bsalomone25eea42015-09-29 06:38:55 -0700412 }
Brian Osmancddfc5e2020-01-24 10:24:27 -0500413 // Copy last output to our output variable
Brian Osman978693c2020-01-24 14:52:10 -0500414 args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, result.c_str());
bsalomone25eea42015-09-29 06:38:55 -0700415 }
416 };
417 return new GLFP;
418 }
Brian Salomon216f2e02017-07-25 15:52:51 -0400419
Brian Salomonaff329b2017-08-11 09:40:37 -0400420 SeriesFragmentProcessor(std::unique_ptr<GrFragmentProcessor>* children, int cnt)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400421 : INHERITED(kSeriesFragmentProcessor_ClassID, OptFlags(children, cnt)) {
Robert Phillips1c9686b2017-06-30 08:40:28 -0400422 SkASSERT(cnt > 1);
Robert Phillips1c9686b2017-06-30 08:40:28 -0400423 for (int i = 0; i < cnt; ++i) {
Michael Ludwig9aba6252020-06-22 14:46:36 -0400424 this->registerChild(std::move(children[i]));
Robert Phillips1c9686b2017-06-30 08:40:28 -0400425 }
426 }
427
Brian Salomonaff329b2017-08-11 09:40:37 -0400428 static OptimizationFlags OptFlags(std::unique_ptr<GrFragmentProcessor>* children, int cnt) {
Brian Salomon587e08f2017-01-27 10:59:27 -0500429 OptimizationFlags flags = kAll_OptimizationFlags;
430 for (int i = 0; i < cnt && flags != kNone_OptimizationFlags; ++i) {
431 flags &= children[i]->optimizationFlags();
432 }
433 return flags;
434 }
Brian Salomon94efbf52016-11-29 13:43:05 -0500435 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
bsalomone25eea42015-09-29 06:38:55 -0700436
437 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
438
Brian Osman1d5b5982018-10-01 13:41:39 -0400439 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
440 SkPMColor4f color = inColor;
Brian Salomon587e08f2017-01-27 10:59:27 -0500441 int childCnt = this->numChildProcessors();
442 for (int i = 0; i < childCnt; ++i) {
443 color = ConstantOutputForConstantInput(this->childProcessor(i), color);
444 }
445 return color;
446 }
447
448 typedef GrFragmentProcessor INHERITED;
bsalomone25eea42015-09-29 06:38:55 -0700449 };
450
451 if (!cnt) {
452 return nullptr;
453 }
Brian Salomoneec6f7b2017-02-10 14:29:38 -0500454 if (1 == cnt) {
Brian Salomonaff329b2017-08-11 09:40:37 -0400455 return std::move(series[0]);
Brian Salomoneec6f7b2017-02-10 14:29:38 -0500456 }
bsalomone25eea42015-09-29 06:38:55 -0700457 // Run the through the series, do the invariant output processing, and look for eliminations.
Brian Salomon650ced02017-07-20 16:46:46 -0400458 GrProcessorAnalysisColor inputColor;
459 inputColor.setToUnknown();
Brian Salomon64f42062020-02-14 10:42:45 -0500460 GrColorFragmentProcessorAnalysis info(inputColor, series, cnt);
Brian Salomonaff329b2017-08-11 09:40:37 -0400461 SkTArray<std::unique_ptr<GrFragmentProcessor>> replacementSeries;
Brian Osmanf28e55d2018-10-03 16:35:54 -0400462 SkPMColor4f knownColor;
Brian Salomoneec6f7b2017-02-10 14:29:38 -0500463 int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
464 if (leadingFPsToEliminate) {
John Stilese3a39f72020-06-15 13:58:48 -0400465 std::unique_ptr<GrFragmentProcessor> colorFP = GrConstColorProcessor::Make(
466 /*inputFP=*/nullptr, knownColor, GrConstColorProcessor::InputMode::kIgnore);
Brian Salomoneec6f7b2017-02-10 14:29:38 -0500467 if (leadingFPsToEliminate == cnt) {
468 return colorFP;
469 }
470 cnt = cnt - leadingFPsToEliminate + 1;
bungeman06ca8ec2016-06-09 08:01:03 -0700471 replacementSeries.reserve(cnt);
472 replacementSeries.emplace_back(std::move(colorFP));
473 for (int i = 0; i < cnt - 1; ++i) {
Brian Salomoneec6f7b2017-02-10 14:29:38 -0500474 replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i]));
bsalomone25eea42015-09-29 06:38:55 -0700475 }
bungeman06ca8ec2016-06-09 08:01:03 -0700476 series = replacementSeries.begin();
bsalomone25eea42015-09-29 06:38:55 -0700477 }
Robert Phillips1c9686b2017-06-30 08:40:28 -0400478 return SeriesFragmentProcessor::Make(series, cnt);
bsalomone25eea42015-09-29 06:38:55 -0700479}
bsalomona624bf32016-09-20 09:12:47 -0700480
481//////////////////////////////////////////////////////////////////////////////
482
Brian Salomon7eabfe82019-12-02 14:20:20 -0500483GrFragmentProcessor::CIter::CIter(const GrPaint& paint) {
Chris Dalton1c548942018-05-22 13:09:48 -0600484 for (int i = paint.numCoverageFragmentProcessors() - 1; i >= 0; --i) {
485 fFPStack.push_back(paint.getCoverageFragmentProcessor(i));
486 }
487 for (int i = paint.numColorFragmentProcessors() - 1; i >= 0; --i) {
488 fFPStack.push_back(paint.getColorFragmentProcessor(i));
489 }
490}
491
Brian Salomon7eabfe82019-12-02 14:20:20 -0500492GrFragmentProcessor::CIter::CIter(const GrProcessorSet& set) {
Brian Salomonc241b582019-11-27 08:57:17 -0500493 for (int i = set.numCoverageFragmentProcessors() - 1; i >= 0; --i) {
494 fFPStack.push_back(set.coverageFragmentProcessor(i));
bsalomona624bf32016-09-20 09:12:47 -0700495 }
Brian Salomonc241b582019-11-27 08:57:17 -0500496 for (int i = set.numColorFragmentProcessors() - 1; i >= 0; --i) {
497 fFPStack.push_back(set.colorFragmentProcessor(i));
498 }
499}
500
Brian Salomon7eabfe82019-12-02 14:20:20 -0500501GrFragmentProcessor::CIter::CIter(const GrPipeline& pipeline) {
Brian Salomonc241b582019-11-27 08:57:17 -0500502 for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
503 fFPStack.push_back(&pipeline.getFragmentProcessor(i));
504 }
505}
506
Brian Salomone782f842018-07-31 13:53:11 -0400507///////////////////////////////////////////////////////////////////////////////////////////////////
508
Robert Phillipsbd99c0c2019-12-12 13:26:58 +0000509GrFragmentProcessor::TextureSampler::TextureSampler(GrSurfaceProxyView view,
Brian Salomonccb61422020-01-09 10:46:36 -0500510 GrSamplerState samplerState)
511 : fView(std::move(view)), fSamplerState(samplerState) {
Robert Phillipsbd99c0c2019-12-12 13:26:58 +0000512 GrSurfaceProxy* proxy = this->proxy();
Greg Danielacf59292019-12-11 13:45:17 -0500513 fSamplerState.setFilterMode(
Brian Osman788b9162020-02-07 10:36:46 -0500514 std::min(samplerState.filter(),
Robert Phillipsbd99c0c2019-12-12 13:26:58 +0000515 GrTextureProxy::HighestFilterMode(proxy->backendFormat().textureType())));
Greg Danielacf59292019-12-11 13:45:17 -0500516}
Robert Phillipsbd99c0c2019-12-12 13:26:58 +0000517
Robert Phillipsbd99c0c2019-12-12 13:26:58 +0000518#if GR_TEST_UTILS
519void GrFragmentProcessor::TextureSampler::set(GrSurfaceProxyView view,
Brian Salomonccb61422020-01-09 10:46:36 -0500520 GrSamplerState samplerState) {
Robert Phillipsbd99c0c2019-12-12 13:26:58 +0000521 SkASSERT(view.proxy()->asTextureProxy());
522 fView = std::move(view);
523 fSamplerState = samplerState;
524
525 fSamplerState.setFilterMode(
Brian Osman788b9162020-02-07 10:36:46 -0500526 std::min(samplerState.filter(),
Robert Phillipsbd99c0c2019-12-12 13:26:58 +0000527 GrTextureProxy::HighestFilterMode(this->proxy()->backendFormat().textureType())));
528}
529#endif