Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2013 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 GrPrimitiveProcessor_DEFINED
      9 #define GrPrimitiveProcessor_DEFINED
     10 
     11 #include "GrColor.h"
     12 #include "GrProcessor.h"
     13 #include "GrShaderVar.h"
     14 
     15 /*
     16  * The GrPrimitiveProcessor represents some kind of geometric primitive.  This includes the shape
     17  * of the primitive and the inherent color of the primitive.  The GrPrimitiveProcessor is
     18  * responsible for providing a color and coverage input into the Ganesh rendering pipeline.  Through
     19  * optimization, Ganesh may decide a different color, no color, and / or no coverage are required
     20  * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to support this
     21  * functionality.  We also use the GrPrimitiveProcessor to make batching decisions.
     22  *
     23  * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
     24  * GrPrimitiveProcessor.  These loops run on the CPU and compute any invariant components which
     25  * might be useful for correctness / optimization decisions.  The GrPrimitiveProcessor seeds these
     26  * loops, one with initial color and one with initial coverage, in its
     27  * onComputeInvariantColor / Coverage calls.  These seed values are processed by the subsequent
     28  * stages of the rendering pipeline and the output is then fed back into the GrPrimitiveProcessor in
     29  * the initBatchTracker call, where the GrPrimitiveProcessor can then initialize the GrBatchTracker
     30  * struct with the appropriate values.
     31  *
     32  * We are evolving this system to move towards generating geometric meshes and their associated
     33  * vertex data after we have batched and reordered draws.  This system, known as 'deferred geometry'
     34  * will allow the GrPrimitiveProcessor much greater control over how data is transmitted to shaders.
     35  *
     36  * In a deferred geometry world, the GrPrimitiveProcessor can always 'batch'  To do this, each
     37  * primitive type is associated with one GrPrimitiveProcessor, who has complete control of how
     38  * it draws.  Each primitive draw will bundle all required data to perform the draw, and these
     39  * bundles of data will be owned by an instance of the associated GrPrimitiveProcessor.  Bundles
     40  * can be updated alongside the GrBatchTracker struct itself, ultimately allowing the
     41  * GrPrimitiveProcessor complete control of how it gets data into the fragment shader as long as
     42  * it emits the appropriate color, or none at all, as directed.
     43  */
     44 
     45 class GrGLSLCaps;
     46 class GrGLSLPrimitiveProcessor;
     47 
     48 struct GrInitInvariantOutput;
     49 
     50 // Describes the state of pixel local storage with respect to the current draw.
     51 enum GrPixelLocalStorageState {
     52     // The draw is actively updating PLS.
     53     kDraw_GrPixelLocalStorageState,
     54     // The draw is a "finish" operation which is reading from PLS and writing color.
     55     kFinish_GrPixelLocalStorageState,
     56     // The draw does not use PLS.
     57     kDisabled_GrPixelLocalStorageState
     58 };
     59 
     60 /*
     61  * This class allows the GrPipeline to communicate information about the pipeline to a
     62  * GrBatch which should be forwarded to the GrPrimitiveProcessor(s) created by the batch.
     63  * These are not properly part of the pipeline because they assume the specific inputs
     64  * that the batch provided when it created the pipeline. Identical pipelines may be
     65  * created by different batches with different input assumptions and therefore different
     66  * computed optimizations. It is the batch-specific optimizations that allow the pipelines
     67  * to be equal.
     68  */
     69 class GrXPOverridesForBatch {
     70 public:
     71     /** Does the pipeline require the GrPrimitiveProcessor's color? */
     72     bool readsColor() const { return SkToBool(kReadsColor_Flag & fFlags); }
     73 
     74     /** Does the pipeline require the GrPrimitiveProcessor's coverage? */
     75     bool readsCoverage() const { return
     76         SkToBool(kReadsCoverage_Flag & fFlags); }
     77 
     78     /** Does the pipeline require access to (implicit or explicit) local coordinates? */
     79     bool readsLocalCoords() const {
     80         return SkToBool(kReadsLocalCoords_Flag & fFlags);
     81     }
     82 
     83     /** Does the pipeline allow the GrPrimitiveProcessor to combine color and coverage into one
     84         color output ? */
     85     bool canTweakAlphaForCoverage() const {
     86         return SkToBool(kCanTweakAlphaForCoverage_Flag & fFlags);
     87     }
     88 
     89     /** Does the pipeline require the GrPrimitiveProcessor to specify a specific color (and if
     90         so get the color)? */
     91     bool getOverrideColorIfSet(GrColor* overrideColor) const {
     92         if (SkToBool(kUseOverrideColor_Flag & fFlags)) {
     93             SkASSERT(SkToBool(kReadsColor_Flag & fFlags));
     94             if (overrideColor) {
     95                 *overrideColor = fOverrideColor;
     96             }
     97             return true;
     98         }
     99         return false;
    100     }
    101 
    102     /**
    103      * Returns true if the pipeline's color output will be affected by the existing render target
    104      * destination pixel values (meaning we need to be careful with overlapping draws). Note that we
    105      * can conflate coverage and color, so the destination color may still bleed into pixels that
    106      * have partial coverage, even if this function returns false.
    107      *
    108      * The above comment seems incorrect for the use case. This funciton is used to turn two
    109      * overlapping draws into a single draw (really to stencil multiple paths and do a single
    110      * cover). It seems that what really matters is whether the dst is read for color OR for
    111      * coverage.
    112      */
    113     bool willColorBlendWithDst() const { return SkToBool(kWillColorBlendWithDst_Flag & fFlags); }
    114 
    115 private:
    116     enum {
    117         // If this is not set the primitive processor need not produce a color output
    118         kReadsColor_Flag                = 0x1,
    119 
    120         // If this is not set the primitive processor need not produce a coverage output
    121         kReadsCoverage_Flag             = 0x2,
    122 
    123         // If this is not set the primitive processor need not produce local coordinates
    124         kReadsLocalCoords_Flag          = 0x4,
    125 
    126         // If this flag is set then the primitive processor may produce color*coverage as
    127         // its color output (and not output a separate coverage).
    128         kCanTweakAlphaForCoverage_Flag  = 0x8,
    129 
    130         // If this flag is set the GrPrimitiveProcessor must produce fOverrideColor as its
    131         // output color. If not set fOverrideColor is to be ignored.
    132         kUseOverrideColor_Flag          = 0x10,
    133 
    134         kWillColorBlendWithDst_Flag     = 0x20,
    135     };
    136 
    137     uint32_t    fFlags;
    138     GrColor     fOverrideColor;
    139 
    140     friend class GrPipeline; // To initialize this
    141 };
    142 
    143 /*
    144  * GrPrimitiveProcessor defines an interface which all subclasses must implement.  All
    145  * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
    146  * pipelines, and they must provide some notion of equality
    147  */
    148 class GrPrimitiveProcessor : public GrProcessor {
    149 public:
    150     // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
    151     // we put these calls on the base class to prevent having to cast
    152     virtual bool willUseGeoShader() const = 0;
    153 
    154     /*
    155      * This is a safeguard to prevent GrPrimitiveProcessor's from going beyond platform specific
    156      * attribute limits. This number can almost certainly be raised if required.
    157      */
    158     static const int kMaxVertexAttribs = 8;
    159 
    160     struct Attribute {
    161         Attribute()
    162             : fName(nullptr)
    163             , fType(kFloat_GrVertexAttribType)
    164             , fOffset(0) {}
    165         Attribute(const char* name, GrVertexAttribType type,
    166                   GrSLPrecision precision = kDefault_GrSLPrecision)
    167             : fName(name)
    168             , fType(type)
    169             , fOffset(SkAlign4(GrVertexAttribTypeSize(type)))
    170             , fPrecision(precision) {}
    171         const char* fName;
    172         GrVertexAttribType fType;
    173         size_t fOffset;
    174         GrSLPrecision fPrecision;
    175     };
    176 
    177     int numAttribs() const { return fNumAttribs; }
    178     const Attribute& getAttrib(int index) const {
    179         SkASSERT(index < fNumAttribs);
    180         return fAttribs[index];
    181     }
    182 
    183     // Returns the vertex stride of the GP.  A common use case is to request geometry from a
    184     // drawtarget based off of the stride, and to populate this memory using an implicit array of
    185     // structs.  In this case, it is best to assert the vertexstride == sizeof(VertexStruct).
    186     size_t getVertexStride() const { return fVertexStride; }
    187 
    188     /**
    189      * Computes a transformKey from an array of coord transforms. Will only look at the first
    190      * <numCoords> transforms in the array.
    191      *
    192      * TODO: A better name for this function  would be "compute" instead of "get".
    193      */
    194     uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
    195                              int numCoords) const;
    196 
    197     /**
    198      * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
    199      * processor's GL backend implementation.
    200      *
    201      * TODO: A better name for this function  would be "compute" instead of "get".
    202      */
    203     virtual void getGLSLProcessorKey(const GrGLSLCaps& caps,
    204                                      GrProcessorKeyBuilder* b) const = 0;
    205 
    206 
    207     /** Returns a new instance of the appropriate *GL* implementation class
    208         for the given GrProcessor; caller is responsible for deleting
    209         the object. */
    210     virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps& caps) const = 0;
    211 
    212     virtual bool isPathRendering() const { return false; }
    213 
    214     /**
    215      * No Local Coord Transformation is needed in the shader, instead transformed local coords will
    216      * be provided via vertex attribute.
    217      */
    218     virtual bool hasTransformedLocalCoords() const = 0;
    219 
    220     virtual GrPixelLocalStorageState getPixelLocalStorageState() const {
    221         return kDisabled_GrPixelLocalStorageState;
    222     }
    223 
    224     /**
    225      * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
    226      */
    227     virtual const char* getDestColorOverride() const { return nullptr; }
    228 
    229 protected:
    230     GrPrimitiveProcessor()
    231         : fNumAttribs(0)
    232         , fVertexStride(0) {}
    233 
    234     Attribute fAttribs[kMaxVertexAttribs];
    235     int fNumAttribs;
    236     size_t fVertexStride;
    237 
    238 private:
    239     void notifyRefCntIsZero() const final {};
    240     virtual bool hasExplicitLocalCoords() const = 0;
    241 
    242     typedef GrProcessor INHERITED;
    243 };
    244 
    245 #endif
    246