• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 #ifndef GrFragmentProcessor_DEFINED
9 #define GrFragmentProcessor_DEFINED
10 
11 #include "include/private/SkMacros.h"
12 #include "include/private/SkSLSampleUsage.h"
13 #include "include/private/SkSLString.h"
14 #include "src/gpu/GrProcessor.h"
15 #include "src/gpu/glsl/GrGLSLUniformHandler.h"
16 
17 #include <tuple>
18 
19 class GrGLSLFPFragmentBuilder;
20 class GrGLSLProgramDataManager;
21 class GrPaint;
22 class GrPipeline;
23 class GrProcessorKeyBuilder;
24 class GrShaderCaps;
25 class GrSwizzle;
26 class GrTextureEffect;
27 
28 /**
29  * Some fragment-processor creation methods have preconditions that might not be satisfied by the
30  * calling code. Those methods can return a `GrFPResult` from their factory methods. If creation
31  * succeeds, the new fragment processor is created and `success` is true. If a precondition is not
32  * met, `success` is set to false and the input FP is returned unchanged.
33  */
34 class GrFragmentProcessor;
35 using GrFPResult = std::tuple<bool /*success*/, std::unique_ptr<GrFragmentProcessor>>;
36 
37 /** Provides custom fragment shader code. Fragment processors receive an input position and
38     produce an output color. They may contain uniforms and may have children fragment processors
39     that are sampled.
40  */
41 class GrFragmentProcessor : public GrProcessor {
42 public:
43     /**
44      * Every GrFragmentProcessor must be capable of creating a subclass of ProgramImpl. The
45      * ProgramImpl emits the fragment shader code that implements the GrFragmentProcessor, is
46      * attached to the generated backend API pipeline/program and used to extract uniform data from
47      * GrFragmentProcessor instances.
48      */
49     class ProgramImpl;
50 
51     // Advanced Filter: Get Advanced Filter status, only GrSkSLFP overwrite isAFEnabled
isAFEnabled()52     virtual bool isAFEnabled() const
53     {
54         return false;
55     }
56 
57     // Advanced Filter: Check Advanced Filter is enabled or not, by visiting its children recursively
58     // If one of its children enables AF, return true
59     bool checkAFRecursively() const;
60 
61     /** Always returns 'color'. */
62     static std::unique_ptr<GrFragmentProcessor> MakeColor(SkPMColor4f color);
63 
64     /**
65      *  Returns the input color, modulated by the child's alpha.
66      *
67      *  output = input * child.a
68      */
69     static std::unique_ptr<GrFragmentProcessor> MulInputByChildAlpha(
70             std::unique_ptr<GrFragmentProcessor> child);
71 
72     /**
73      *  Invokes child with an opaque version of the input color, then applies the input alpha to
74      *  the result. Used to incorporate paint alpha to the evaluation of an SkShader tree FP.
75      */
76     static std::unique_ptr<GrFragmentProcessor> ApplyPaintAlpha(
77             std::unique_ptr<GrFragmentProcessor> child);
78 
79     /**
80      *  Returns a fragment processor that generates the passed-in color, modulated by the child's
81      *  RGBA color. The child's input color will be the parent's fInputColor. (Pass a null FP to use
82      *  the color from fInputColor instead of a child FP.)
83      */
84     static std::unique_ptr<GrFragmentProcessor> ModulateRGBA(
85             std::unique_ptr<GrFragmentProcessor> child, const SkPMColor4f& color);
86 
87     /**
88      *  Returns a parent fragment processor that adopts the passed fragment processor as a child.
89      *  The parent will ignore its input color and instead feed the passed in color as input to the
90      *  child.
91      */
92     static std::unique_ptr<GrFragmentProcessor> OverrideInput(std::unique_ptr<GrFragmentProcessor>,
93                                                               const SkPMColor4f&);
94 
95     /**
96      *  Returns a parent fragment processor that adopts the passed fragment processor as a child.
97      *  The parent will simply return the child's color, but disable the coverage-as-alpha
98      *  optimization.
99      */
100     static std::unique_ptr<GrFragmentProcessor> DisableCoverageAsAlpha(
101             std::unique_ptr<GrFragmentProcessor>);
102 
103     /**
104      *  Returns a fragment processor which samples the passed-in fragment processor using
105      *  `args.fDestColor` as its input color. Pass a null FP to access `args.fDestColor` directly.
106      *  (This is only meaningful in contexts like blenders, which use a source and dest color.)
107      */
108     static std::unique_ptr<GrFragmentProcessor> UseDestColorAsInput(
109             std::unique_ptr<GrFragmentProcessor>);
110 
111     /**
112      *  Returns a fragment processor that calls the passed in fragment processor, and then swizzles
113      *  the output.
114      */
115     static std::unique_ptr<GrFragmentProcessor> SwizzleOutput(std::unique_ptr<GrFragmentProcessor>,
116                                                               const GrSwizzle&);
117 
118     /**
119      *  Returns a fragment processor that calls the passed in fragment processor, and then clamps
120      *  the output to [0, 1].
121      */
122     static std::unique_ptr<GrFragmentProcessor> ClampOutput(std::unique_ptr<GrFragmentProcessor>);
123 
124     /**
125      * Returns a fragment processor that composes two fragment processors `f` and `g` into f(g(x)).
126      * This is equivalent to running them in series (`g`, then `f`). This is not the same as
127      * transfer-mode composition; there is no blending step.
128      */
129     static std::unique_ptr<GrFragmentProcessor> Compose(std::unique_ptr<GrFragmentProcessor> f,
130                                                         std::unique_ptr<GrFragmentProcessor> g);
131 
132     /*
133      * Returns a fragment processor that calls the passed in fragment processor, then runs the
134      * resulting color through the supplied color matrix.
135      */
136     static std::unique_ptr<GrFragmentProcessor> ColorMatrix(
137             std::unique_ptr<GrFragmentProcessor> child,
138             const float matrix[20],
139             bool unpremulInput,
140             bool clampRGBOutput,
141             bool premulOutput);
142 
143     /**
144      * Returns a fragment processor that reads back the color on the surface being painted; that is,
145      * sampling this will return the color of the pixel that is currently being painted over.
146      */
147     static std::unique_ptr<GrFragmentProcessor> SurfaceColor();
148 
149     /**
150      * Returns a fragment processor that calls the passed in fragment processor, but evaluates it
151      * in device-space (rather than local space).
152      */
153     static std::unique_ptr<GrFragmentProcessor> DeviceSpace(std::unique_ptr<GrFragmentProcessor>);
154 
155     /**
156      * "Shape" FPs, often used for clipping. Each one evaluates a particular kind of shape (rect,
157      * circle, ellipse), and modulates the coverage of that shape against the results of the input
158      * FP. GrClipEdgeType is used to select inverse/normal fill, and AA or non-AA edges.
159      */
160     static std::unique_ptr<GrFragmentProcessor> Rect(std::unique_ptr<GrFragmentProcessor>,
161                                                      GrClipEdgeType,
162                                                      SkRect);
163 
164     static GrFPResult Circle(std::unique_ptr<GrFragmentProcessor>,
165                              GrClipEdgeType,
166                              SkPoint center,
167                              float radius);
168 
169     static GrFPResult Ellipse(std::unique_ptr<GrFragmentProcessor>,
170                               GrClipEdgeType,
171                               SkPoint center,
172                               SkPoint radii,
173                               const GrShaderCaps&);
174 
175     /**
176      * Returns a fragment processor that calls the passed in fragment processor, but ensures the
177      * entire program is compiled with high-precision types.
178      */
179     static std::unique_ptr<GrFragmentProcessor> HighPrecision(std::unique_ptr<GrFragmentProcessor>);
180 
181     /**
182      * Makes a copy of this fragment processor that draws equivalently to the original.
183      * If the processor has child processors they are cloned as well.
184      */
185     virtual std::unique_ptr<GrFragmentProcessor> clone() const = 0;
186 
187     // The FP this was registered with as a child function. This will be null if this is a root.
parent()188     const GrFragmentProcessor* parent() const { return fParent; }
189 
190     std::unique_ptr<ProgramImpl> makeProgramImpl() const;
191 
addToKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b)192     void addToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
193         this->onAddToKey(caps, b);
194         for (const auto& child : fChildProcessors) {
195             if (child) {
196                 child->addToKey(caps, b);
197             }
198         }
199     }
200 
numChildProcessors()201     int numChildProcessors() const { return fChildProcessors.count(); }
202     int numNonNullChildProcessors() const;
203 
childProcessor(int index)204     GrFragmentProcessor* childProcessor(int index) { return fChildProcessors[index].get(); }
childProcessor(int index)205     const GrFragmentProcessor* childProcessor(int index) const {
206         return fChildProcessors[index].get();
207     }
208 
SkDEBUGCODE(bool isInstantiated ()const;)209     SkDEBUGCODE(bool isInstantiated() const;)
210 
211     /** Do any of the FPs in this tree read back the color from the destination surface? */
212     bool willReadDstColor() const {
213         return SkToBool(fFlags & kWillReadDstColor_Flag);
214     }
215 
216     /** Does the SkSL for this FP take two colors as its input arguments? */
isBlendFunction()217     bool isBlendFunction() const {
218         return SkToBool(fFlags & kIsBlendFunction_Flag);
219     }
220 
221     /**
222      * True if this FP refers directly to the sample coordinate parameter of its function
223      * (e.g. uses EmitArgs::fSampleCoord in emitCode()). This is decided at FP-tree construction
224      * time and is not affected by lifting coords to varyings.
225      */
usesSampleCoordsDirectly()226     bool usesSampleCoordsDirectly() const {
227         return SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag);
228     }
229 
230     /**
231      * True if this FP uses its input coordinates or if any descendant FP uses them through a chain
232      * of non-explicit sample usages. (e.g. uses EmitArgs::fSampleCoord in emitCode()). This is
233      * decided at FP-tree construction time and is not affected by lifting coords to varyings.
234      */
usesSampleCoords()235     bool usesSampleCoords() const {
236         return SkToBool(fFlags & (kUsesSampleCoordsDirectly_Flag |
237                                   kUsesSampleCoordsIndirectly_Flag));
238     }
239 
240     // The SampleUsage describing how this FP is invoked by its parent. This only reflects the
241     // immediate sampling from parent to this FP.
sampleUsage()242     const SkSL::SampleUsage& sampleUsage() const {
243         return fUsage;
244     }
245 
246     /**
247      * A GrDrawOp may premultiply its antialiasing coverage into its GrGeometryProcessor's color
248      * output under the following scenario:
249      *   * all the color fragment processors report true to this query,
250      *   * all the coverage fragment processors report true to this query,
251      *   * the blend mode arithmetic allows for it it.
252      * To be compatible a fragment processor's output must be a modulation of its input color or
253      * alpha with a computed premultiplied color or alpha that is in 0..1 range. The computed color
254      * or alpha that is modulated against the input cannot depend on the input's alpha. The computed
255      * value cannot depend on the input's color channels unless it unpremultiplies the input color
256      * channels by the input alpha.
257      */
compatibleWithCoverageAsAlpha()258     bool compatibleWithCoverageAsAlpha() const {
259         return SkToBool(fFlags & kCompatibleWithCoverageAsAlpha_OptimizationFlag);
260     }
261 
262     /**
263      * If this is true then all opaque input colors to the processor produce opaque output colors.
264      */
preservesOpaqueInput()265     bool preservesOpaqueInput() const {
266         return SkToBool(fFlags & kPreservesOpaqueInput_OptimizationFlag);
267     }
268 
269     /**
270      * Tests whether given a constant input color the processor produces a constant output color
271      * (for all fragments). If true outputColor will contain the constant color produces for
272      * inputColor.
273      */
hasConstantOutputForConstantInput(SkPMColor4f inputColor,SkPMColor4f * outputColor)274     bool hasConstantOutputForConstantInput(SkPMColor4f inputColor, SkPMColor4f* outputColor) const {
275         if (fFlags & kConstantOutputForConstantInput_OptimizationFlag) {
276             *outputColor = this->constantOutputForConstantInput(inputColor);
277             return true;
278         }
279         return false;
280     }
hasConstantOutputForConstantInput()281     bool hasConstantOutputForConstantInput() const {
282         return SkToBool(fFlags & kConstantOutputForConstantInput_OptimizationFlag);
283     }
284 
285     /** Returns true if this and other processor conservatively draw identically. It can only return
286         true when the two processor are of the same subclass (i.e. they return the same object from
287         from getFactory()).
288 
289         A return value of true from isEqual() should not be used to test whether the processor would
290         generate the same shader code. To test for identical code generation use addToKey.
291      */
292     bool isEqual(const GrFragmentProcessor& that) const;
293 
294     void visitProxies(const GrVisitProxyFunc&) const;
295 
296     void visitTextureEffects(const std::function<void(const GrTextureEffect&)>&) const;
297 
298     void visitWithImpls(const std::function<void(const GrFragmentProcessor&, ProgramImpl&)>&,
299                         ProgramImpl&) const;
300 
301     GrTextureEffect* asTextureEffect();
302     const GrTextureEffect* asTextureEffect() const;
303 
304 #if GR_TEST_UTILS
305     // Generates debug info for this processor tree by recursively calling dumpInfo() on this
306     // processor and its children.
307     SkString dumpTreeInfo() const;
308 #endif
309 
310 protected:
311     enum OptimizationFlags : uint32_t {
312         kNone_OptimizationFlags,
313         kCompatibleWithCoverageAsAlpha_OptimizationFlag = 0x1,
314         kPreservesOpaqueInput_OptimizationFlag = 0x2,
315         kConstantOutputForConstantInput_OptimizationFlag = 0x4,
316         kAll_OptimizationFlags = kCompatibleWithCoverageAsAlpha_OptimizationFlag |
317                                  kPreservesOpaqueInput_OptimizationFlag |
318                                  kConstantOutputForConstantInput_OptimizationFlag
319     };
SK_DECL_BITFIELD_OPS_FRIENDS(OptimizationFlags)320     SK_DECL_BITFIELD_OPS_FRIENDS(OptimizationFlags)
321 
322     /**
323      * Can be used as a helper to decide which fragment processor OptimizationFlags should be set.
324      * This assumes that the subclass output color will be a modulation of the input color with a
325      * value read from a texture of the passed color type and that the texture contains
326      * premultiplied color or alpha values that are in range.
327      *
328      * Since there are multiple ways in which a sampler may have its coordinates clamped or wrapped,
329      * callers must determine on their own if the sampling uses a decal strategy in any way, in
330      * which case the texture may become transparent regardless of the color type.
331      */
332     static OptimizationFlags ModulateForSamplerOptFlags(SkAlphaType alphaType, bool samplingDecal) {
333         if (samplingDecal) {
334             return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
335         } else {
336             return ModulateForClampedSamplerOptFlags(alphaType);
337         }
338     }
339 
340     // As above, but callers should somehow ensure or assert their sampler still uses clamping
ModulateForClampedSamplerOptFlags(SkAlphaType alphaType)341     static OptimizationFlags ModulateForClampedSamplerOptFlags(SkAlphaType alphaType) {
342         if (alphaType == kOpaque_SkAlphaType) {
343             return kCompatibleWithCoverageAsAlpha_OptimizationFlag |
344                    kPreservesOpaqueInput_OptimizationFlag;
345         } else {
346             return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
347         }
348     }
349 
GrFragmentProcessor(ClassID classID,OptimizationFlags optimizationFlags)350     GrFragmentProcessor(ClassID classID, OptimizationFlags optimizationFlags)
351             : INHERITED(classID), fFlags(optimizationFlags) {
352         SkASSERT((optimizationFlags & ~kAll_OptimizationFlags) == 0);
353     }
354 
GrFragmentProcessor(const GrFragmentProcessor & src)355     explicit GrFragmentProcessor(const GrFragmentProcessor& src)
356             : INHERITED(src.classID()), fFlags(src.fFlags) {
357         this->cloneAndRegisterAllChildProcessors(src);
358     }
359 
optimizationFlags()360     OptimizationFlags optimizationFlags() const {
361         return static_cast<OptimizationFlags>(kAll_OptimizationFlags & fFlags);
362     }
363 
364     /** Useful when you can't call fp->optimizationFlags() on a base class object from a subclass.*/
ProcessorOptimizationFlags(const GrFragmentProcessor * fp)365     static OptimizationFlags ProcessorOptimizationFlags(const GrFragmentProcessor* fp) {
366         return fp ? fp->optimizationFlags() : kAll_OptimizationFlags;
367     }
368 
369     /**
370      * This allows one subclass to access another subclass's implementation of
371      * constantOutputForConstantInput. It must only be called when
372      * hasConstantOutputForConstantInput() is known to be true.
373      */
ConstantOutputForConstantInput(const GrFragmentProcessor * fp,const SkPMColor4f & input)374     static SkPMColor4f ConstantOutputForConstantInput(const GrFragmentProcessor* fp,
375                                                       const SkPMColor4f& input) {
376         if (fp) {
377             SkASSERT(fp->hasConstantOutputForConstantInput());
378             return fp->constantOutputForConstantInput(input);
379         } else {
380             return input;
381         }
382     }
383 
384     /**
385      * FragmentProcessor subclasses call this from their constructor to register any child
386      * FragmentProcessors they have. This must be called AFTER all texture accesses and coord
387      * transforms have been added.
388      * This is for processors whose shader code will be composed of nested processors whose output
389      * colors will be combined somehow to produce its output color. Registering these child
390      * processors will allow the ProgramBuilder to automatically handle their transformed coords and
391      * texture accesses and mangle their uniform and output color names.
392      *
393      * The SampleUsage parameter describes all of the ways that the child is sampled by the parent.
394      */
395     void registerChild(std::unique_ptr<GrFragmentProcessor> child,
396                        SkSL::SampleUsage sampleUsage = SkSL::SampleUsage::PassThrough());
397 
398     /**
399      * This method takes an existing fragment processor, clones all of its children, and registers
400      * the clones as children of this fragment processor.
401      */
402     void cloneAndRegisterAllChildProcessors(const GrFragmentProcessor& src);
403 
404     // FP implementations must call this function if their matching ProgramImpl's emitCode()
405     // function uses the EmitArgs::fSampleCoord variable in generated SkSL.
setUsesSampleCoordsDirectly()406     void setUsesSampleCoordsDirectly() {
407         fFlags |= kUsesSampleCoordsDirectly_Flag;
408     }
409 
410     // FP implementations must set this flag if their ProgramImpl's emitCode() function calls
411     // dstColor() to read back the framebuffer.
setWillReadDstColor()412     void setWillReadDstColor() {
413         fFlags |= kWillReadDstColor_Flag;
414     }
415 
416     // FP implementations must set this flag if their ProgramImpl's emitCode() function emits a
417     // blend function (taking two color inputs instead of just one).
setIsBlendFunction()418     void setIsBlendFunction() {
419         fFlags |= kIsBlendFunction_Flag;
420     }
421 
mergeOptimizationFlags(OptimizationFlags flags)422     void mergeOptimizationFlags(OptimizationFlags flags) {
423         SkASSERT((flags & ~kAll_OptimizationFlags) == 0);
424         fFlags &= (flags | ~kAll_OptimizationFlags);
425     }
426 
427 private:
constantOutputForConstantInput(const SkPMColor4f &)428     virtual SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& /* inputColor */) const {
429         SK_ABORT("Subclass must override this if advertising this optimization.");
430     }
431 
432     /**
433      * Returns a new instance of the appropriate ProgramImpl subclass for the given
434      * GrFragmentProcessor. It will emit the appropriate code and live with the cached program
435      * to setup uniform data for each draw that uses the program.
436      */
437     virtual std::unique_ptr<ProgramImpl> onMakeProgramImpl() const = 0;
438 
439     virtual void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
440 
441     /**
442      * Subclass implements this to support isEqual(). It will only be called if it is known that
443      * the two processors are of the same subclass (i.e. have the same ClassID).
444      */
445     virtual bool onIsEqual(const GrFragmentProcessor&) const = 0;
446 
447     enum PrivateFlags {
448         kFirstPrivateFlag = kAll_OptimizationFlags + 1,
449 
450         // Propagates up the FP tree to either root or first explicit sample usage.
451         kUsesSampleCoordsIndirectly_Flag = kFirstPrivateFlag,
452 
453         // Does not propagate at all. It means this FP uses its input sample coords in some way.
454         // Note passthrough and matrix sampling of children don't count as a usage of the coords.
455         // Because indirect sampling stops at an explicit sample usage it is imperative that a FP
456         // that calculates explicit coords for its children using its own sample coords sets this.
457         kUsesSampleCoordsDirectly_Flag = kFirstPrivateFlag << 1,
458 
459         // Does not propagate at all.
460         kIsBlendFunction_Flag = kFirstPrivateFlag << 2,
461 
462         // Propagates up the FP tree to the root.
463         kWillReadDstColor_Flag = kFirstPrivateFlag << 3,
464     };
465 
466     SkSTArray<1, std::unique_ptr<GrFragmentProcessor>, true> fChildProcessors;
467     const GrFragmentProcessor* fParent = nullptr;
468     uint32_t fFlags = 0;
469     SkSL::SampleUsage fUsage;
470 
471     using INHERITED = GrProcessor;
472 };
473 
474 //////////////////////////////////////////////////////////////////////////////
475 
476 class GrFragmentProcessor::ProgramImpl {
477 public:
478     ProgramImpl() = default;
479 
480     virtual ~ProgramImpl() = default;
481 
482     using UniformHandle = GrGLSLUniformHandler::UniformHandle;
483     using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
484 
485     /** Called when the program stage should insert its code into the shaders. The code in each
486         shader will be in its own block ({}) and so locally scoped names will not collide across
487         stages.
488 
489         @param fragBuilder       Interface used to emit code in the shaders.
490         @param uniformHandler    Interface used for accessing information about our uniforms
491         @param caps              The capabilities of the GPU which will render this FP
492         @param fp                The processor that generated this program stage.
493         @param inputColor        A half4 that holds the input color to the stage in the FS (or the
494                                  source color, for blend processors). nullptr inputs are converted
495                                  to "half4(1.0)" (solid white) during construction.
496                                  TODO: Better system for communicating optimization info
497                                  (e.g. input color is solid white, trans black, known to be opaque,
498                                  etc.) that allows the processor to communicate back similar known
499                                  info about its output.
500         @param destColor         A half4 that holds the dest color to the stage. Only meaningful
501                                  when the "is blend processor" FP flag is set.
502         @param sampleCoord       The name of a local coord reference to a float2 variable. Only
503                                  meaningful when the "references sample coords" FP flag is set.
504      */
505     struct EmitArgs {
EmitArgsEmitArgs506         EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder,
507                  GrGLSLUniformHandler* uniformHandler,
508                  const GrShaderCaps* caps,
509                  const GrFragmentProcessor& fp,
510                  const char* inputColor,
511                  const char* destColor,
512                  const char* sampleCoord)
513                 : fFragBuilder(fragBuilder)
514                 , fUniformHandler(uniformHandler)
515                 , fShaderCaps(caps)
516                 , fFp(fp)
517                 , fInputColor(inputColor ? inputColor : "half4(1.0)")
518                 , fDestColor(destColor)
519                 , fSampleCoord(sampleCoord) {}
520         GrGLSLFPFragmentBuilder* fFragBuilder;
521         GrGLSLUniformHandler* fUniformHandler;
522         const GrShaderCaps* fShaderCaps;
523         const GrFragmentProcessor& fFp;
524         const char* fInputColor;
525         const char* fDestColor;
526         const char* fSampleCoord;
527     };
528 
529     virtual void emitCode(EmitArgs&) = 0;
530 
531     // This does not recurse to any attached child processors. Recursing the entire processor tree
532     // is the responsibility of the caller.
533     void setData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor);
534 
numChildProcessors()535     int numChildProcessors() const { return fChildProcessors.count(); }
536 
childProcessor(int index)537     ProgramImpl* childProcessor(int index) const { return fChildProcessors[index].get(); }
538 
setFunctionName(SkString name)539     void setFunctionName(SkString name) {
540         SkASSERT(fFunctionName.isEmpty());
541         fFunctionName = std::move(name);
542     }
543 
functionName()544     const char* functionName() const {
545         SkASSERT(!fFunctionName.isEmpty());
546         return fFunctionName.c_str();
547     }
548 
549     // Invoke the child with the default input and destination colors (solid white)
550     inline SkString invokeChild(int childIndex,
551                                 EmitArgs& parentArgs,
552                                 SkSL::String skslCoords = "") {
553         return this->invokeChild(childIndex,
554                                  /*inputColor=*/nullptr,
555                                  /*destColor=*/nullptr,
556                                  parentArgs,
557                                  skslCoords);
558     }
559 
invokeChildWithMatrix(int childIndex,EmitArgs & parentArgs)560     inline SkString invokeChildWithMatrix(int childIndex, EmitArgs& parentArgs) {
561         return this->invokeChildWithMatrix(childIndex,
562                                            /*inputColor=*/nullptr,
563                                            /*destColor=*/nullptr,
564                                            parentArgs);
565     }
566 
567     // Invoke the child with the default destination color (solid white)
568     inline SkString invokeChild(int childIndex,
569                                 const char* inputColor,
570                                 EmitArgs& parentArgs,
571                                 SkSL::String skslCoords = "") {
572         return this->invokeChild(childIndex,
573                                  inputColor,
574                                  /*destColor=*/nullptr,
575                                  parentArgs,
576                                  skslCoords);
577     }
578 
invokeChildWithMatrix(int childIndex,const char * inputColor,EmitArgs & parentArgs)579     inline SkString invokeChildWithMatrix(int childIndex,
580                                           const char* inputColor,
581                                           EmitArgs& parentArgs) {
582         return this->invokeChildWithMatrix(childIndex,
583                                            inputColor,
584                                            /*destColor=*/nullptr,
585                                            parentArgs);
586     }
587 
588     /** Invokes a child proc in its own scope. Pass in the parent's EmitArgs and invokeChild will
589      *  automatically extract the coords and samplers of that child and pass them on to the child's
590      *  emitCode(). Also, any uniforms or functions emitted by the child will have their names
591      *  mangled to prevent redefinitions. The returned string contains the output color (as a call
592      *  to the child's helper function). It is legal to pass nullptr as inputColor, since all
593      *  fragment processors are required to work without an input color.
594      *
595      *  When skslCoords is empty, the child is invoked at the sample coordinates from parentArgs.
596      *  When skslCoords is not empty, is must be an SkSL expression that evaluates to a float2.
597      *  That expression is passed to the child's processor function as the "_coords" argument.
598      */
599     SkString invokeChild(int childIndex,
600                          const char* inputColor,
601                          const char* destColor,
602                          EmitArgs& parentArgs,
603                          SkSL::String skslCoords = "");
604 
605     /**
606      * As invokeChild, but transforms the coordinates according to the matrix expression attached
607      * to the child's SampleUsage object. This is only valid if the child is sampled with a
608      * const-uniform matrix.
609      */
610     SkString invokeChildWithMatrix(int childIndex,
611                                    const char* inputColor,
612                                    const char* destColor,
613                                    EmitArgs& parentArgs);
614 
615     /**
616      * Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
617      * GLSLFPS. If initialized with an array color followed by coverage processors installed in a
618      * program thenthe iteration order will agree with a GrFragmentProcessor::Iter initialized with
619      * a GrPipeline that produces the same program key.
620      */
621     class Iter {
622     public:
623         Iter(std::unique_ptr<ProgramImpl> fps[], int cnt);
Iter(ProgramImpl & fp)624         Iter(ProgramImpl& fp) { fFPStack.push_back(&fp); }
625 
626         ProgramImpl& operator*() const;
627         ProgramImpl* operator->() const;
628         Iter& operator++();
629         operator bool() const { return !fFPStack.empty(); }
630 
631         // Because each iterator carries a stack we want to avoid copies.
632         Iter(const Iter&) = delete;
633         Iter& operator=(const Iter&) = delete;
634 
635     private:
636         SkSTArray<4, ProgramImpl*, true> fFPStack;
637     };
638 
639 private:
640     /**
641      * A ProgramImpl instance can be reused with any GrFragmentProcessor that produces the same
642      * the same key; this function reads data from a GrFragmentProcessor and uploads any
643      * uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor
644      * parameter is guaranteed to be of the same type that created this ProgramImpl and
645      * to have an identical key as the one that created this ProgramImpl.
646      */
onSetData(const GrGLSLProgramDataManager &,const GrFragmentProcessor &)647     virtual void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) {}
648 
649     // The (mangled) name of our entry-point function
650     SkString fFunctionName;
651 
652     SkTArray<std::unique_ptr<ProgramImpl>, true> fChildProcessors;
653 
654     friend class GrFragmentProcessor;
655 };
656 
657 //////////////////////////////////////////////////////////////////////////////
658 
SK_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)659 SK_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)
660 
661 static inline GrFPResult GrFPFailure(std::unique_ptr<GrFragmentProcessor> fp) {
662     return {false, std::move(fp)};
663 }
GrFPSuccess(std::unique_ptr<GrFragmentProcessor> fp)664 static inline GrFPResult GrFPSuccess(std::unique_ptr<GrFragmentProcessor> fp) {
665     SkASSERT(fp);
666     return {true, std::move(fp)};
667 }
668 
669 #endif
670