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 "glsl/GrGLSLFragmentProcessor.h"
16 #include "glsl/GrGLSLFragmentShaderBuilder.h"
17 #include "glsl/GrGLSLProgramDataManager.h"
18 #include "glsl/GrGLSLUniformHandler.h"
19 
20 bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
21     if (this->classID() != that.classID()) {
22         return false;
23     }
24     if (this->numTextureSamplers() != that.numTextureSamplers()) {
25         return false;
26     }
27     for (int i = 0; i < this->numTextureSamplers(); ++i) {
28         if (this->textureSampler(i) != that.textureSampler(i)) {
29             return false;
30         }
31     }
32     if (!this->hasSameTransforms(that)) {
33         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) {
42         if (!this->childProcessor(i).isEqual(that.childProcessor(i))) {
43             return false;
44         }
45     }
46     return true;
47 }
48 
49 void GrFragmentProcessor::visitProxies(const std::function<void(GrSurfaceProxy*)>& func) {
50     GrFragmentProcessor::TextureAccessIter iter(this);
51     while (const TextureSampler* sampler = iter.next()) {
52         func(sampler->proxy());
53     }
54 }
55 
56 GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const {
57     GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance();
58     glFragProc->fChildProcessors.push_back_n(fChildProcessors.count());
59     for (int i = 0; i < fChildProcessors.count(); ++i) {
60         glFragProc->fChildProcessors[i] = fChildProcessors[i]->createGLSLInstance();
61     }
62     return glFragProc;
63 }
64 
65 const GrFragmentProcessor::TextureSampler& GrFragmentProcessor::textureSampler(int i) const {
66     SkASSERT(i >= 0 && i < fTextureSamplerCnt);
67     return this->onTextureSampler(i);
68 }
69 
70 void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
71     fCoordTransforms.push_back(transform);
72     fFlags |= kUsesLocalCoords_Flag;
73     SkDEBUGCODE(transform->setInProcessor();)
74 }
75 
76 bool GrFragmentProcessor::instantiate(GrResourceProvider* resourceProvider) const {
77     for (int i = 0; i < fTextureSamplerCnt; ++i) {
78         if (!this->textureSampler(i).instantiate(resourceProvider)) {
79             return false;
80         }
81     }
82 
83     for (int i = 0; i < this->numChildProcessors(); ++i) {
84         if (!this->childProcessor(i).instantiate(resourceProvider)) {
85             return false;
86         }
87     }
88 
89     return true;
90 }
91 
92 void GrFragmentProcessor::markPendingExecution() const {
93     for (int i = 0; i < fTextureSamplerCnt; ++i) {
94         auto* ref = this->textureSampler(i).proxyRef();
95         ref->markPendingIO();
96         ref->removeRef();
97     }
98     for (int i = 0; i < this->numChildProcessors(); ++i) {
99         this->childProcessor(i).markPendingExecution();
100     }
101 }
102 
103 int GrFragmentProcessor::registerChildProcessor(std::unique_ptr<GrFragmentProcessor> child) {
104     if (child->usesLocalCoords()) {
105         fFlags |= kUsesLocalCoords_Flag;
106     }
107 
108     int index = fChildProcessors.count();
109     fChildProcessors.push_back(std::move(child));
110 
111     return index;
112 }
113 
114 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
115     if (this->numCoordTransforms() != that.numCoordTransforms()) {
116         return false;
117     }
118     int count = this->numCoordTransforms();
119     for (int i = 0; i < count; ++i) {
120         if (!this->coordTransform(i).hasSameEffectAs(that.coordTransform(i))) {
121             return false;
122         }
123     }
124     return true;
125 }
126 
127 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulChildByInputAlpha(
128         std::unique_ptr<GrFragmentProcessor> fp) {
129     if (!fp) {
130         return nullptr;
131     }
132     return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn);
133 }
134 
135 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulInputByChildAlpha(
136         std::unique_ptr<GrFragmentProcessor> fp) {
137     if (!fp) {
138         return nullptr;
139     }
140     return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kSrcIn);
141 }
142 
143 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::PremulInput(
144         std::unique_ptr<GrFragmentProcessor> fp) {
145     if (!fp) {
146         return nullptr;
147     }
148     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { GrPremulInputFragmentProcessor::Make(),
149                                                           std::move(fp) };
150     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
151 }
152 
153 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(
154         std::unique_ptr<GrFragmentProcessor> fp, const GrSwizzle& swizzle) {
155     class SwizzleFragmentProcessor : public GrFragmentProcessor {
156     public:
157         static std::unique_ptr<GrFragmentProcessor> Make(const GrSwizzle& swizzle) {
158             return std::unique_ptr<GrFragmentProcessor>(new SwizzleFragmentProcessor(swizzle));
159         }
160 
161         const char* name() const override { return "Swizzle"; }
162         const GrSwizzle& swizzle() const { return fSwizzle; }
163 
164         std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(fSwizzle); }
165 
166     private:
167         SwizzleFragmentProcessor(const GrSwizzle& swizzle)
168                 : INHERITED(kSwizzleFragmentProcessor_ClassID, kAll_OptimizationFlags)
169                 , fSwizzle(swizzle) {}
170 
171         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
172             class GLFP : public GrGLSLFragmentProcessor {
173             public:
174                 void emitCode(EmitArgs& args) override {
175                     const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>();
176                     const GrSwizzle& swizzle = sfp.swizzle();
177                     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
178 
179                     fragBuilder->codeAppendf("%s = %s.%s;",
180                                              args.fOutputColor, args.fInputColor, swizzle.c_str());
181                 }
182             };
183             return new GLFP;
184         }
185 
186         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
187             b->add32(fSwizzle.asKey());
188         }
189 
190         bool onIsEqual(const GrFragmentProcessor& other) const override {
191             const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>();
192             return fSwizzle == sfp.fSwizzle;
193         }
194 
195         SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
196             return fSwizzle.applyTo(input);
197         }
198 
199         GrSwizzle fSwizzle;
200 
201         typedef GrFragmentProcessor INHERITED;
202     };
203 
204     if (!fp) {
205         return nullptr;
206     }
207     if (GrSwizzle::RGBA() == swizzle) {
208         return fp;
209     }
210     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { std::move(fp),
211                                                           SwizzleFragmentProcessor::Make(swizzle) };
212     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
213 }
214 
215 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput(
216         std::unique_ptr<GrFragmentProcessor> fp) {
217     class PremulFragmentProcessor : public GrFragmentProcessor {
218     public:
219         static std::unique_ptr<GrFragmentProcessor> Make(
220                 std::unique_ptr<GrFragmentProcessor> processor) {
221             return std::unique_ptr<GrFragmentProcessor>(
222                     new PremulFragmentProcessor(std::move(processor)));
223         }
224 
225         const char* name() const override { return "Premultiply"; }
226 
227         std::unique_ptr<GrFragmentProcessor> clone() const override {
228             return Make(this->childProcessor(0).clone());
229         }
230 
231     private:
232         PremulFragmentProcessor(std::unique_ptr<GrFragmentProcessor> processor)
233                 : INHERITED(kPremulFragmentProcessor_ClassID, OptFlags(processor.get())) {
234             this->registerChildProcessor(std::move(processor));
235         }
236 
237         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
238             class GLFP : public GrGLSLFragmentProcessor {
239             public:
240                 void emitCode(EmitArgs& args) override {
241                     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
242                     this->emitChild(0, args);
243                     fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor,
244                                                                 args.fInputColor);
245                     fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
246                 }
247             };
248             return new GLFP;
249         }
250 
251         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
252 
253         bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
254 
255         static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) {
256             OptimizationFlags flags = kNone_OptimizationFlags;
257             if (inner->preservesOpaqueInput()) {
258                 flags |= kPreservesOpaqueInput_OptimizationFlag;
259             }
260             if (inner->hasConstantOutputForConstantInput()) {
261                 flags |= kConstantOutputForConstantInput_OptimizationFlag;
262             }
263             return flags;
264         }
265 
266         SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
267             SkPMColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
268                                                                     SK_PMColor4fWHITE);
269             SkPMColor4f premulInput = SkColor4f{ input.fR, input.fG, input.fB, input.fA }.premul();
270             return premulInput * childColor;
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 
283 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(
284         std::unique_ptr<GrFragmentProcessor> fp, const SkPMColor4f& color) {
285     class ReplaceInputFragmentProcessor : public GrFragmentProcessor {
286     public:
287         static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child,
288                                                          const SkPMColor4f& 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                     SkPMColor4f color = fp.cast<ReplaceInputFragmentProcessor>().fColor;
316                     if (!fHaveSetColor || color != fPreviousColor) {
317                         pdman.set4fv(fColorUni, 1, color.vec());
318                         fPreviousColor = color;
319                         fHaveSetColor = true;
320                     }
321                 }
322 
323                 GrGLSLProgramDataManager::UniformHandle fColorUni;
324                 bool        fHaveSetColor;
325                 SkPMColor4f fPreviousColor;
326             };
327 
328             return new GLFP;
329         }
330 
331         ReplaceInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> child,
332                                       const SkPMColor4f& color)
333                 : INHERITED(kReplaceInputFragmentProcessor_ClassID, OptFlags(child.get(), color))
334                 , fColor(color) {
335             this->registerChildProcessor(std::move(child));
336         }
337 
338         static OptimizationFlags OptFlags(const GrFragmentProcessor* child,
339                                           const SkPMColor4f& color) {
340             OptimizationFlags childFlags = child->optimizationFlags();
341             OptimizationFlags flags = kNone_OptimizationFlags;
342             if (childFlags & kConstantOutputForConstantInput_OptimizationFlag) {
343                 flags |= kConstantOutputForConstantInput_OptimizationFlag;
344             }
345             if ((childFlags & kPreservesOpaqueInput_OptimizationFlag) && color.isOpaque()) {
346                 flags |= kPreservesOpaqueInput_OptimizationFlag;
347             }
348             return flags;
349         }
350 
351         void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override
352         {}
353 
354         bool onIsEqual(const GrFragmentProcessor& that) const override {
355             return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor;
356         }
357 
358         SkPMColor4f constantOutputForConstantInput(const SkPMColor4f&) const override {
359             return ConstantOutputForConstantInput(this->childProcessor(0), fColor);
360         }
361 
362         SkPMColor4f fColor;
363 
364         typedef GrFragmentProcessor INHERITED;
365     };
366 
367     if (!fp) {
368         return nullptr;
369     }
370     return ReplaceInputFragmentProcessor::Make(std::move(fp), color);
371 }
372 
373 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(
374         std::unique_ptr<GrFragmentProcessor>* series, int cnt) {
375     class SeriesFragmentProcessor : public GrFragmentProcessor {
376     public:
377         static std::unique_ptr<GrFragmentProcessor> Make(
378                 std::unique_ptr<GrFragmentProcessor>* children, int cnt) {
379             return std::unique_ptr<GrFragmentProcessor>(new SeriesFragmentProcessor(children, cnt));
380         }
381 
382         const char* name() const override { return "Series"; }
383 
384         std::unique_ptr<GrFragmentProcessor> clone() const override {
385             SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> children(this->numChildProcessors());
386             for (int i = 0; i < this->numChildProcessors(); ++i) {
387                 if (!children.push_back(this->childProcessor(i).clone())) {
388                     return nullptr;
389                 }
390             }
391             return Make(children.begin(), this->numChildProcessors());
392         }
393 
394     private:
395         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
396             class GLFP : public GrGLSLFragmentProcessor {
397             public:
398                 void emitCode(EmitArgs& args) override {
399                     // First guy's input might be nil.
400                     SkString temp("out0");
401                     this->emitChild(0, args.fInputColor, &temp, args);
402                     SkString input = temp;
403                     for (int i = 1; i < this->numChildProcessors() - 1; ++i) {
404                         temp.printf("out%d", i);
405                         this->emitChild(i, input.c_str(), &temp, args);
406                         input = temp;
407                     }
408                     // Last guy writes to our output variable.
409                     this->emitChild(this->numChildProcessors() - 1, input.c_str(), args);
410                 }
411             };
412             return new GLFP;
413         }
414 
415         SeriesFragmentProcessor(std::unique_ptr<GrFragmentProcessor>* children, int cnt)
416                 : INHERITED(kSeriesFragmentProcessor_ClassID, OptFlags(children, cnt)) {
417             SkASSERT(cnt > 1);
418             for (int i = 0; i < cnt; ++i) {
419                 this->registerChildProcessor(std::move(children[i]));
420             }
421         }
422 
423         static OptimizationFlags OptFlags(std::unique_ptr<GrFragmentProcessor>* children, int cnt) {
424             OptimizationFlags flags = kAll_OptimizationFlags;
425             for (int i = 0; i < cnt && flags != kNone_OptimizationFlags; ++i) {
426                 flags &= children[i]->optimizationFlags();
427             }
428             return flags;
429         }
430         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
431 
432         bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
433 
434         SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
435             SkPMColor4f color = inColor;
436             int childCnt = this->numChildProcessors();
437             for (int i = 0; i < childCnt; ++i) {
438                 color = ConstantOutputForConstantInput(this->childProcessor(i), color);
439             }
440             return color;
441         }
442 
443         typedef GrFragmentProcessor INHERITED;
444     };
445 
446     if (!cnt) {
447         return nullptr;
448     }
449     if (1 == cnt) {
450         return std::move(series[0]);
451     }
452     // Run the through the series, do the invariant output processing, and look for eliminations.
453     GrProcessorAnalysisColor inputColor;
454     inputColor.setToUnknown();
455     GrColorFragmentProcessorAnalysis info(inputColor, unique_ptr_address_as_pointer_address(series),
456                                           cnt);
457     SkTArray<std::unique_ptr<GrFragmentProcessor>> replacementSeries;
458     SkPMColor4f knownColor;
459     int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
460     if (leadingFPsToEliminate) {
461         std::unique_ptr<GrFragmentProcessor> colorFP(
462                 GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::InputMode::kIgnore));
463         if (leadingFPsToEliminate == cnt) {
464             return colorFP;
465         }
466         cnt = cnt - leadingFPsToEliminate + 1;
467         replacementSeries.reserve(cnt);
468         replacementSeries.emplace_back(std::move(colorFP));
469         for (int i = 0; i < cnt - 1; ++i) {
470             replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i]));
471         }
472         series = replacementSeries.begin();
473     }
474     return SeriesFragmentProcessor::Make(series, cnt);
475 }
476 
477 //////////////////////////////////////////////////////////////////////////////
478 
479 GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) {
480     for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
481         fFPStack.push_back(&pipeline.getFragmentProcessor(i));
482     }
483 }
484 
485 GrFragmentProcessor::Iter::Iter(const GrPaint& paint) {
486     for (int i = paint.numCoverageFragmentProcessors() - 1; i >= 0; --i) {
487         fFPStack.push_back(paint.getCoverageFragmentProcessor(i));
488     }
489     for (int i = paint.numColorFragmentProcessors() - 1; i >= 0; --i) {
490         fFPStack.push_back(paint.getColorFragmentProcessor(i));
491     }
492 }
493 
494 const GrFragmentProcessor* GrFragmentProcessor::Iter::next() {
495     if (fFPStack.empty()) {
496         return nullptr;
497     }
498     const GrFragmentProcessor* back = fFPStack.back();
499     fFPStack.pop_back();
500     for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
501         fFPStack.push_back(&back->childProcessor(i));
502     }
503     return back;
504 }
505 
506 ///////////////////////////////////////////////////////////////////////////////////////////////////
507 
508 GrFragmentProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
509                                                     const GrSamplerState& samplerState) {
510     this->reset(std::move(proxy), samplerState);
511 }
512 
513 GrFragmentProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
514                                                     GrSamplerState::Filter filterMode,
515                                                     GrSamplerState::WrapMode wrapXAndY) {
516     this->reset(std::move(proxy), filterMode, wrapXAndY);
517 }
518 
519 void GrFragmentProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
520                                                 const GrSamplerState& samplerState) {
521     fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
522     fSamplerState = samplerState;
523     fSamplerState.setFilterMode(SkTMin(samplerState.filter(), this->proxy()->highestFilterMode()));
524 }
525 
526 void GrFragmentProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
527                                                 GrSamplerState::Filter filterMode,
528                                                 GrSamplerState::WrapMode wrapXAndY) {
529     fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
530     filterMode = SkTMin(filterMode, this->proxy()->highestFilterMode());
531     fSamplerState = GrSamplerState(wrapXAndY, filterMode);
532 }
533