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/GrOverrideInputFragmentProcessor.h"
14 #include "effects/GrPremulInputFragmentProcessor.h"
15 #include "effects/GrXfermodeFragmentProcessor.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         return false;
24     }
25     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     }
33     if (!this->hasSameTransforms(that)) {
34         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) {
43         if (!this->childProcessor(i).isEqual(that.childProcessor(i))) {
44             return false;
45         }
46     }
47     return true;
48 }
49 
visitProxies(const std::function<void (GrSurfaceProxy *)> & func)50 void GrFragmentProcessor::visitProxies(const std::function<void(GrSurfaceProxy*)>& func) {
51     GrFragmentProcessor::TextureAccessIter iter(this);
52     while (const TextureSampler* sampler = iter.next()) {
53         func(sampler->proxy());
54     }
55 }
56 
createGLSLInstance() const57 GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const {
58     GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance();
59     glFragProc->fChildProcessors.push_back_n(fChildProcessors.count());
60     for (int i = 0; i < fChildProcessors.count(); ++i) {
61         glFragProc->fChildProcessors[i] = fChildProcessors[i]->createGLSLInstance();
62     }
63     return glFragProc;
64 }
65 
textureSampler(int i) const66 const GrFragmentProcessor::TextureSampler& GrFragmentProcessor::textureSampler(int i) const {
67     SkASSERT(i >= 0 && i < fTextureSamplerCnt);
68     return this->onTextureSampler(i);
69 }
70 
addCoordTransform(const GrCoordTransform * transform)71 void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
72     fCoordTransforms.push_back(transform);
73     fFlags |= kUsesLocalCoords_Flag;
74     SkDEBUGCODE(transform->setInProcessor();)
75 }
76 
instantiate(GrResourceProvider * resourceProvider) const77 bool GrFragmentProcessor::instantiate(GrResourceProvider* resourceProvider) const {
78     for (int i = 0; i < fTextureSamplerCnt; ++i) {
79         if (!this->textureSampler(i).instantiate(resourceProvider)) {
80             return false;
81         }
82     }
83 
84     for (int i = 0; i < this->numChildProcessors(); ++i) {
85         if (!this->childProcessor(i).instantiate(resourceProvider)) {
86             return false;
87         }
88     }
89 
90     return true;
91 }
92 
markPendingExecution() const93 void GrFragmentProcessor::markPendingExecution() const {
94     for (int i = 0; i < fTextureSamplerCnt; ++i) {
95         auto* ref = this->textureSampler(i).proxyRef();
96         ref->markPendingIO();
97         ref->removeRef();
98     }
99     for (int i = 0; i < this->numChildProcessors(); ++i) {
100         this->childProcessor(i).markPendingExecution();
101     }
102 }
103 
registerChildProcessor(std::unique_ptr<GrFragmentProcessor> child)104 int GrFragmentProcessor::registerChildProcessor(std::unique_ptr<GrFragmentProcessor> child) {
105     if (child->usesLocalCoords()) {
106         fFlags |= kUsesLocalCoords_Flag;
107     }
108     fRequestedFeatures |= child->fRequestedFeatures;
109 
110     int index = fChildProcessors.count();
111     fChildProcessors.push_back(std::move(child));
112 
113     return index;
114 }
115 
hasSameTransforms(const GrFragmentProcessor & that) const116 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
117     if (this->numCoordTransforms() != that.numCoordTransforms()) {
118         return false;
119     }
120     int count = this->numCoordTransforms();
121     for (int i = 0; i < count; ++i) {
122         if (!this->coordTransform(i).hasSameEffectAs(that.coordTransform(i))) {
123             return false;
124         }
125     }
126     return true;
127 }
128 
MulChildByInputAlpha(std::unique_ptr<GrFragmentProcessor> fp)129 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulChildByInputAlpha(
130         std::unique_ptr<GrFragmentProcessor> fp) {
131     if (!fp) {
132         return nullptr;
133     }
134     return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn);
135 }
136 
MulInputByChildAlpha(std::unique_ptr<GrFragmentProcessor> fp)137 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulInputByChildAlpha(
138         std::unique_ptr<GrFragmentProcessor> fp) {
139     if (!fp) {
140         return nullptr;
141     }
142     return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kSrcIn);
143 }
144 
PremulInput(std::unique_ptr<GrFragmentProcessor> fp)145 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::PremulInput(
146         std::unique_ptr<GrFragmentProcessor> fp) {
147     if (!fp) {
148         return nullptr;
149     }
150     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { GrPremulInputFragmentProcessor::Make(),
151                                                           std::move(fp) };
152     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
153 }
154 
SwizzleOutput(std::unique_ptr<GrFragmentProcessor> fp,const GrSwizzle & swizzle)155 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(
156         std::unique_ptr<GrFragmentProcessor> fp, const GrSwizzle& swizzle) {
157     class SwizzleFragmentProcessor : public GrFragmentProcessor {
158     public:
159         static std::unique_ptr<GrFragmentProcessor> Make(const GrSwizzle& swizzle) {
160             return std::unique_ptr<GrFragmentProcessor>(new SwizzleFragmentProcessor(swizzle));
161         }
162 
163         const char* name() const override { return "Swizzle"; }
164         const GrSwizzle& swizzle() const { return fSwizzle; }
165 
166         std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(fSwizzle); }
167 
168     private:
169         SwizzleFragmentProcessor(const GrSwizzle& swizzle)
170                 : INHERITED(kSwizzleFragmentProcessor_ClassID, kAll_OptimizationFlags)
171                 , fSwizzle(swizzle) {}
172 
173         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
174             class GLFP : public GrGLSLFragmentProcessor {
175             public:
176                 void emitCode(EmitArgs& args) override {
177                     const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>();
178                     const GrSwizzle& swizzle = sfp.swizzle();
179                     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
180 
181                     fragBuilder->codeAppendf("%s = %s.%s;",
182                                              args.fOutputColor, args.fInputColor, swizzle.c_str());
183                 }
184             };
185             return new GLFP;
186         }
187 
188         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
189             b->add32(fSwizzle.asKey());
190         }
191 
192         bool onIsEqual(const GrFragmentProcessor& other) const override {
193             const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>();
194             return fSwizzle == sfp.fSwizzle;
195         }
196 
197         SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
198             return fSwizzle.applyTo(input);
199         }
200 
201         GrSwizzle fSwizzle;
202 
203         typedef GrFragmentProcessor INHERITED;
204     };
205 
206     if (!fp) {
207         return nullptr;
208     }
209     if (GrSwizzle::RGBA() == swizzle) {
210         return fp;
211     }
212     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { std::move(fp),
213                                                           SwizzleFragmentProcessor::Make(swizzle) };
214     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
215 }
216 
MakeInputPremulAndMulByOutput(std::unique_ptr<GrFragmentProcessor> fp)217 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput(
218         std::unique_ptr<GrFragmentProcessor> fp) {
219     class PremulFragmentProcessor : public GrFragmentProcessor {
220     public:
221         static std::unique_ptr<GrFragmentProcessor> Make(
222                 std::unique_ptr<GrFragmentProcessor> processor) {
223             return std::unique_ptr<GrFragmentProcessor>(
224                     new PremulFragmentProcessor(std::move(processor)));
225         }
226 
227         const char* name() const override { return "Premultiply"; }
228 
229         std::unique_ptr<GrFragmentProcessor> clone() const override {
230             return Make(this->childProcessor(0).clone());
231         }
232 
233     private:
234         PremulFragmentProcessor(std::unique_ptr<GrFragmentProcessor> processor)
235                 : INHERITED(kPremulFragmentProcessor_ClassID, OptFlags(processor.get())) {
236             this->registerChildProcessor(std::move(processor));
237         }
238 
239         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
240             class GLFP : public GrGLSLFragmentProcessor {
241             public:
242                 void emitCode(EmitArgs& args) override {
243                     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
244                     this->emitChild(0, args);
245                     fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor,
246                                                                 args.fInputColor);
247                     fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
248                 }
249             };
250             return new GLFP;
251         }
252 
253         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
254 
255         bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
256 
257         static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) {
258             OptimizationFlags flags = kNone_OptimizationFlags;
259             if (inner->preservesOpaqueInput()) {
260                 flags |= kPreservesOpaqueInput_OptimizationFlag;
261             }
262             if (inner->hasConstantOutputForConstantInput()) {
263                 flags |= kConstantOutputForConstantInput_OptimizationFlag;
264             }
265             return flags;
266         }
267 
268         SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
269             SkPMColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
270                                                                     SK_PMColor4fWHITE);
271             SkPMColor4f premulInput = SkColor4f{ input.fR, input.fG, input.fB, input.fA }.premul();
272             return premulInput * childColor;
273         }
274 
275         typedef GrFragmentProcessor INHERITED;
276     };
277     if (!fp) {
278         return nullptr;
279     }
280     return PremulFragmentProcessor::Make(std::move(fp));
281 }
282 
283 //////////////////////////////////////////////////////////////////////////////
284 
OverrideInput(std::unique_ptr<GrFragmentProcessor> fp,const SkPMColor4f & color,bool useUniform)285 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(
286         std::unique_ptr<GrFragmentProcessor> fp, const SkPMColor4f& color, bool useUniform) {
287     if (!fp) {
288         return nullptr;
289     }
290     return GrOverrideInputFragmentProcessor::Make(std::move(fp), color, useUniform);
291 }
292 
RunInSeries(std::unique_ptr<GrFragmentProcessor> * series,int cnt)293 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(
294         std::unique_ptr<GrFragmentProcessor>* series, int cnt) {
295     class SeriesFragmentProcessor : public GrFragmentProcessor {
296     public:
297         static std::unique_ptr<GrFragmentProcessor> Make(
298                 std::unique_ptr<GrFragmentProcessor>* children, int cnt) {
299             return std::unique_ptr<GrFragmentProcessor>(new SeriesFragmentProcessor(children, cnt));
300         }
301 
302         const char* name() const override { return "Series"; }
303 
304         std::unique_ptr<GrFragmentProcessor> clone() const override {
305             SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> children(this->numChildProcessors());
306             for (int i = 0; i < this->numChildProcessors(); ++i) {
307                 if (!children.push_back(this->childProcessor(i).clone())) {
308                     return nullptr;
309                 }
310             }
311             return Make(children.begin(), this->numChildProcessors());
312         }
313 
314     private:
315         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
316             class GLFP : public GrGLSLFragmentProcessor {
317             public:
318                 void emitCode(EmitArgs& args) override {
319                     // First guy's input might be nil.
320                     SkString temp("out0");
321                     this->emitChild(0, args.fInputColor, &temp, args);
322                     SkString input = temp;
323                     for (int i = 1; i < this->numChildProcessors() - 1; ++i) {
324                         temp.printf("out%d", i);
325                         this->emitChild(i, input.c_str(), &temp, args);
326                         input = temp;
327                     }
328                     // Last guy writes to our output variable.
329                     this->emitChild(this->numChildProcessors() - 1, input.c_str(), args);
330                 }
331             };
332             return new GLFP;
333         }
334 
335         SeriesFragmentProcessor(std::unique_ptr<GrFragmentProcessor>* children, int cnt)
336                 : INHERITED(kSeriesFragmentProcessor_ClassID, OptFlags(children, cnt)) {
337             SkASSERT(cnt > 1);
338             for (int i = 0; i < cnt; ++i) {
339                 this->registerChildProcessor(std::move(children[i]));
340             }
341         }
342 
343         static OptimizationFlags OptFlags(std::unique_ptr<GrFragmentProcessor>* children, int cnt) {
344             OptimizationFlags flags = kAll_OptimizationFlags;
345             for (int i = 0; i < cnt && flags != kNone_OptimizationFlags; ++i) {
346                 flags &= children[i]->optimizationFlags();
347             }
348             return flags;
349         }
350         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
351 
352         bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
353 
354         SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
355             SkPMColor4f color = inColor;
356             int childCnt = this->numChildProcessors();
357             for (int i = 0; i < childCnt; ++i) {
358                 color = ConstantOutputForConstantInput(this->childProcessor(i), color);
359             }
360             return color;
361         }
362 
363         typedef GrFragmentProcessor INHERITED;
364     };
365 
366     if (!cnt) {
367         return nullptr;
368     }
369     if (1 == cnt) {
370         return std::move(series[0]);
371     }
372     // Run the through the series, do the invariant output processing, and look for eliminations.
373     GrProcessorAnalysisColor inputColor;
374     inputColor.setToUnknown();
375     GrColorFragmentProcessorAnalysis info(inputColor, unique_ptr_address_as_pointer_address(series),
376                                           cnt);
377     SkTArray<std::unique_ptr<GrFragmentProcessor>> replacementSeries;
378     SkPMColor4f knownColor;
379     int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
380     if (leadingFPsToEliminate) {
381         std::unique_ptr<GrFragmentProcessor> colorFP(
382                 GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::InputMode::kIgnore));
383         if (leadingFPsToEliminate == cnt) {
384             return colorFP;
385         }
386         cnt = cnt - leadingFPsToEliminate + 1;
387         replacementSeries.reserve(cnt);
388         replacementSeries.emplace_back(std::move(colorFP));
389         for (int i = 0; i < cnt - 1; ++i) {
390             replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i]));
391         }
392         series = replacementSeries.begin();
393     }
394     return SeriesFragmentProcessor::Make(series, cnt);
395 }
396 
397 //////////////////////////////////////////////////////////////////////////////
398 
Iter(const GrPipeline & pipeline)399 GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) {
400     for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
401         fFPStack.push_back(&pipeline.getFragmentProcessor(i));
402     }
403 }
404 
Iter(const GrPaint & paint)405 GrFragmentProcessor::Iter::Iter(const GrPaint& paint) {
406     for (int i = paint.numCoverageFragmentProcessors() - 1; i >= 0; --i) {
407         fFPStack.push_back(paint.getCoverageFragmentProcessor(i));
408     }
409     for (int i = paint.numColorFragmentProcessors() - 1; i >= 0; --i) {
410         fFPStack.push_back(paint.getColorFragmentProcessor(i));
411     }
412 }
413 
next()414 const GrFragmentProcessor* GrFragmentProcessor::Iter::next() {
415     if (fFPStack.empty()) {
416         return nullptr;
417     }
418     const GrFragmentProcessor* back = fFPStack.back();
419     fFPStack.pop_back();
420     for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
421         fFPStack.push_back(&back->childProcessor(i));
422     }
423     return back;
424 }
425 
426 ///////////////////////////////////////////////////////////////////////////////////////////////////
427 
TextureSampler(sk_sp<GrTextureProxy> proxy,const GrSamplerState & samplerState)428 GrFragmentProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
429                                                     const GrSamplerState& samplerState) {
430     this->reset(std::move(proxy), samplerState);
431 }
432 
TextureSampler(sk_sp<GrTextureProxy> proxy,GrSamplerState::Filter filterMode,GrSamplerState::WrapMode wrapXAndY)433 GrFragmentProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
434                                                     GrSamplerState::Filter filterMode,
435                                                     GrSamplerState::WrapMode wrapXAndY) {
436     this->reset(std::move(proxy), filterMode, wrapXAndY);
437 }
438 
reset(sk_sp<GrTextureProxy> proxy,const GrSamplerState & samplerState)439 void GrFragmentProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
440                                                 const GrSamplerState& samplerState) {
441     fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
442     fSamplerState = samplerState;
443     fSamplerState.setFilterMode(SkTMin(samplerState.filter(), this->proxy()->highestFilterMode()));
444 }
445 
reset(sk_sp<GrTextureProxy> proxy,GrSamplerState::Filter filterMode,GrSamplerState::WrapMode wrapXAndY)446 void GrFragmentProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
447                                                 GrSamplerState::Filter filterMode,
448                                                 GrSamplerState::WrapMode wrapXAndY) {
449     fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
450     filterMode = SkTMin(filterMode, this->proxy()->highestFilterMode());
451     fSamplerState = GrSamplerState(wrapXAndY, filterMode);
452 }
453