• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     this->combineRequiredFeatures(*child);
82 
83     if (child->usesLocalCoords()) {
84         fFlags |= kUsesLocalCoords_Flag;
85     }
86 
87     int index = fChildProcessors.count();
88     fChildProcessors.push_back(std::move(child));
89 
90     return index;
91 }
92 
hasSameTransforms(const GrFragmentProcessor & that) const93 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
94     if (this->numCoordTransforms() != that.numCoordTransforms()) {
95         return false;
96     }
97     int count = this->numCoordTransforms();
98     for (int i = 0; i < count; ++i) {
99         if (!this->coordTransform(i).hasSameEffectAs(that.coordTransform(i))) {
100             return false;
101         }
102     }
103     return true;
104 }
105 
MulChildByInputAlpha(std::unique_ptr<GrFragmentProcessor> fp)106 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulChildByInputAlpha(
107         std::unique_ptr<GrFragmentProcessor> fp) {
108     if (!fp) {
109         return nullptr;
110     }
111     return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn);
112 }
113 
MulInputByChildAlpha(std::unique_ptr<GrFragmentProcessor> fp)114 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulInputByChildAlpha(
115         std::unique_ptr<GrFragmentProcessor> fp) {
116     if (!fp) {
117         return nullptr;
118     }
119     return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kSrcIn);
120 }
121 
PremulInput(std::unique_ptr<GrFragmentProcessor> fp)122 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::PremulInput(
123         std::unique_ptr<GrFragmentProcessor> fp) {
124     if (!fp) {
125         return nullptr;
126     }
127     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { GrPremulInputFragmentProcessor::Make(),
128                                                           std::move(fp) };
129     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
130 }
131 
PremulOutput(std::unique_ptr<GrFragmentProcessor> fp)132 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::PremulOutput(
133         std::unique_ptr<GrFragmentProcessor> fp) {
134     if (!fp) {
135         return nullptr;
136     }
137     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { std::move(fp),
138                                                           GrPremulInputFragmentProcessor::Make() };
139     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
140 }
141 
UnpremulOutput(std::unique_ptr<GrFragmentProcessor> fp)142 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::UnpremulOutput(
143         std::unique_ptr<GrFragmentProcessor> fp) {
144     if (!fp) {
145         return nullptr;
146     }
147     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { std::move(fp),
148                                                           GrUnpremulInputFragmentProcessor::Make() };
149     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
150 }
151 
SwizzleOutput(std::unique_ptr<GrFragmentProcessor> fp,const GrSwizzle & swizzle)152 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(
153         std::unique_ptr<GrFragmentProcessor> fp, const GrSwizzle& swizzle) {
154     class SwizzleFragmentProcessor : public GrFragmentProcessor {
155     public:
156         static std::unique_ptr<GrFragmentProcessor> Make(const GrSwizzle& swizzle) {
157             return std::unique_ptr<GrFragmentProcessor>(new SwizzleFragmentProcessor(swizzle));
158         }
159 
160         const char* name() const override { return "Swizzle"; }
161         const GrSwizzle& swizzle() const { return fSwizzle; }
162 
163         std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(fSwizzle); }
164 
165     private:
166         SwizzleFragmentProcessor(const GrSwizzle& swizzle)
167                 : INHERITED(kSwizzleFragmentProcessor_ClassID, kAll_OptimizationFlags)
168                 , fSwizzle(swizzle) {
169         }
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         GrColor4f constantOutputForConstantInput(GrColor4f 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 
MakeInputPremulAndMulByOutput(std::unique_ptr<GrFragmentProcessor> fp)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         GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
267             GrColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
268                                                                   GrColor4f::OpaqueWhite());
269             return GrColor4f(input.fRGBA[3] * input.fRGBA[0] * childColor.fRGBA[0],
270                              input.fRGBA[3] * input.fRGBA[1] * childColor.fRGBA[1],
271                              input.fRGBA[3] * input.fRGBA[2] * childColor.fRGBA[2],
272                              input.fRGBA[3] * childColor.fRGBA[3]);
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,GrColor4f color)285 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(
286         std::unique_ptr<GrFragmentProcessor> fp, GrColor4f color) {
287     class ReplaceInputFragmentProcessor : public GrFragmentProcessor {
288     public:
289         static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child,
290                                                          GrColor4f color) {
291             return std::unique_ptr<GrFragmentProcessor>(
292                     new ReplaceInputFragmentProcessor(std::move(child), color));
293         }
294 
295         const char* name() const override { return "Replace Color"; }
296 
297         std::unique_ptr<GrFragmentProcessor> clone() const override {
298             return Make(this->childProcessor(0).clone(), fColor);
299         }
300 
301     private:
302         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
303             class GLFP : public GrGLSLFragmentProcessor {
304             public:
305                 GLFP() : fHaveSetColor(false) {}
306                 void emitCode(EmitArgs& args) override {
307                     const char* colorName;
308                     fColorUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
309                                                                  kHalf4_GrSLType,
310                                                                  "Color", &colorName);
311                     this->emitChild(0, colorName, args);
312                 }
313 
314             private:
315                 void onSetData(const GrGLSLProgramDataManager& pdman,
316                                const GrFragmentProcessor& fp) override {
317                     GrColor4f color = fp.cast<ReplaceInputFragmentProcessor>().fColor;
318                     if (!fHaveSetColor || color != fPreviousColor) {
319                         pdman.set4fv(fColorUni, 1, color.fRGBA);
320                         fPreviousColor = color;
321                         fHaveSetColor = true;
322                     }
323                 }
324 
325                 GrGLSLProgramDataManager::UniformHandle fColorUni;
326                 bool      fHaveSetColor;
327                 GrColor4f fPreviousColor;
328             };
329 
330             return new GLFP;
331         }
332 
333         ReplaceInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> child, GrColor4f color)
334                 : INHERITED(kReplaceInputFragmentProcessor_ClassID, OptFlags(child.get(), color))
335                 , fColor(color) {
336             this->registerChildProcessor(std::move(child));
337         }
338 
339         static OptimizationFlags OptFlags(const GrFragmentProcessor* child, GrColor4f 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         GrColor4f constantOutputForConstantInput(GrColor4f) const override {
359             return ConstantOutputForConstantInput(this->childProcessor(0), fColor);
360         }
361 
362         GrColor4f 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 
RunInSeries(std::unique_ptr<GrFragmentProcessor> * series,int cnt)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         GrColor4f constantOutputForConstantInput(GrColor4f color) const override {
435             int childCnt = this->numChildProcessors();
436             for (int i = 0; i < childCnt; ++i) {
437                 color = ConstantOutputForConstantInput(this->childProcessor(i), color);
438             }
439             return color;
440         }
441 
442         typedef GrFragmentProcessor INHERITED;
443     };
444 
445     if (!cnt) {
446         return nullptr;
447     }
448     if (1 == cnt) {
449         return std::move(series[0]);
450     }
451     // Run the through the series, do the invariant output processing, and look for eliminations.
452     GrProcessorAnalysisColor inputColor;
453     inputColor.setToUnknown();
454     GrColorFragmentProcessorAnalysis info(inputColor, unique_ptr_address_as_pointer_address(series),
455                                           cnt);
456     SkTArray<std::unique_ptr<GrFragmentProcessor>> replacementSeries;
457     GrColor4f knownColor;
458     int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
459     if (leadingFPsToEliminate) {
460         std::unique_ptr<GrFragmentProcessor> colorFP(
461                 GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::InputMode::kIgnore));
462         if (leadingFPsToEliminate == cnt) {
463             return colorFP;
464         }
465         cnt = cnt - leadingFPsToEliminate + 1;
466         replacementSeries.reserve(cnt);
467         replacementSeries.emplace_back(std::move(colorFP));
468         for (int i = 0; i < cnt - 1; ++i) {
469             replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i]));
470         }
471         series = replacementSeries.begin();
472     }
473     return SeriesFragmentProcessor::Make(series, cnt);
474 }
475 
476 //////////////////////////////////////////////////////////////////////////////
477 
Iter(const GrPipeline & pipeline)478 GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) {
479     for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
480         fFPStack.push_back(&pipeline.getFragmentProcessor(i));
481     }
482 }
483 
next()484 const GrFragmentProcessor* GrFragmentProcessor::Iter::next() {
485     if (fFPStack.empty()) {
486         return nullptr;
487     }
488     const GrFragmentProcessor* back = fFPStack.back();
489     fFPStack.pop_back();
490     for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
491         fFPStack.push_back(&back->childProcessor(i));
492     }
493     return back;
494 }
495 
496