1 /*
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"
10 #include "GrPipeline.h"
11 #include "GrProcessorAnalysis.h"
12 #include "effects/GrConstColorProcessor.h"
13 #include "effects/GrPremulInputFragmentProcessor.h"
14 #include "effects/GrXfermodeFragmentProcessor.h"
15 #include "effects/GrUnpremulInputFragmentProcessor.h"
16 #include "glsl/GrGLSLFragmentProcessor.h"
17 #include "glsl/GrGLSLFragmentShaderBuilder.h"
18 #include "glsl/GrGLSLProgramDataManager.h"
19 #include "glsl/GrGLSLUniformHandler.h"
20 
isEqual(const GrFragmentProcessor & that) const21 bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
22     if (this->classID() != that.classID() ||
23         !this->hasSameSamplersAndAccesses(that)) {
24         return false;
25     }
26     if (!this->hasSameTransforms(that)) {
27         return false;
28     }
29     if (!this->onIsEqual(that)) {
30         return false;
31     }
32     if (this->numChildProcessors() != that.numChildProcessors()) {
33         return false;
34     }
35     for (int i = 0; i < this->numChildProcessors(); ++i) {
36         if (!this->childProcessor(i).isEqual(that.childProcessor(i))) {
37             return false;
38         }
39     }
40     return true;
41 }
42 
createGLSLInstance() const43 GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const {
44     GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance();
45     glFragProc->fChildProcessors.push_back_n(fChildProcessors.count());
46     for (int i = 0; i < fChildProcessors.count(); ++i) {
47         glFragProc->fChildProcessors[i] = fChildProcessors[i]->createGLSLInstance();
48     }
49     return glFragProc;
50 }
51 
addCoordTransform(const GrCoordTransform * transform)52 void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
53     fCoordTransforms.push_back(transform);
54     fFlags |= kUsesLocalCoords_Flag;
55     SkDEBUGCODE(transform->setInProcessor();)
56 }
57 
instantiate(GrResourceProvider * resourceProvider) const58 bool GrFragmentProcessor::instantiate(GrResourceProvider* resourceProvider) const {
59     if (!INHERITED::instantiate(resourceProvider)) {
60         return false;
61     }
62 
63     for (int i = 0; i < this->numChildProcessors(); ++i) {
64         if (!this->childProcessor(i).instantiate(resourceProvider)) {
65             return false;
66         }
67     }
68 
69     return true;
70 }
71 
markPendingExecution() const72 void GrFragmentProcessor::markPendingExecution() const {
73     INHERITED::addPendingIOs();
74     INHERITED::removeRefs();
75     for (int i = 0; i < this->numChildProcessors(); ++i) {
76         this->childProcessor(i).markPendingExecution();
77     }
78 }
79 
registerChildProcessor(std::unique_ptr<GrFragmentProcessor> child)80 int GrFragmentProcessor::registerChildProcessor(std::unique_ptr<GrFragmentProcessor> child) {
81     if (child->usesLocalCoords()) {
82         fFlags |= kUsesLocalCoords_Flag;
83     }
84 
85     int index = fChildProcessors.count();
86     fChildProcessors.push_back(std::move(child));
87 
88     return index;
89 }
90 
hasSameTransforms(const GrFragmentProcessor & that) const91 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
92     if (this->numCoordTransforms() != that.numCoordTransforms()) {
93         return false;
94     }
95     int count = this->numCoordTransforms();
96     for (int i = 0; i < count; ++i) {
97         if (!this->coordTransform(i).hasSameEffectAs(that.coordTransform(i))) {
98             return false;
99         }
100     }
101     return true;
102 }
103 
MulChildByInputAlpha(std::unique_ptr<GrFragmentProcessor> fp)104 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulChildByInputAlpha(
105         std::unique_ptr<GrFragmentProcessor> fp) {
106     if (!fp) {
107         return nullptr;
108     }
109     return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn);
110 }
111 
MulInputByChildAlpha(std::unique_ptr<GrFragmentProcessor> fp)112 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulInputByChildAlpha(
113         std::unique_ptr<GrFragmentProcessor> fp) {
114     if (!fp) {
115         return nullptr;
116     }
117     return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kSrcIn);
118 }
119 
PremulInput(std::unique_ptr<GrFragmentProcessor> fp)120 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::PremulInput(
121         std::unique_ptr<GrFragmentProcessor> fp) {
122     if (!fp) {
123         return nullptr;
124     }
125     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { GrPremulInputFragmentProcessor::Make(),
126                                                           std::move(fp) };
127     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
128 }
129 
PremulOutput(std::unique_ptr<GrFragmentProcessor> fp)130 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::PremulOutput(
131         std::unique_ptr<GrFragmentProcessor> fp) {
132     if (!fp) {
133         return nullptr;
134     }
135     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { std::move(fp),
136                                                           GrPremulInputFragmentProcessor::Make() };
137     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
138 }
139 
UnpremulOutput(std::unique_ptr<GrFragmentProcessor> fp)140 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::UnpremulOutput(
141         std::unique_ptr<GrFragmentProcessor> fp) {
142     if (!fp) {
143         return nullptr;
144     }
145     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { std::move(fp),
146                                                           GrUnpremulInputFragmentProcessor::Make() };
147     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
148 }
149 
SwizzleOutput(std::unique_ptr<GrFragmentProcessor> fp,const GrSwizzle & swizzle)150 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(
151         std::unique_ptr<GrFragmentProcessor> fp, const GrSwizzle& swizzle) {
152     class SwizzleFragmentProcessor : public GrFragmentProcessor {
153     public:
154         static std::unique_ptr<GrFragmentProcessor> Make(const GrSwizzle& swizzle) {
155             return std::unique_ptr<GrFragmentProcessor>(new SwizzleFragmentProcessor(swizzle));
156         }
157 
158         const char* name() const override { return "Swizzle"; }
159         const GrSwizzle& swizzle() const { return fSwizzle; }
160 
161         std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(fSwizzle); }
162 
163     private:
164         SwizzleFragmentProcessor(const GrSwizzle& swizzle)
165                 : INHERITED(kSwizzleFragmentProcessor_ClassID, kAll_OptimizationFlags)
166                 , fSwizzle(swizzle) {
167         }
168 
169         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
170             class GLFP : public GrGLSLFragmentProcessor {
171             public:
172                 void emitCode(EmitArgs& args) override {
173                     const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>();
174                     const GrSwizzle& swizzle = sfp.swizzle();
175                     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
176 
177                     fragBuilder->codeAppendf("%s = %s.%s;",
178                                              args.fOutputColor, args.fInputColor, swizzle.c_str());
179                 }
180             };
181             return new GLFP;
182         }
183 
184         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
185             b->add32(fSwizzle.asKey());
186         }
187 
188         bool onIsEqual(const GrFragmentProcessor& other) const override {
189             const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>();
190             return fSwizzle == sfp.fSwizzle;
191         }
192 
193         GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
194             return fSwizzle.applyTo(input);
195         }
196 
197         GrSwizzle fSwizzle;
198 
199         typedef GrFragmentProcessor INHERITED;
200     };
201 
202     if (!fp) {
203         return nullptr;
204     }
205     if (GrSwizzle::RGBA() == swizzle) {
206         return fp;
207     }
208     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { std::move(fp),
209                                                           SwizzleFragmentProcessor::Make(swizzle) };
210     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
211 }
212 
MakeInputPremulAndMulByOutput(std::unique_ptr<GrFragmentProcessor> fp)213 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput(
214         std::unique_ptr<GrFragmentProcessor> fp) {
215     class PremulFragmentProcessor : public GrFragmentProcessor {
216     public:
217         static std::unique_ptr<GrFragmentProcessor> Make(
218                 std::unique_ptr<GrFragmentProcessor> processor) {
219             return std::unique_ptr<GrFragmentProcessor>(
220                     new PremulFragmentProcessor(std::move(processor)));
221         }
222 
223         const char* name() const override { return "Premultiply"; }
224 
225         std::unique_ptr<GrFragmentProcessor> clone() const override {
226             return Make(this->childProcessor(0).clone());
227         }
228 
229     private:
230         PremulFragmentProcessor(std::unique_ptr<GrFragmentProcessor> processor)
231                 : INHERITED(kPremulFragmentProcessor_ClassID, OptFlags(processor.get())) {
232             this->registerChildProcessor(std::move(processor));
233         }
234 
235         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
236             class GLFP : public GrGLSLFragmentProcessor {
237             public:
238                 void emitCode(EmitArgs& args) override {
239                     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
240                     this->emitChild(0, args);
241                     fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor,
242                                                                 args.fInputColor);
243                     fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
244                 }
245             };
246             return new GLFP;
247         }
248 
249         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
250 
251         bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
252 
253         static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) {
254             OptimizationFlags flags = kNone_OptimizationFlags;
255             if (inner->preservesOpaqueInput()) {
256                 flags |= kPreservesOpaqueInput_OptimizationFlag;
257             }
258             if (inner->hasConstantOutputForConstantInput()) {
259                 flags |= kConstantOutputForConstantInput_OptimizationFlag;
260             }
261             return flags;
262         }
263 
264         GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
265             GrColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
266                                                                   GrColor4f::OpaqueWhite());
267             return GrColor4f(input.fRGBA[3] * input.fRGBA[0] * childColor.fRGBA[0],
268                              input.fRGBA[3] * input.fRGBA[1] * childColor.fRGBA[1],
269                              input.fRGBA[3] * input.fRGBA[2] * childColor.fRGBA[2],
270                              input.fRGBA[3] * childColor.fRGBA[3]);
271         }
272 
273         typedef GrFragmentProcessor INHERITED;
274     };
275     if (!fp) {
276         return nullptr;
277     }
278     return PremulFragmentProcessor::Make(std::move(fp));
279 }
280 
281 //////////////////////////////////////////////////////////////////////////////
282 
OverrideInput(std::unique_ptr<GrFragmentProcessor> fp,GrColor4f color)283 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(
284         std::unique_ptr<GrFragmentProcessor> fp, GrColor4f color) {
285     class ReplaceInputFragmentProcessor : public GrFragmentProcessor {
286     public:
287         static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child,
288                                                          GrColor4f color) {
289             return std::unique_ptr<GrFragmentProcessor>(
290                     new ReplaceInputFragmentProcessor(std::move(child), color));
291         }
292 
293         const char* name() const override { return "Replace Color"; }
294 
295         std::unique_ptr<GrFragmentProcessor> clone() const override {
296             return Make(this->childProcessor(0).clone(), fColor);
297         }
298 
299     private:
300         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
301             class GLFP : public GrGLSLFragmentProcessor {
302             public:
303                 GLFP() : fHaveSetColor(false) {}
304                 void emitCode(EmitArgs& args) override {
305                     const char* colorName;
306                     fColorUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
307                                                                  kHalf4_GrSLType,
308                                                                  "Color", &colorName);
309                     this->emitChild(0, colorName, args);
310                 }
311 
312             private:
313                 void onSetData(const GrGLSLProgramDataManager& pdman,
314                                const GrFragmentProcessor& fp) override {
315                     GrColor4f color = fp.cast<ReplaceInputFragmentProcessor>().fColor;
316                     if (!fHaveSetColor || color != fPreviousColor) {
317                         pdman.set4fv(fColorUni, 1, color.fRGBA);
318                         fPreviousColor = color;
319                         fHaveSetColor = true;
320                     }
321                 }
322 
323                 GrGLSLProgramDataManager::UniformHandle fColorUni;
324                 bool      fHaveSetColor;
325                 GrColor4f fPreviousColor;
326             };
327 
328             return new GLFP;
329         }
330 
331         ReplaceInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> child, GrColor4f color)
332                 : INHERITED(kReplaceInputFragmentProcessor_ClassID, OptFlags(child.get(), color))
333                 , fColor(color) {
334             this->registerChildProcessor(std::move(child));
335         }
336 
337         static OptimizationFlags OptFlags(const GrFragmentProcessor* child, GrColor4f color) {
338             OptimizationFlags childFlags = child->optimizationFlags();
339             OptimizationFlags flags = kNone_OptimizationFlags;
340             if (childFlags & kConstantOutputForConstantInput_OptimizationFlag) {
341                 flags |= kConstantOutputForConstantInput_OptimizationFlag;
342             }
343             if ((childFlags & kPreservesOpaqueInput_OptimizationFlag) && color.isOpaque()) {
344                 flags |= kPreservesOpaqueInput_OptimizationFlag;
345             }
346             return flags;
347         }
348 
349         void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override
350         {}
351 
352         bool onIsEqual(const GrFragmentProcessor& that) const override {
353             return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor;
354         }
355 
356         GrColor4f constantOutputForConstantInput(GrColor4f) const override {
357             return ConstantOutputForConstantInput(this->childProcessor(0), fColor);
358         }
359 
360         GrColor4f fColor;
361 
362         typedef GrFragmentProcessor INHERITED;
363     };
364 
365     if (!fp) {
366         return nullptr;
367     }
368     return ReplaceInputFragmentProcessor::Make(std::move(fp), color);
369 }
370 
RunInSeries(std::unique_ptr<GrFragmentProcessor> * series,int cnt)371 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(
372         std::unique_ptr<GrFragmentProcessor>* series, int cnt) {
373     class SeriesFragmentProcessor : public GrFragmentProcessor {
374     public:
375         static std::unique_ptr<GrFragmentProcessor> Make(
376                 std::unique_ptr<GrFragmentProcessor>* children, int cnt) {
377             return std::unique_ptr<GrFragmentProcessor>(new SeriesFragmentProcessor(children, cnt));
378         }
379 
380         const char* name() const override { return "Series"; }
381 
382         std::unique_ptr<GrFragmentProcessor> clone() const override {
383             SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> children(this->numChildProcessors());
384             for (int i = 0; i < this->numChildProcessors(); ++i) {
385                 if (!children.push_back(this->childProcessor(i).clone())) {
386                     return nullptr;
387                 }
388             }
389             return Make(children.begin(), this->numChildProcessors());
390         }
391 
392     private:
393         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
394             class GLFP : public GrGLSLFragmentProcessor {
395             public:
396                 void emitCode(EmitArgs& args) override {
397                     // First guy's input might be nil.
398                     SkString temp("out0");
399                     this->emitChild(0, args.fInputColor, &temp, args);
400                     SkString input = temp;
401                     for (int i = 1; i < this->numChildProcessors() - 1; ++i) {
402                         temp.printf("out%d", i);
403                         this->emitChild(i, input.c_str(), &temp, args);
404                         input = temp;
405                     }
406                     // Last guy writes to our output variable.
407                     this->emitChild(this->numChildProcessors() - 1, input.c_str(), args);
408                 }
409             };
410             return new GLFP;
411         }
412 
413         SeriesFragmentProcessor(std::unique_ptr<GrFragmentProcessor>* children, int cnt)
414                 : INHERITED(kSeriesFragmentProcessor_ClassID, OptFlags(children, cnt)) {
415             SkASSERT(cnt > 1);
416             for (int i = 0; i < cnt; ++i) {
417                 this->registerChildProcessor(std::move(children[i]));
418             }
419         }
420 
421         static OptimizationFlags OptFlags(std::unique_ptr<GrFragmentProcessor>* children, int cnt) {
422             OptimizationFlags flags = kAll_OptimizationFlags;
423             for (int i = 0; i < cnt && flags != kNone_OptimizationFlags; ++i) {
424                 flags &= children[i]->optimizationFlags();
425             }
426             return flags;
427         }
428         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
429 
430         bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
431 
432         GrColor4f constantOutputForConstantInput(GrColor4f color) const override {
433             int childCnt = this->numChildProcessors();
434             for (int i = 0; i < childCnt; ++i) {
435                 color = ConstantOutputForConstantInput(this->childProcessor(i), color);
436             }
437             return color;
438         }
439 
440         typedef GrFragmentProcessor INHERITED;
441     };
442 
443     if (!cnt) {
444         return nullptr;
445     }
446     if (1 == cnt) {
447         return std::move(series[0]);
448     }
449     // Run the through the series, do the invariant output processing, and look for eliminations.
450     GrProcessorAnalysisColor inputColor;
451     inputColor.setToUnknown();
452     GrColorFragmentProcessorAnalysis info(inputColor, unique_ptr_address_as_pointer_address(series),
453                                           cnt);
454     SkTArray<std::unique_ptr<GrFragmentProcessor>> replacementSeries;
455     GrColor4f knownColor;
456     int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
457     if (leadingFPsToEliminate) {
458         std::unique_ptr<GrFragmentProcessor> colorFP(
459                 GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::InputMode::kIgnore));
460         if (leadingFPsToEliminate == cnt) {
461             return colorFP;
462         }
463         cnt = cnt - leadingFPsToEliminate + 1;
464         replacementSeries.reserve(cnt);
465         replacementSeries.emplace_back(std::move(colorFP));
466         for (int i = 0; i < cnt - 1; ++i) {
467             replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i]));
468         }
469         series = replacementSeries.begin();
470     }
471     return SeriesFragmentProcessor::Make(series, cnt);
472 }
473 
474 //////////////////////////////////////////////////////////////////////////////
475 
Iter(const GrPipeline & pipeline)476 GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) {
477     for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
478         fFPStack.push_back(&pipeline.getFragmentProcessor(i));
479     }
480 }
481 
next()482 const GrFragmentProcessor* GrFragmentProcessor::Iter::next() {
483     if (fFPStack.empty()) {
484         return nullptr;
485     }
486     const GrFragmentProcessor* back = fFPStack.back();
487     fFPStack.pop_back();
488     for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
489         fFPStack.push_back(&back->childProcessor(i));
490     }
491     return back;
492 }
493 
494