LCOV - code coverage report
Current view: top level - gfx/skia/skia/include/gpu - GrFragmentProcessor.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 60 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 33 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 GrResourceIOProcessor, public GrProgramElement {
      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           0 :     void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
      92           0 :         this->onGetGLSLProcessorKey(caps, b);
      93           0 :         for (int i = 0; i < fChildProcessors.count(); ++i) {
      94           0 :             fChildProcessors[i]->getGLSLProcessorKey(caps, b);
      95             :         }
      96           0 :     }
      97             : 
      98           0 :     int numCoordTransforms() const { return fCoordTransforms.count(); }
      99             : 
     100             :     /** Returns the coordinate transformation at index. index must be valid according to
     101             :         numTransforms(). */
     102           0 :     const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
     103             : 
     104           0 :     const SkTArray<const GrCoordTransform*, true>& coordTransforms() const {
     105           0 :         return fCoordTransforms;
     106             :     }
     107             : 
     108           0 :     int numChildProcessors() const { return fChildProcessors.count(); }
     109             : 
     110           0 :     const GrFragmentProcessor& childProcessor(int index) const { return *fChildProcessors[index]; }
     111             : 
     112             :     /** Do any of the coordtransforms for this processor require local coords? */
     113           0 :     bool usesLocalCoords() const { return SkToBool(fFlags & kUsesLocalCoords_Flag); }
     114             : 
     115             :     /** Does this FP need a vector to the nearest edge? */
     116           0 :     bool usesDistanceVectorField() const {
     117           0 :         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           0 :     bool compatibleWithCoverageAsAlpha() const {
     133           0 :         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           0 :     bool preservesOpaqueInput() const {
     140           0 :         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           0 :     bool hasConstantOutputForConstantInput(GrColor4f inputColor, GrColor4f* outputColor) const {
     149           0 :         if (fFlags & kConstantOutputForConstantInput_OptimizationFlag) {
     150           0 :             *outputColor = this->constantOutputForConstantInput(inputColor);
     151           0 :             return true;
     152             :         }
     153           0 :         return false;
     154             :     }
     155           0 :     bool hasConstantOutputForConstantInput() const {
     156           0 :         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           0 :     class Iter : public SkNoncopyable {
     173             :     public:
     174           0 :         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           0 :     class FPItemIter : public SkNoncopyable {
     191             :     public:
     192           0 :         explicit FPItemIter(const GrFragmentProcessor* fp)
     193             :                 : fCurrFP(nullptr)
     194             :                 , fCTIdx(0)
     195           0 :                 , fFPIter(fp) {
     196           0 :             fCurrFP = fFPIter.next();
     197           0 :         }
     198           0 :         explicit FPItemIter(const GrPipeline& pipeline)
     199             :                 : fCurrFP(nullptr)
     200             :                 , fCTIdx(0)
     201           0 :                 , fFPIter(pipeline) {
     202           0 :             fCurrFP = fFPIter.next();
     203           0 :         }
     204             : 
     205           0 :         const T* next() {
     206           0 :             if (!fCurrFP) {
     207           0 :                 return nullptr;
     208             :             }
     209           0 :             while (fCTIdx == (fCurrFP->*COUNT)()) {
     210           0 :                 fCTIdx = 0;
     211           0 :                 fCurrFP = fFPIter.next();
     212           0 :                 if (!fCurrFP) {
     213           0 :                     return nullptr;
     214             :                 }
     215             :             }
     216           0 :             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             :                                          GrResourceIOProcessor,
     232             :                                          &GrResourceIOProcessor::numTextureSamplers,
     233             :                                          &GrResourceIOProcessor::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           0 :     GrFragmentProcessor(OptimizationFlags optimizationFlags) : fFlags(optimizationFlags) {
     248           0 :         SkASSERT((fFlags & ~kAll_OptimizationFlags) == 0);
     249           0 :     }
     250             : 
     251           0 :     OptimizationFlags optimizationFlags() const {
     252           0 :         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           0 :     static GrColor4f ConstantOutputForConstantInput(const GrFragmentProcessor& fp,
     261             :                                                     GrColor4f input) {
     262           0 :         SkASSERT(fp.hasConstantOutputForConstantInput());
     263           0 :         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           0 :     void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); }
     304           0 :     void removeRefs() const override { GrResourceIOProcessor::removeRefs(); }
     305           0 :     void pendingIOComplete() const override { GrResourceIOProcessor::pendingIOComplete(); }
     306             : 
     307             :     void notifyRefCntIsZero() const final;
     308             : 
     309           0 :     virtual GrColor4f constantOutputForConstantInput(GrColor4f /* inputColor */) const {
     310           0 :         SkFAIL("Subclass must override this if advertising this optimization.");
     311           0 :         return GrColor4f::TransparentBlack();
     312             :     }
     313             : 
     314             :     /** Returns a new instance of the appropriate *GL* implementation class
     315             :         for the given GrFragmentProcessor; caller is responsible for deleting
     316             :         the object. */
     317             :     virtual GrGLSLFragmentProcessor* onCreateGLSLInstance() const = 0;
     318             : 
     319             :     /** Implemented using GLFragmentProcessor::GenKey as described in this class's comment. */
     320             :     virtual void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
     321             : 
     322             :     /**
     323             :      * Subclass implements this to support isEqual(). It will only be called if it is known that
     324             :      * the two processors are of the same subclass (i.e. they return the same object from
     325             :      * getFactory()). The processor subclass should not compare its coord transforms as that will
     326             :      * be performed automatically in the non-virtual isEqual().
     327             :      */
     328             :     virtual bool onIsEqual(const GrFragmentProcessor&) const = 0;
     329             : 
     330             :     bool hasSameTransforms(const GrFragmentProcessor&) const;
     331             : 
     332             :     enum PrivateFlags {
     333             :         kFirstPrivateFlag = kAll_OptimizationFlags + 1,
     334             :         kUsesLocalCoords_Flag = kFirstPrivateFlag,
     335             :         kUsesDistanceVectorField_Flag = kFirstPrivateFlag << 1,
     336             :     };
     337             : 
     338             :     mutable uint32_t fFlags = 0;
     339             : 
     340             :     SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
     341             : 
     342             :     /**
     343             :      * This is not SkSTArray<1, sk_sp<GrFragmentProcessor>> because this class holds strong
     344             :      * references until notifyRefCntIsZero and then it holds pending executions.
     345             :      */
     346             :     SkSTArray<1, GrFragmentProcessor*, true> fChildProcessors;
     347             : 
     348             :     typedef GrProcessor INHERITED;
     349             : };
     350             : 
     351           0 : GR_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)
     352             : 
     353             : #endif

Generated by: LCOV version 1.13