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 "GrProcessor.h"
12 
13 class GrCoordTransform;
14 class GrGLSLFragmentProcessor;
15 class GrInvariantOutput;
16 class GrPipeline;
17 class GrProcessorKeyBuilder;
18 class GrShaderCaps;
19 class GrSwizzle;
20 
21 /** Provides custom fragment shader code. Fragment processors receive an input color (vec4f) and
22     produce an output color. They may reference textures and uniforms. They may use
23     GrCoordTransforms to receive a transformation of the local coordinates that map from local space
24     to the fragment being processed.
25  */
26 class GrFragmentProcessor : public GrProcessor {
27 public:
28     /**
29     *  In many instances (e.g. SkShader::asFragmentProcessor() implementations) it is desirable to
30     *  only consider the input color's alpha. However, there is a competing desire to have reusable
31     *  GrFragmentProcessor subclasses that can be used in other scenarios where the entire input
32     *  color is considered. This function exists to filter the input color and pass it to a FP. It
33     *  does so by returning a parent FP that multiplies the passed in FPs output by the parent's
34     *  input alpha. The passed in FP will not receive an input color.
35     */
36     static sk_sp<GrFragmentProcessor> MulOutputByInputAlpha(sk_sp<GrFragmentProcessor>);
37 
38     /**
39      *  This assumes that the input color to the returned processor will be unpremul and that the
40      *  passed processor (which becomes the returned processor's child) produces a premul output.
41      *  The result of the returned processor is a premul of its input color modulated by the child
42      *  processor's premul output.
43      */
44     static sk_sp<GrFragmentProcessor> MakeInputPremulAndMulByOutput(sk_sp<GrFragmentProcessor>);
45 
46     /**
47      *  Returns a parent fragment processor that adopts the passed fragment processor as a child.
48      *  The parent will ignore its input color and instead feed the passed in color as input to the
49      *  child.
50      */
51     static sk_sp<GrFragmentProcessor> OverrideInput(sk_sp<GrFragmentProcessor>, GrColor4f);
52 
53     /**
54      *  Returns a fragment processor that premuls the input before calling the passed in fragment
55      *  processor.
56      */
57     static sk_sp<GrFragmentProcessor> PremulInput(sk_sp<GrFragmentProcessor>);
58 
59     /**
60      *  Returns a fragment processor that calls the passed in fragment processor, and then premuls
61      *  the output.
62      */
63     static sk_sp<GrFragmentProcessor> PremulOutput(sk_sp<GrFragmentProcessor>);
64 
65     /**
66      *  Returns a fragment processor that calls the passed in fragment processor, and then unpremuls
67      *  the output.
68      */
69     static sk_sp<GrFragmentProcessor> UnpremulOutput(sk_sp<GrFragmentProcessor>);
70 
71     /**
72      *  Returns a fragment processor that calls the passed in fragment processor, and then swizzles
73      *  the output.
74      */
75     static sk_sp<GrFragmentProcessor> SwizzleOutput(sk_sp<GrFragmentProcessor>, const GrSwizzle&);
76 
77     /**
78      * Returns a fragment processor that runs the passed in array of fragment processors in a
79      * series. The original input is passed to the first, the first's output is passed to the
80      * second, etc. The output of the returned processor is the output of the last processor of the
81      * series.
82      *
83      * The array elements with be moved.
84      */
85     static sk_sp<GrFragmentProcessor> RunInSeries(sk_sp<GrFragmentProcessor>*, int cnt);
86 
87     ~GrFragmentProcessor() override;
88 
89     GrGLSLFragmentProcessor* createGLSLInstance() const;
90 
getGLSLProcessorKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b)91     void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
92         this->onGetGLSLProcessorKey(caps, b);
93         for (int i = 0; i < fChildProcessors.count(); ++i) {
94             fChildProcessors[i]->getGLSLProcessorKey(caps, b);
95         }
96     }
97 
numCoordTransforms()98     int numCoordTransforms() const { return fCoordTransforms.count(); }
99 
100     /** Returns the coordinate transformation at index. index must be valid according to
101         numTransforms(). */
coordTransform(int index)102     const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
103 
coordTransforms()104     const SkTArray<const GrCoordTransform*, true>& coordTransforms() const {
105         return fCoordTransforms;
106     }
107 
numChildProcessors()108     int numChildProcessors() const { return fChildProcessors.count(); }
109 
childProcessor(int index)110     const GrFragmentProcessor& childProcessor(int index) const { return *fChildProcessors[index]; }
111 
112     /** Do any of the coordtransforms for this processor require local coords? */
usesLocalCoords()113     bool usesLocalCoords() const { return SkToBool(fFlags & kUsesLocalCoords_Flag); }
114 
115     /** Does this FP need a vector to the nearest edge? */
usesDistanceVectorField()116     bool usesDistanceVectorField() const {
117         return SkToBool(fFlags & kUsesDistanceVectorField_Flag);
118     }
119 
120     /**
121      * A GrDrawOp may premultiply its antialiasing coverage into its GrGeometryProcessor's color
122      * output under the following scenario:
123      *   * all the color fragment processors report true to this query,
124      *   * all the coverage fragment processors report true to this query,
125      *   * the blend mode arithmetic allows for it it.
126      * To be compatible a fragment processor's output must be a modulation of its input color or
127      * alpha with a computed premultiplied color or alpha that is in 0..1 range. The computed color
128      * or alpha that is modulated against the input cannot depend on the input's alpha. The computed
129      * value cannot depend on the input's color channels unless it unpremultiplies the input color
130      * channels by the input alpha.
131      */
compatibleWithCoverageAsAlpha()132     bool compatibleWithCoverageAsAlpha() const {
133         return SkToBool(fFlags & kCompatibleWithCoverageAsAlpha_OptimizationFlag);
134     }
135 
136     /**
137      * If this is true then all opaque input colors to the processor produce opaque output colors.
138      */
preservesOpaqueInput()139     bool preservesOpaqueInput() const {
140         return SkToBool(fFlags & kPreservesOpaqueInput_OptimizationFlag);
141     }
142 
143     /**
144      * Tests whether given a constant input color the processor produces a constant output color
145      * (for all fragments). If true outputColor will contain the constant color produces for
146      * inputColor.
147      */
hasConstantOutputForConstantInput(GrColor4f inputColor,GrColor4f * outputColor)148     bool hasConstantOutputForConstantInput(GrColor4f inputColor, GrColor4f* outputColor) const {
149         if (fFlags & kConstantOutputForConstantInput_OptimizationFlag) {
150             *outputColor = this->constantOutputForConstantInput(inputColor);
151             return true;
152         }
153         return false;
154     }
hasConstantOutputForConstantInput()155     bool hasConstantOutputForConstantInput() const {
156         return SkToBool(fFlags & kConstantOutputForConstantInput_OptimizationFlag);
157     }
158 
159     /** Returns true if this and other processor conservatively draw identically. It can only return
160         true when the two processor are of the same subclass (i.e. they return the same object from
161         from getFactory()).
162 
163         A return value of true from isEqual() should not be used to test whether the processor would
164         generate the same shader code. To test for identical code generation use getGLSLProcessorKey
165      */
166     bool isEqual(const GrFragmentProcessor& that) const;
167 
168     /**
169      * Pre-order traversal of a FP hierarchy, or of the forest of FPs in a GrPipeline. In the latter
170      * case the tree rooted at each FP in the GrPipeline is visited successively.
171      */
172     class Iter : public SkNoncopyable {
173     public:
Iter(const GrFragmentProcessor * fp)174         explicit Iter(const GrFragmentProcessor* fp) { fFPStack.push_back(fp); }
175         explicit Iter(const GrPipeline& pipeline);
176         const GrFragmentProcessor* next();
177 
178     private:
179         SkSTArray<4, const GrFragmentProcessor*, true> fFPStack;
180     };
181 
182     /**
183      * Iterates over all the Ts owned by a GrFragmentProcessor and its children or over all the Ts
184      * owned by the forest of GrFragmentProcessors in a GrPipeline. FPs are visited in the same
185      * order as Iter and each of an FP's Ts are visited in order.
186      */
187     template <typename T, typename BASE,
188               int (BASE::*COUNT)() const,
189               const T& (BASE::*GET)(int) const>
190     class FPItemIter : public SkNoncopyable {
191     public:
FPItemIter(const GrFragmentProcessor * fp)192         explicit FPItemIter(const GrFragmentProcessor* fp)
193                 : fCurrFP(nullptr)
194                 , fCTIdx(0)
195                 , fFPIter(fp) {
196             fCurrFP = fFPIter.next();
197         }
FPItemIter(const GrPipeline & pipeline)198         explicit FPItemIter(const GrPipeline& pipeline)
199                 : fCurrFP(nullptr)
200                 , fCTIdx(0)
201                 , fFPIter(pipeline) {
202             fCurrFP = fFPIter.next();
203         }
204 
next()205         const T* next() {
206             if (!fCurrFP) {
207                 return nullptr;
208             }
209             while (fCTIdx == (fCurrFP->*COUNT)()) {
210                 fCTIdx = 0;
211                 fCurrFP = fFPIter.next();
212                 if (!fCurrFP) {
213                     return nullptr;
214                 }
215             }
216             return &(fCurrFP->*GET)(fCTIdx++);
217         }
218 
219     private:
220         const GrFragmentProcessor*  fCurrFP;
221         int                         fCTIdx;
222         GrFragmentProcessor::Iter   fFPIter;
223     };
224 
225     using CoordTransformIter = FPItemIter<GrCoordTransform,
226                                           GrFragmentProcessor,
227                                           &GrFragmentProcessor::numCoordTransforms,
228                                           &GrFragmentProcessor::coordTransform>;
229 
230     using TextureAccessIter = FPItemIter<TextureSampler,
231                                          GrProcessor,
232                                          &GrProcessor::numTextureSamplers,
233                                          &GrProcessor::textureSampler>;
234 
235 protected:
236     enum OptimizationFlags : uint32_t {
237         kNone_OptimizationFlags,
238         kCompatibleWithCoverageAsAlpha_OptimizationFlag = 0x1,
239         kPreservesOpaqueInput_OptimizationFlag = 0x2,
240         kConstantOutputForConstantInput_OptimizationFlag = 0x4,
241         kAll_OptimizationFlags = kCompatibleWithCoverageAsAlpha_OptimizationFlag |
242                                  kPreservesOpaqueInput_OptimizationFlag |
243                                  kConstantOutputForConstantInput_OptimizationFlag
244     };
245     GR_DECL_BITFIELD_OPS_FRIENDS(OptimizationFlags)
246 
GrFragmentProcessor(OptimizationFlags optimizationFlags)247     GrFragmentProcessor(OptimizationFlags optimizationFlags) : fFlags(optimizationFlags) {
248         SkASSERT((fFlags & ~kAll_OptimizationFlags) == 0);
249     }
250 
optimizationFlags()251     OptimizationFlags optimizationFlags() const {
252         return static_cast<OptimizationFlags>(kAll_OptimizationFlags & fFlags);
253     }
254 
255     /**
256      * This allows one subclass to access another subclass's implementation of
257      * constantOutputForConstantInput. It must only be called when
258      * hasConstantOutputForConstantInput() is known to be true.
259      */
ConstantOutputForConstantInput(const GrFragmentProcessor & fp,GrColor4f input)260     static GrColor4f ConstantOutputForConstantInput(const GrFragmentProcessor& fp,
261                                                     GrColor4f input) {
262         SkASSERT(fp.hasConstantOutputForConstantInput());
263         return fp.constantOutputForConstantInput(input);
264     }
265 
266     /**
267      * Fragment Processor subclasses call this from their constructor to register coordinate
268      * transformations. Coord transforms provide a mechanism for a processor to receive coordinates
269      * in their FS code. The matrix expresses a transformation from local space. For a given
270      * fragment the matrix will be applied to the local coordinate that maps to the fragment.
271      *
272      * When the transformation has perspective, the transformed coordinates will have
273      * 3 components. Otherwise they'll have 2.
274      *
275      * This must only be called from the constructor because GrProcessors are immutable. The
276      * processor subclass manages the lifetime of the transformations (this function only stores a
277      * pointer). The GrCoordTransform is typically a member field of the GrProcessor subclass.
278      *
279      * A processor subclass that has multiple methods of construction should always add its coord
280      * transforms in a consistent order. The non-virtual implementation of isEqual() automatically
281      * compares transforms and will assume they line up across the two processor instances.
282      */
283     void addCoordTransform(const GrCoordTransform*);
284 
285     /**
286      * FragmentProcessor subclasses call this from their constructor to register any child
287      * FragmentProcessors they have. This must be called AFTER all texture accesses and coord
288      * transforms have been added.
289      * This is for processors whose shader code will be composed of nested processors whose output
290      * colors will be combined somehow to produce its output color.  Registering these child
291      * processors will allow the ProgramBuilder to automatically handle their transformed coords and
292      * texture accesses and mangle their uniform and output color names.
293      */
294     int registerChildProcessor(sk_sp<GrFragmentProcessor> child);
295 
296     /**
297      * Sub-classes should call this in their constructors if they need access to a distance
298      * vector field to the nearest edge
299      */
setWillUseDistanceVectorField()300     void setWillUseDistanceVectorField() { fFlags |= kUsesDistanceVectorField_Flag; }
301 
302 private:
303     void notifyRefCntIsZero() const final;
304 
constantOutputForConstantInput(GrColor4f)305     virtual GrColor4f constantOutputForConstantInput(GrColor4f /* inputColor */) const {
306         SkFAIL("Subclass must override this if advertising this optimization.");
307         return GrColor4f::TransparentBlack();
308     }
309 
310     /** Returns a new instance of the appropriate *GL* implementation class
311         for the given GrFragmentProcessor; caller is responsible for deleting
312         the object. */
313     virtual GrGLSLFragmentProcessor* onCreateGLSLInstance() const = 0;
314 
315     /** Implemented using GLFragmentProcessor::GenKey as described in this class's comment. */
316     virtual void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
317 
318     /**
319      * Subclass implements this to support isEqual(). It will only be called if it is known that
320      * the two processors are of the same subclass (i.e. they return the same object from
321      * getFactory()). The processor subclass should not compare its coord transforms as that will
322      * be performed automatically in the non-virtual isEqual().
323      */
324     virtual bool onIsEqual(const GrFragmentProcessor&) const = 0;
325 
326     bool hasSameTransforms(const GrFragmentProcessor&) const;
327 
328     enum PrivateFlags {
329         kFirstPrivateFlag = kAll_OptimizationFlags + 1,
330         kUsesLocalCoords_Flag = kFirstPrivateFlag,
331         kUsesDistanceVectorField_Flag = kFirstPrivateFlag << 1,
332     };
333 
334     mutable uint32_t fFlags = 0;
335 
336     SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
337 
338     /**
339      * This is not SkSTArray<1, sk_sp<GrFragmentProcessor>> because this class holds strong
340      * references until notifyRefCntIsZero and then it holds pending executions.
341      */
342     SkSTArray<1, GrFragmentProcessor*, true> fChildProcessors;
343 
344     typedef GrProcessor INHERITED;
345 };
346 
347 GR_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)
348 
349 #endif
350