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 /*
     46  * A struct for tracking batching decisions.  While this lives on GrOptState, it is managed
     47  * entirely by the derived classes of the GP.
     48  * // TODO this was an early attempt at handling out of order batching.  It should be
     49  * used carefully as it is being replaced by GrBatch
     50  */
     51 class GrBatchTracker {
     52 public:
     53     template <typename T> const T& cast() const {
     54         SkASSERT(sizeof(T) <= kMaxSize);
     55         return *reinterpret_cast<const T*>(fData.get());
     56     }
     57 
     58     template <typename T> T* cast() {
     59         SkASSERT(sizeof(T) <= kMaxSize);
     60         return reinterpret_cast<T*>(fData.get());
     61     }
     62 
     63     static const size_t kMaxSize = 32;
     64 
     65 private:
     66     SkAlignedSStorage<kMaxSize> fData;
     67 };
     68 
     69 class GrGLSLCaps;
     70 class GrGLPrimitiveProcessor;
     71 
     72 struct GrInitInvariantOutput;
     73 
     74 /*
     75  * This struct allows the GrPipeline to communicate information about the pipeline.  Most of this
     76  * is overrides, but some of it is general information.  Logically it should live in GrPipeline.h,
     77  * but this is problematic due to circular dependencies.
     78  */
     79 struct GrPipelineInfo {
     80     bool fColorIgnored;
     81     bool fCoverageIgnored;
     82     GrColor fOverrideColor;
     83     bool fUsesLocalCoords;
     84     bool fCanTweakAlphaForCoverage;
     85 };
     86 
     87 /*
     88  * This enum is shared by GrPrimitiveProcessors and GrGLPrimitiveProcessors to coordinate shaders
     89  * with vertex attributes / uniforms.
     90  */
     91 enum GrGPInput {
     92     kAllOnes_GrGPInput,
     93     kAttribute_GrGPInput,
     94     kUniform_GrGPInput,
     95     kIgnored_GrGPInput,
     96 };
     97 
     98 /*
     99  * GrPrimitiveProcessor defines an interface which all subclasses must implement.  All
    100  * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
    101  * pipelines, and they must provide some notion of equality
    102  */
    103 class GrPrimitiveProcessor : public GrProcessor {
    104 public:
    105     virtual void initBatchTracker(GrBatchTracker*, const GrPipelineInfo&) const = 0;
    106 
    107     virtual bool canMakeEqual(const GrBatchTracker& mine,
    108                               const GrPrimitiveProcessor& that,
    109                               const GrBatchTracker& theirs) const = 0;
    110 
    111     virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0;
    112     virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0;
    113 
    114     // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
    115     // we put these calls on the base class to prevent having to cast
    116     virtual bool willUseGeoShader() const = 0;
    117 
    118     /*
    119      * This is a safeguard to prevent GrPrimitiveProcessor's from going beyond platform specific
    120      * attribute limits. This number can almost certainly be raised if required.
    121      */
    122     static const int kMaxVertexAttribs = 6;
    123 
    124     struct Attribute {
    125         Attribute()
    126             : fName(NULL)
    127             , fType(kFloat_GrVertexAttribType)
    128             , fOffset(0) {}
    129         Attribute(const char* name, GrVertexAttribType type,
    130                   GrSLPrecision precision = kDefault_GrSLPrecision)
    131             : fName(name)
    132             , fType(type)
    133             , fOffset(SkAlign4(GrVertexAttribTypeSize(type)))
    134             , fPrecision(precision) {}
    135         const char* fName;
    136         GrVertexAttribType fType;
    137         size_t fOffset;
    138         GrSLPrecision fPrecision;
    139     };
    140 
    141     int numAttribs() const { return fNumAttribs; }
    142     const Attribute& getAttrib(int index) const {
    143         SkASSERT(index < fNumAttribs);
    144         return fAttribs[index];
    145     }
    146 
    147     // Returns the vertex stride of the GP.  A common use case is to request geometry from a
    148     // drawtarget based off of the stride, and to populate this memory using an implicit array of
    149     // structs.  In this case, it is best to assert the vertexstride == sizeof(VertexStruct).
    150     size_t getVertexStride() const { return fVertexStride; }
    151 
    152     /**
    153      * Gets a transformKey from an array of coord transforms
    154      */
    155     uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>&) const;
    156 
    157     /**
    158      * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
    159      * processor's GL backend implementation.
    160      */
    161     virtual void getGLProcessorKey(const GrBatchTracker& bt,
    162                                    const GrGLSLCaps& caps,
    163                                    GrProcessorKeyBuilder* b) const = 0;
    164 
    165 
    166     /** Returns a new instance of the appropriate *GL* implementation class
    167         for the given GrProcessor; caller is responsible for deleting
    168         the object. */
    169     virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt,
    170                                                      const GrGLSLCaps& caps) const = 0;
    171 
    172     bool isPathRendering() const { return fIsPathRendering; }
    173 
    174 protected:
    175     GrPrimitiveProcessor(bool isPathRendering)
    176         : fNumAttribs(0)
    177         , fVertexStride(0)
    178         , fIsPathRendering(isPathRendering) {}
    179 
    180     Attribute fAttribs[kMaxVertexAttribs];
    181     int fNumAttribs;
    182     size_t fVertexStride;
    183 
    184 private:
    185     virtual bool hasExplicitLocalCoords() const = 0;
    186 
    187     bool fIsPathRendering;
    188 
    189     typedef GrProcessor INHERITED;
    190 };
    191 
    192 #endif
    193