Home | History | Annotate | Download | only in gpu
      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 
     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 
     98     int numCoordTransforms() const { return fCoordTransforms.count(); }
     99 
    100     /** Returns the coordinate transformation at index. index must be valid according to
    101         numTransforms(). */
    102     const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
    103 
    104     const SkTArray<const GrCoordTransform*, true>& coordTransforms() const {
    105         return fCoordTransforms;
    106     }
    107 
    108     int numChildProcessors() const { return fChildProcessors.count(); }
    109 
    110     const GrFragmentProcessor& childProcessor(int index) const { return *fChildProcessors[index]; }
    111 
    112     /** Do any of the coordtransforms for this processor require local coords? */
    113     bool usesLocalCoords() const { return SkToBool(fFlags & kUsesLocalCoords_Flag); }
    114 
    115     /** Does this FP need a vector to the nearest edge? */
    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      */
    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      */
    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      */
    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     }
    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:
    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:
    192         explicit FPItemIter(const GrFragmentProcessor* fp)
    193                 : fCurrFP(nullptr)
    194                 , fCTIdx(0)
    195                 , fFPIter(fp) {
    196             fCurrFP = fFPIter.next();
    197         }
    198         explicit FPItemIter(const GrPipeline& pipeline)
    199                 : fCurrFP(nullptr)
    200                 , fCTIdx(0)
    201                 , fFPIter(pipeline) {
    202             fCurrFP = fFPIter.next();
    203         }
    204 
    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 
    247     GrFragmentProcessor(OptimizationFlags optimizationFlags) : fFlags(optimizationFlags) {
    248         SkASSERT((fFlags & ~kAll_OptimizationFlags) == 0);
    249     }
    250 
    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      */
    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      */
    300     void setWillUseDistanceVectorField() { fFlags |= kUsesDistanceVectorField_Flag; }
    301 
    302 private:
    303     void notifyRefCntIsZero() const final;
    304 
    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