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