• 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/GrClampFragmentProcessor.h"
14 #include "src/gpu/effects/generated/GrConstColorProcessor.h"
15 #include "src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h"
16 #include "src/gpu/effects/generated/GrPremulInputFragmentProcessor.h"
17 #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
18 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
19 #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
20 #include "src/gpu/glsl/GrGLSLUniformHandler.h"
21 
isEqual(const GrFragmentProcessor & that) const22 bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
23     if (this->classID() != that.classID()) {
24         return false;
25     }
26     if (this->numTextureSamplers() != that.numTextureSamplers()) {
27         return false;
28     }
29     for (int i = 0; i < this->numTextureSamplers(); ++i) {
30         if (this->textureSampler(i) != that.textureSampler(i)) {
31             return false;
32         }
33     }
34     if (!this->hasSameTransforms(that)) {
35         return false;
36     }
37     if (!this->onIsEqual(that)) {
38         return false;
39     }
40     if (this->numChildProcessors() != that.numChildProcessors()) {
41         return false;
42     }
43     for (int i = 0; i < this->numChildProcessors(); ++i) {
44         if (!this->childProcessor(i).isEqual(that.childProcessor(i))) {
45             return false;
46         }
47     }
48     return true;
49 }
50 
visitProxies(const GrOp::VisitProxyFunc & func)51 void GrFragmentProcessor::visitProxies(const GrOp::VisitProxyFunc& func) {
52     for (auto [sampler, fp] : FPTextureSamplerRange(*this)) {
53         bool mipped = (GrSamplerState::Filter::kMipMap == sampler.samplerState().filter());
54         func(sampler.view().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(GrCoordTransform * transform)72 void GrFragmentProcessor::addCoordTransform(GrCoordTransform* transform) {
73     fCoordTransforms.push_back(transform);
74     fFlags |= kHasCoordTransforms_Flag;
75 }
76 
77 #ifdef SK_DEBUG
isInstantiated() const78 bool GrFragmentProcessor::isInstantiated() const {
79     for (int i = 0; i < fTextureSamplerCnt; ++i) {
80         if (!this->textureSampler(i).isInstantiated()) {
81             return false;
82         }
83     }
84 
85     for (int i = 0; i < this->numChildProcessors(); ++i) {
86         if (!this->childProcessor(i).isInstantiated()) {
87             return false;
88         }
89     }
90 
91     return true;
92 }
93 #endif
94 
registerChildProcessor(std::unique_ptr<GrFragmentProcessor> child)95 int GrFragmentProcessor::registerChildProcessor(std::unique_ptr<GrFragmentProcessor> child) {
96     if (child->fFlags & kHasCoordTransforms_Flag) {
97         fFlags |= kHasCoordTransforms_Flag;
98     }
99     fRequestedFeatures |= child->fRequestedFeatures;
100 
101     int index = fChildProcessors.count();
102     fChildProcessors.push_back(std::move(child));
103 
104     return index;
105 }
106 
hasSameTransforms(const GrFragmentProcessor & that) const107 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
108     if (this->numCoordTransforms() != that.numCoordTransforms()) {
109         return false;
110     }
111     int count = this->numCoordTransforms();
112     for (int i = 0; i < count; ++i) {
113         if (!this->coordTransform(i).hasSameEffectiveMatrix(that.coordTransform(i))) {
114             return false;
115         }
116     }
117     return true;
118 }
119 
MulChildByInputAlpha(std::unique_ptr<GrFragmentProcessor> fp)120 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulChildByInputAlpha(
121         std::unique_ptr<GrFragmentProcessor> fp) {
122     if (!fp) {
123         return nullptr;
124     }
125     return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn);
126 }
127 
MulInputByChildAlpha(std::unique_ptr<GrFragmentProcessor> fp)128 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulInputByChildAlpha(
129         std::unique_ptr<GrFragmentProcessor> fp) {
130     if (!fp) {
131         return nullptr;
132     }
133     return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kSrcIn);
134 }
135 
PremulInput(std::unique_ptr<GrFragmentProcessor> fp)136 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::PremulInput(
137         std::unique_ptr<GrFragmentProcessor> fp) {
138     if (!fp) {
139         return nullptr;
140     }
141     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { GrPremulInputFragmentProcessor::Make(),
142                                                           std::move(fp) };
143     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
144 }
145 
ClampPremulOutput(std::unique_ptr<GrFragmentProcessor> fp)146 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ClampPremulOutput(
147         std::unique_ptr<GrFragmentProcessor> fp) {
148     if (!fp) {
149         return nullptr;
150     }
151     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = {
152         std::move(fp),
153         GrClampFragmentProcessor::Make(true)
154     };
155     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
156 }
157 
SwizzleOutput(std::unique_ptr<GrFragmentProcessor> fp,const GrSwizzle & swizzle)158 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(
159         std::unique_ptr<GrFragmentProcessor> fp, const GrSwizzle& swizzle) {
160     class SwizzleFragmentProcessor : public GrFragmentProcessor {
161     public:
162         static std::unique_ptr<GrFragmentProcessor> Make(const GrSwizzle& swizzle) {
163             return std::unique_ptr<GrFragmentProcessor>(new SwizzleFragmentProcessor(swizzle));
164         }
165 
166         const char* name() const override { return "Swizzle"; }
167         const GrSwizzle& swizzle() const { return fSwizzle; }
168 
169         std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(fSwizzle); }
170 
171     private:
172         SwizzleFragmentProcessor(const GrSwizzle& swizzle)
173                 : INHERITED(kSwizzleFragmentProcessor_ClassID, kAll_OptimizationFlags)
174                 , fSwizzle(swizzle) {}
175 
176         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
177             class GLFP : public GrGLSLFragmentProcessor {
178             public:
179                 void emitCode(EmitArgs& args) override {
180                     const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>();
181                     const GrSwizzle& swizzle = sfp.swizzle();
182                     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
183 
184                     fragBuilder->codeAppendf("%s = %s.%s;",
185                             args.fOutputColor, args.fInputColor, swizzle.asString().c_str());
186                 }
187             };
188             return new GLFP;
189         }
190 
191         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
192             b->add32(fSwizzle.asKey());
193         }
194 
195         bool onIsEqual(const GrFragmentProcessor& other) const override {
196             const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>();
197             return fSwizzle == sfp.fSwizzle;
198         }
199 
200         SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
201             return fSwizzle.applyTo(input);
202         }
203 
204         GrSwizzle fSwizzle;
205 
206         typedef GrFragmentProcessor INHERITED;
207     };
208 
209     if (!fp) {
210         return nullptr;
211     }
212     if (GrSwizzle::RGBA() == swizzle) {
213         return fp;
214     }
215     std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { std::move(fp),
216                                                           SwizzleFragmentProcessor::Make(swizzle) };
217     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
218 }
219 
MakeInputPremulAndMulByOutput(std::unique_ptr<GrFragmentProcessor> fp)220 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput(
221         std::unique_ptr<GrFragmentProcessor> fp) {
222     class PremulFragmentProcessor : public GrFragmentProcessor {
223     public:
224         static std::unique_ptr<GrFragmentProcessor> Make(
225                 std::unique_ptr<GrFragmentProcessor> processor) {
226             return std::unique_ptr<GrFragmentProcessor>(
227                     new PremulFragmentProcessor(std::move(processor)));
228         }
229 
230         const char* name() const override { return "Premultiply"; }
231 
232         std::unique_ptr<GrFragmentProcessor> clone() const override {
233             return Make(this->childProcessor(0).clone());
234         }
235 
236     private:
237         PremulFragmentProcessor(std::unique_ptr<GrFragmentProcessor> processor)
238                 : INHERITED(kPremulFragmentProcessor_ClassID, OptFlags(processor.get())) {
239             this->registerChildProcessor(std::move(processor));
240         }
241 
242         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
243             class GLFP : public GrGLSLFragmentProcessor {
244             public:
245                 void emitCode(EmitArgs& args) override {
246                     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
247                     SkString temp = this->invokeChild(0, args);
248                     fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, temp.c_str());
249                     fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor,
250                                                                   args.fInputColor);
251                     fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
252                 }
253             };
254             return new GLFP;
255         }
256 
257         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
258 
259         bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
260 
261         static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) {
262             OptimizationFlags flags = kNone_OptimizationFlags;
263             if (inner->preservesOpaqueInput()) {
264                 flags |= kPreservesOpaqueInput_OptimizationFlag;
265             }
266             if (inner->hasConstantOutputForConstantInput()) {
267                 flags |= kConstantOutputForConstantInput_OptimizationFlag;
268             }
269             return flags;
270         }
271 
272         SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
273             SkPMColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
274                                                                     SK_PMColor4fWHITE);
275             SkPMColor4f premulInput = SkColor4f{ input.fR, input.fG, input.fB, input.fA }.premul();
276             return premulInput * childColor;
277         }
278 
279         typedef GrFragmentProcessor INHERITED;
280     };
281     if (!fp) {
282         return nullptr;
283     }
284     return PremulFragmentProcessor::Make(std::move(fp));
285 }
286 
287 //////////////////////////////////////////////////////////////////////////////
288 
OverrideInput(std::unique_ptr<GrFragmentProcessor> fp,const SkPMColor4f & color,bool useUniform)289 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(
290         std::unique_ptr<GrFragmentProcessor> fp, const SkPMColor4f& color, bool useUniform) {
291     if (!fp) {
292         return nullptr;
293     }
294     return GrOverrideInputFragmentProcessor::Make(std::move(fp), color, useUniform);
295 }
296 
RunInSeries(std::unique_ptr<GrFragmentProcessor> series[],int cnt)297 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(
298         std::unique_ptr<GrFragmentProcessor> series[], int cnt) {
299     class SeriesFragmentProcessor : public GrFragmentProcessor {
300     public:
301         static std::unique_ptr<GrFragmentProcessor> Make(
302                 std::unique_ptr<GrFragmentProcessor>* children, int cnt) {
303             return std::unique_ptr<GrFragmentProcessor>(new SeriesFragmentProcessor(children, cnt));
304         }
305 
306         const char* name() const override { return "Series"; }
307 
308         std::unique_ptr<GrFragmentProcessor> clone() const override {
309             SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> children(this->numChildProcessors());
310             for (int i = 0; i < this->numChildProcessors(); ++i) {
311                 if (!children.push_back(this->childProcessor(i).clone())) {
312                     return nullptr;
313                 }
314             }
315             return Make(children.begin(), this->numChildProcessors());
316         }
317 
318     private:
319         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
320             class GLFP : public GrGLSLFragmentProcessor {
321             public:
322                 void emitCode(EmitArgs& args) override {
323                     // First guy's input might be nil.
324                     SkString result = this->invokeChild(0, args.fInputColor, args);
325                     for (int i = 1; i < this->numChildProcessors(); ++i) {
326                         result = this->invokeChild(i, result.c_str(), args);
327                     }
328                     // Copy last output to our output variable
329                     args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, result.c_str());
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, series, cnt);
376     SkTArray<std::unique_ptr<GrFragmentProcessor>> replacementSeries;
377     SkPMColor4f knownColor;
378     int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
379     if (leadingFPsToEliminate) {
380         std::unique_ptr<GrFragmentProcessor> colorFP(
381                 GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::InputMode::kIgnore));
382         if (leadingFPsToEliminate == cnt) {
383             return colorFP;
384         }
385         cnt = cnt - leadingFPsToEliminate + 1;
386         replacementSeries.reserve(cnt);
387         replacementSeries.emplace_back(std::move(colorFP));
388         for (int i = 0; i < cnt - 1; ++i) {
389             replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i]));
390         }
391         series = replacementSeries.begin();
392     }
393     return SeriesFragmentProcessor::Make(series, cnt);
394 }
395 
396 //////////////////////////////////////////////////////////////////////////////
397 
CIter(const GrPaint & paint)398 GrFragmentProcessor::CIter::CIter(const GrPaint& paint) {
399     for (int i = paint.numCoverageFragmentProcessors() - 1; i >= 0; --i) {
400         fFPStack.push_back(paint.getCoverageFragmentProcessor(i));
401     }
402     for (int i = paint.numColorFragmentProcessors() - 1; i >= 0; --i) {
403         fFPStack.push_back(paint.getColorFragmentProcessor(i));
404     }
405 }
406 
CIter(const GrProcessorSet & set)407 GrFragmentProcessor::CIter::CIter(const GrProcessorSet& set) {
408     for (int i = set.numCoverageFragmentProcessors() - 1; i >= 0; --i) {
409         fFPStack.push_back(set.coverageFragmentProcessor(i));
410     }
411     for (int i = set.numColorFragmentProcessors() - 1; i >= 0; --i) {
412         fFPStack.push_back(set.colorFragmentProcessor(i));
413     }
414 }
415 
CIter(const GrPipeline & pipeline)416 GrFragmentProcessor::CIter::CIter(const GrPipeline& pipeline) {
417     for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
418         fFPStack.push_back(&pipeline.getFragmentProcessor(i));
419     }
420 }
421 
422 ///////////////////////////////////////////////////////////////////////////////////////////////////
423 
TextureSampler(GrSurfaceProxyView view,GrSamplerState samplerState)424 GrFragmentProcessor::TextureSampler::TextureSampler(GrSurfaceProxyView view,
425                                                     GrSamplerState samplerState)
426         : fView(std::move(view)), fSamplerState(samplerState) {
427     GrSurfaceProxy* proxy = this->proxy();
428     fSamplerState.setFilterMode(
429             std::min(samplerState.filter(),
430                    GrTextureProxy::HighestFilterMode(proxy->backendFormat().textureType())));
431 }
432 
433 #if GR_TEST_UTILS
set(GrSurfaceProxyView view,GrSamplerState samplerState)434 void GrFragmentProcessor::TextureSampler::set(GrSurfaceProxyView view,
435                                               GrSamplerState samplerState) {
436     SkASSERT(view.proxy()->asTextureProxy());
437     fView = std::move(view);
438     fSamplerState = samplerState;
439 
440     fSamplerState.setFilterMode(
441             std::min(samplerState.filter(),
442                    GrTextureProxy::HighestFilterMode(this->proxy()->backendFormat().textureType())));
443 }
444 #endif
445