blob: b0a36fce6d5726cf32fc92c7b3bc73c7660db889 [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
8#include "GrFragmentProcessor.h"
9#include "GrCoordTransform.h"
bsalomona624bf32016-09-20 09:12:47 -070010#include "GrPipeline.h"
Brian Salomona811b122017-03-30 08:21:32 -040011#include "GrProcessorAnalysis.h"
Brian Salomonc0b642c2017-03-27 13:09:36 -040012#include "effects/GrConstColorProcessor.h"
13#include "effects/GrXfermodeFragmentProcessor.h"
egdaniel64c47282015-11-13 06:54:19 -080014#include "glsl/GrGLSLFragmentProcessor.h"
egdaniel2d721d32015-11-11 13:06:05 -080015#include "glsl/GrGLSLFragmentShaderBuilder.h"
egdaniel018fb622015-10-28 07:26:40 -070016#include "glsl/GrGLSLProgramDataManager.h"
egdaniel7ea439b2015-12-03 09:20:44 -080017#include "glsl/GrGLSLUniformHandler.h"
bsalomonbf877302015-09-22 09:06:13 -070018
19GrFragmentProcessor::~GrFragmentProcessor() {
20 // If we got here then our ref count must have reached zero, so we will have converted refs
21 // to pending executions for all children.
22 for (int i = 0; i < fChildProcessors.count(); ++i) {
23 fChildProcessors[i]->completedExecution();
24 }
25}
26
bsalomon7312ff82016-09-12 08:55:38 -070027bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
bsalomonbf877302015-09-22 09:06:13 -070028 if (this->classID() != that.classID() ||
Brian Salomonf9f45122016-11-29 11:59:17 -050029 !this->hasSameSamplersAndAccesses(that)) {
bsalomonbf877302015-09-22 09:06:13 -070030 return false;
31 }
bsalomon7312ff82016-09-12 08:55:38 -070032 if (!this->hasSameTransforms(that)) {
bsalomonbf877302015-09-22 09:06:13 -070033 return false;
34 }
35 if (!this->onIsEqual(that)) {
36 return false;
37 }
38 if (this->numChildProcessors() != that.numChildProcessors()) {
39 return false;
40 }
41 for (int i = 0; i < this->numChildProcessors(); ++i) {
bsalomon7312ff82016-09-12 08:55:38 -070042 if (!this->childProcessor(i).isEqual(that.childProcessor(i))) {
bsalomonbf877302015-09-22 09:06:13 -070043 return false;
44 }
45 }
46 return true;
47}
48
egdaniel57d3b032015-11-13 11:57:27 -080049GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const {
50 GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance();
bsalomonbf877302015-09-22 09:06:13 -070051 glFragProc->fChildProcessors.push_back_n(fChildProcessors.count());
52 for (int i = 0; i < fChildProcessors.count(); ++i) {
egdaniel57d3b032015-11-13 11:57:27 -080053 glFragProc->fChildProcessors[i] = fChildProcessors[i]->createGLSLInstance();
bsalomonbf877302015-09-22 09:06:13 -070054 }
55 return glFragProc;
56}
57
bsalomonbf877302015-09-22 09:06:13 -070058void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
bsalomonbf877302015-09-22 09:06:13 -070059 fCoordTransforms.push_back(transform);
Brian Salomon587e08f2017-01-27 10:59:27 -050060 fFlags |= kUsesLocalCoords_Flag;
bsalomonbf877302015-09-22 09:06:13 -070061 SkDEBUGCODE(transform->setInProcessor();)
bsalomonbf877302015-09-22 09:06:13 -070062}
63
bungeman06ca8ec2016-06-09 08:01:03 -070064int GrFragmentProcessor::registerChildProcessor(sk_sp<GrFragmentProcessor> child) {
Robert Phillipsa91e0b72017-05-01 13:12:20 -040065 if (child->isBad()) {
66 this->markAsBad();
67 }
68
cdalton87332102016-02-26 12:22:02 -080069 this->combineRequiredFeatures(*child);
bsalomonbf877302015-09-22 09:06:13 -070070
71 if (child->usesLocalCoords()) {
Brian Salomon587e08f2017-01-27 10:59:27 -050072 fFlags |= kUsesLocalCoords_Flag;
bsalomonbf877302015-09-22 09:06:13 -070073 }
dvonbeck9b03e7b2016-08-01 11:01:56 -070074 if (child->usesDistanceVectorField()) {
Brian Salomon587e08f2017-01-27 10:59:27 -050075 fFlags |= kUsesDistanceVectorField_Flag;
dvonbeck9b03e7b2016-08-01 11:01:56 -070076 }
bsalomonbf877302015-09-22 09:06:13 -070077
bungeman06ca8ec2016-06-09 08:01:03 -070078 int index = fChildProcessors.count();
79 fChildProcessors.push_back(child.release());
80
bsalomonbf877302015-09-22 09:06:13 -070081 return index;
82}
83
84void GrFragmentProcessor::notifyRefCntIsZero() const {
85 // See comment above GrProgramElement for a detailed explanation of why we do this.
86 for (int i = 0; i < fChildProcessors.count(); ++i) {
87 fChildProcessors[i]->addPendingExecution();
88 fChildProcessors[i]->unref();
89 }
90}
91
92bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
bsalomona624bf32016-09-20 09:12:47 -070093 if (this->numCoordTransforms() != that.numCoordTransforms()) {
bsalomonbf877302015-09-22 09:06:13 -070094 return false;
95 }
bsalomona624bf32016-09-20 09:12:47 -070096 int count = this->numCoordTransforms();
bsalomonbf877302015-09-22 09:06:13 -070097 for (int i = 0; i < count; ++i) {
Robert Phillips67c18d62017-01-20 12:44:06 -050098 if (!this->coordTransform(i).hasSameEffectAs(that.coordTransform(i))) {
bsalomonbf877302015-09-22 09:06:13 -070099 return false;
100 }
101 }
102 return true;
103}
104
bungeman06ca8ec2016-06-09 08:01:03 -0700105sk_sp<GrFragmentProcessor> GrFragmentProcessor::MulOutputByInputAlpha(
106 sk_sp<GrFragmentProcessor> fp) {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700107 if (!fp) {
108 return nullptr;
109 }
Mike Reed7d954ad2016-10-28 15:42:34 -0400110 return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn);
bsalomonbf877302015-09-22 09:06:13 -0700111}
112
Brian Osmande1a6052017-03-22 10:57:00 -0400113namespace {
114
115class PremulInputFragmentProcessor : public GrFragmentProcessor {
116public:
117 PremulInputFragmentProcessor()
118 : INHERITED(kPreservesOpaqueInput_OptimizationFlag |
119 kConstantOutputForConstantInput_OptimizationFlag) {
120 this->initClassID<PremulInputFragmentProcessor>();
121 }
122
123 const char* name() const override { return "PremultiplyInput"; }
124
125private:
126 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
127 class GLFP : public GrGLSLFragmentProcessor {
128 public:
129 void emitCode(EmitArgs& args) override {
130 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
131
132 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor);
133 fragBuilder->codeAppendf("%s.rgb *= %s.a;",
134 args.fOutputColor, args.fInputColor);
135 }
136 };
137 return new GLFP;
138 }
139
140 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
141
142 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
143
144 GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
145 return input.premul();
146 }
147
148 typedef GrFragmentProcessor INHERITED;
149};
150
151class UnpremulInputFragmentProcessor : public GrFragmentProcessor {
152public:
153 UnpremulInputFragmentProcessor()
154 : INHERITED(kPreservesOpaqueInput_OptimizationFlag |
155 kConstantOutputForConstantInput_OptimizationFlag) {
156 this->initClassID<UnpremulInputFragmentProcessor>();
157 }
158
159 const char* name() const override { return "UnpremultiplyInput"; }
160
161private:
162 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
163 class GLFP : public GrGLSLFragmentProcessor {
164 public:
165 void emitCode(EmitArgs& args) override {
166 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
167
168 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor);
169 fragBuilder->codeAppendf("float invAlpha = %s.a <= 0.0 ? 0.0 : 1.0 / %s.a;",
170 args.fInputColor, args.fInputColor);
171 fragBuilder->codeAppendf("%s.rgb *= invAlpha;", args.fOutputColor);
172 }
173 };
174 return new GLFP;
175 }
176
177 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
178
179 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
180
181 GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
182 return input.unpremul();
183 }
184
185 typedef GrFragmentProcessor INHERITED;
186};
187
188}
189
dvonbeckc526da92016-07-20 11:20:30 -0700190sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulInput(sk_sp<GrFragmentProcessor> fp) {
dvonbeckc526da92016-07-20 11:20:30 -0700191 if (!fp) {
192 return nullptr;
193 }
194 sk_sp<GrFragmentProcessor> fpPipeline[] = { sk_make_sp<PremulInputFragmentProcessor>(), fp};
195 return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
196}
197
Brian Osmande1a6052017-03-22 10:57:00 -0400198sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulOutput(sk_sp<GrFragmentProcessor> fp) {
199 if (!fp) {
200 return nullptr;
201 }
202 sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<PremulInputFragmentProcessor>() };
203 return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
204}
205
206sk_sp<GrFragmentProcessor> GrFragmentProcessor::UnpremulOutput(sk_sp<GrFragmentProcessor> fp) {
207 if (!fp) {
208 return nullptr;
209 }
210 sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<UnpremulInputFragmentProcessor>() };
211 return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
212}
213
Brian Osmance425512017-03-22 14:37:50 -0400214sk_sp<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(sk_sp<GrFragmentProcessor> fp,
215 const GrSwizzle& swizzle) {
216 class SwizzleFragmentProcessor : public GrFragmentProcessor {
217 public:
218 SwizzleFragmentProcessor(const GrSwizzle& swizzle)
219 : INHERITED(kAll_OptimizationFlags)
220 , fSwizzle(swizzle) {
221 this->initClassID<SwizzleFragmentProcessor>();
222 }
223
224 const char* name() const override { return "Swizzle"; }
225 const GrSwizzle& swizzle() const { return fSwizzle; }
226
227 private:
228 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
229 class GLFP : public GrGLSLFragmentProcessor {
230 public:
231 void emitCode(EmitArgs& args) override {
232 const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>();
233 const GrSwizzle& swizzle = sfp.swizzle();
234 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
235
236 fragBuilder->codeAppendf("%s = %s.%s;",
237 args.fOutputColor, args.fInputColor, swizzle.c_str());
238 }
239 };
240 return new GLFP;
241 }
242
243 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
244 b->add32(fSwizzle.asKey());
245 }
246
247 bool onIsEqual(const GrFragmentProcessor& other) const override {
248 const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>();
249 return fSwizzle == sfp.fSwizzle;
250 }
251
252 GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
253 return fSwizzle.applyTo(input);
254 }
255
256 GrSwizzle fSwizzle;
257
258 typedef GrFragmentProcessor INHERITED;
259 };
260
261 if (!fp) {
262 return nullptr;
263 }
264 if (GrSwizzle::RGBA() == swizzle) {
265 return fp;
266 }
267 sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<SwizzleFragmentProcessor>(swizzle) };
268 return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
269}
270
Brian Salomon22af73f2017-01-26 11:25:12 -0500271sk_sp<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput(
272 sk_sp<GrFragmentProcessor> fp) {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700273
274 class PremulFragmentProcessor : public GrFragmentProcessor {
275 public:
Brian Salomon587e08f2017-01-27 10:59:27 -0500276 PremulFragmentProcessor(sk_sp<GrFragmentProcessor> processor)
277 : INHERITED(OptFlags(processor.get())) {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700278 this->initClassID<PremulFragmentProcessor>();
279 this->registerChildProcessor(processor);
280 }
281
282 const char* name() const override { return "Premultiply"; }
283
284 private:
egdaniel57d3b032015-11-13 11:57:27 -0800285 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
egdaniel64c47282015-11-13 06:54:19 -0800286 class GLFP : public GrGLSLFragmentProcessor {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700287 public:
bsalomonf1b7a1d2015-09-28 06:26:28 -0700288 void emitCode(EmitArgs& args) override {
cdalton85285412016-02-18 12:37:07 -0800289 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
Ethan Nicholas2983f402017-05-08 09:36:08 -0400290 this->emitChild(0, args);
egdaniel4ca2e602015-11-18 08:01:26 -0800291 fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor,
bsalomonf1b7a1d2015-09-28 06:26:28 -0700292 args.fInputColor);
egdaniel4ca2e602015-11-18 08:01:26 -0800293 fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
bsalomonf1b7a1d2015-09-28 06:26:28 -0700294 }
295 };
296 return new GLFP;
297 }
298
Brian Salomon94efbf52016-11-29 13:43:05 -0500299 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
bsalomonf1b7a1d2015-09-28 06:26:28 -0700300
301 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
302
Brian Salomon587e08f2017-01-27 10:59:27 -0500303 static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) {
304 OptimizationFlags flags = kNone_OptimizationFlags;
305 if (inner->preservesOpaqueInput()) {
306 flags |= kPreservesOpaqueInput_OptimizationFlag;
307 }
308 if (inner->hasConstantOutputForConstantInput()) {
309 flags |= kConstantOutputForConstantInput_OptimizationFlag;
310 }
311 return flags;
312 }
bsalomonf1b7a1d2015-09-28 06:26:28 -0700313
Brian Salomon587e08f2017-01-27 10:59:27 -0500314 GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
315 GrColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
316 GrColor4f::OpaqueWhite());
317 return GrColor4f(input.fRGBA[3] * input.fRGBA[0] * childColor.fRGBA[0],
318 input.fRGBA[3] * input.fRGBA[1] * childColor.fRGBA[1],
319 input.fRGBA[3] * input.fRGBA[2] * childColor.fRGBA[2],
320 input.fRGBA[3] * childColor.fRGBA[3]);
321 }
322
323 typedef GrFragmentProcessor INHERITED;
bsalomonf1b7a1d2015-09-28 06:26:28 -0700324 };
325 if (!fp) {
326 return nullptr;
327 }
bungeman06ca8ec2016-06-09 08:01:03 -0700328 return sk_sp<GrFragmentProcessor>(new PremulFragmentProcessor(std::move(fp)));
bsalomonf1b7a1d2015-09-28 06:26:28 -0700329}
330
331//////////////////////////////////////////////////////////////////////////////
332
bungeman06ca8ec2016-06-09 08:01:03 -0700333sk_sp<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(sk_sp<GrFragmentProcessor> fp,
brianosman4cea3b92016-09-08 09:33:50 -0700334 GrColor4f color) {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700335 class ReplaceInputFragmentProcessor : public GrFragmentProcessor {
336 public:
brianosman4cea3b92016-09-08 09:33:50 -0700337 ReplaceInputFragmentProcessor(sk_sp<GrFragmentProcessor> child, GrColor4f color)
Brian Salomon587e08f2017-01-27 10:59:27 -0500338 : INHERITED(OptFlags(child.get(), color)), fColor(color) {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700339 this->initClassID<ReplaceInputFragmentProcessor>();
bungeman06ca8ec2016-06-09 08:01:03 -0700340 this->registerChildProcessor(std::move(child));
bsalomonf1b7a1d2015-09-28 06:26:28 -0700341 }
342
343 const char* name() const override { return "Replace Color"; }
344
egdaniel57d3b032015-11-13 11:57:27 -0800345 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
egdaniel64c47282015-11-13 06:54:19 -0800346 class GLFP : public GrGLSLFragmentProcessor {
bsalomonf1b7a1d2015-09-28 06:26:28 -0700347 public:
348 GLFP() : fHaveSetColor(false) {}
349 void emitCode(EmitArgs& args) override {
350 const char* colorName;
cdalton5e58cee2016-02-11 12:49:47 -0800351 fColorUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
352 kVec4f_GrSLType,
353 kDefault_GrSLPrecision,
354 "Color", &colorName);
bsalomonf1b7a1d2015-09-28 06:26:28 -0700355 this->emitChild(0, colorName, args);
356 }
357
358 private:
egdaniel018fb622015-10-28 07:26:40 -0700359 void onSetData(const GrGLSLProgramDataManager& pdman,
Brian Salomonab015ef2017-04-04 10:15:51 -0400360 const GrFragmentProcessor& fp) override {
brianosman4cea3b92016-09-08 09:33:50 -0700361 GrColor4f color = fp.cast<ReplaceInputFragmentProcessor>().fColor;
bsalomonf1b7a1d2015-09-28 06:26:28 -0700362 if (!fHaveSetColor || color != fPreviousColor) {
brianosman4cea3b92016-09-08 09:33:50 -0700363 pdman.set4fv(fColorUni, 1, color.fRGBA);
bsalomonf1b7a1d2015-09-28 06:26:28 -0700364 fPreviousColor = color;
365 fHaveSetColor = true;
366 }
367 }
368
egdaniel018fb622015-10-28 07:26:40 -0700369 GrGLSLProgramDataManager::UniformHandle fColorUni;
brianosman4cea3b92016-09-08 09:33:50 -0700370 bool fHaveSetColor;
371 GrColor4f fPreviousColor;
bsalomonf1b7a1d2015-09-28 06:26:28 -0700372 };
373
374 return new GLFP;
375 }
376
377 private:
Brian Salomon587e08f2017-01-27 10:59:27 -0500378 static OptimizationFlags OptFlags(const GrFragmentProcessor* child, GrColor4f color) {
379 OptimizationFlags childFlags = child->optimizationFlags();
380 OptimizationFlags flags = kNone_OptimizationFlags;
381 if (childFlags & kConstantOutputForConstantInput_OptimizationFlag) {
382 flags |= kConstantOutputForConstantInput_OptimizationFlag;
383 }
384 if ((childFlags & kPreservesOpaqueInput_OptimizationFlag) && color.isOpaque()) {
385 flags |= kPreservesOpaqueInput_OptimizationFlag;
386 }
387 return flags;
388 }
389
Brian Salomon94efbf52016-11-29 13:43:05 -0500390 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override
egdaniel57d3b032015-11-13 11:57:27 -0800391 {}
bsalomonf1b7a1d2015-09-28 06:26:28 -0700392
393 bool onIsEqual(const GrFragmentProcessor& that) const override {
394 return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor;
395 }
396
Brian Salomon587e08f2017-01-27 10:59:27 -0500397 GrColor4f constantOutputForConstantInput(GrColor4f) const override {
398 return ConstantOutputForConstantInput(this->childProcessor(0), fColor);
399 }
400
brianosman4cea3b92016-09-08 09:33:50 -0700401 GrColor4f fColor;
Brian Salomon587e08f2017-01-27 10:59:27 -0500402
403 typedef GrFragmentProcessor INHERITED;
bsalomonf1b7a1d2015-09-28 06:26:28 -0700404 };
405
Brian Salomon5f13fba2017-01-23 14:35:25 -0500406 return sk_sp<GrFragmentProcessor>(new ReplaceInputFragmentProcessor(std::move(fp), color));
bsalomonf1b7a1d2015-09-28 06:26:28 -0700407}
bsalomone25eea42015-09-29 06:38:55 -0700408
bungeman06ca8ec2016-06-09 08:01:03 -0700409sk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProcessor>* series,
bsalomone25eea42015-09-29 06:38:55 -0700410 int cnt) {
411 class SeriesFragmentProcessor : public GrFragmentProcessor {
412 public:
Brian Salomon587e08f2017-01-27 10:59:27 -0500413 SeriesFragmentProcessor(sk_sp<GrFragmentProcessor>* children, int cnt)
414 : INHERITED(OptFlags(children, cnt)) {
bsalomone25eea42015-09-29 06:38:55 -0700415 SkASSERT(cnt > 1);
416 this->initClassID<SeriesFragmentProcessor>();
417 for (int i = 0; i < cnt; ++i) {
bungeman06ca8ec2016-06-09 08:01:03 -0700418 this->registerChildProcessor(std::move(children[i]));
bsalomone25eea42015-09-29 06:38:55 -0700419 }
420 }
421
422 const char* name() const override { return "Series"; }
423
egdaniel57d3b032015-11-13 11:57:27 -0800424 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
egdaniel64c47282015-11-13 06:54:19 -0800425 class GLFP : public GrGLSLFragmentProcessor {
bsalomone25eea42015-09-29 06:38:55 -0700426 public:
bsalomone25eea42015-09-29 06:38:55 -0700427 void emitCode(EmitArgs& args) override {
dvonbeckca9eeab2016-07-06 12:00:06 -0700428 // First guy's input might be nil.
429 SkString temp("out0");
430 this->emitChild(0, args.fInputColor, &temp, args);
431 SkString input = temp;
432 for (int i = 1; i < this->numChildProcessors() - 1; ++i) {
bsalomone25eea42015-09-29 06:38:55 -0700433 temp.printf("out%d", i);
434 this->emitChild(i, input.c_str(), &temp, args);
435 input = temp;
436 }
437 // Last guy writes to our output variable.
438 this->emitChild(this->numChildProcessors() - 1, input.c_str(), args);
439 }
440 };
441 return new GLFP;
442 }
bsalomone25eea42015-09-29 06:38:55 -0700443 private:
Brian Salomon587e08f2017-01-27 10:59:27 -0500444 static OptimizationFlags OptFlags(sk_sp<GrFragmentProcessor>* children, int cnt) {
445 OptimizationFlags flags = kAll_OptimizationFlags;
446 for (int i = 0; i < cnt && flags != kNone_OptimizationFlags; ++i) {
447 flags &= children[i]->optimizationFlags();
448 }
449 return flags;
450 }
Brian Salomon94efbf52016-11-29 13:43:05 -0500451 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
bsalomone25eea42015-09-29 06:38:55 -0700452
453 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
454
Brian Salomon587e08f2017-01-27 10:59:27 -0500455 GrColor4f constantOutputForConstantInput(GrColor4f color) const override {
456 int childCnt = this->numChildProcessors();
457 for (int i = 0; i < childCnt; ++i) {
458 color = ConstantOutputForConstantInput(this->childProcessor(i), color);
459 }
460 return color;
461 }
462
463 typedef GrFragmentProcessor INHERITED;
bsalomone25eea42015-09-29 06:38:55 -0700464 };
465
466 if (!cnt) {
467 return nullptr;
468 }
Brian Salomoneec6f7b2017-02-10 14:29:38 -0500469 if (1 == cnt) {
470 return series[0];
471 }
bsalomone25eea42015-09-29 06:38:55 -0700472 // Run the through the series, do the invariant output processing, and look for eliminations.
Brian Salomonc0b642c2017-03-27 13:09:36 -0400473 GrColorFragmentProcessorAnalysis info;
Brian Salomon0831f1b2017-01-18 11:08:41 -0500474 info.analyzeProcessors(sk_sp_address_as_pointer_address(series), cnt);
bungeman06ca8ec2016-06-09 08:01:03 -0700475 SkTArray<sk_sp<GrFragmentProcessor>> replacementSeries;
Brian Salomoneec6f7b2017-02-10 14:29:38 -0500476 GrColor4f knownColor;
477 int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
478 if (leadingFPsToEliminate) {
479 sk_sp<GrFragmentProcessor> colorFP(
480 GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::kIgnore_InputMode));
481 if (leadingFPsToEliminate == cnt) {
482 return colorFP;
483 }
484 cnt = cnt - leadingFPsToEliminate + 1;
bungeman06ca8ec2016-06-09 08:01:03 -0700485 replacementSeries.reserve(cnt);
486 replacementSeries.emplace_back(std::move(colorFP));
487 for (int i = 0; i < cnt - 1; ++i) {
Brian Salomoneec6f7b2017-02-10 14:29:38 -0500488 replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i]));
bsalomone25eea42015-09-29 06:38:55 -0700489 }
bungeman06ca8ec2016-06-09 08:01:03 -0700490 series = replacementSeries.begin();
bsalomone25eea42015-09-29 06:38:55 -0700491 }
bungeman06ca8ec2016-06-09 08:01:03 -0700492 return sk_sp<GrFragmentProcessor>(new SeriesFragmentProcessor(series, cnt));
bsalomone25eea42015-09-29 06:38:55 -0700493}
bsalomona624bf32016-09-20 09:12:47 -0700494
495//////////////////////////////////////////////////////////////////////////////
496
497GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) {
498 for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
499 fFPStack.push_back(&pipeline.getFragmentProcessor(i));
500 }
501}
502
503const GrFragmentProcessor* GrFragmentProcessor::Iter::next() {
504 if (fFPStack.empty()) {
505 return nullptr;
506 }
507 const GrFragmentProcessor* back = fFPStack.back();
508 fFPStack.pop_back();
509 for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
510 fFPStack.push_back(&back->childProcessor(i));
511 }
512 return back;
513}
514