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