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.
     22  *
     23  * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
     24  * GrPrimitiveProcessor. These loops run on the CPU and to determine known properties of the final
     25  * color and coverage inputs to the GrXferProcessor in order to perform optimizations that preserve
     26  * correctness. The GrDrawOp seeds these loops with initial color and coverage, in its
     27  * getProcessorAnalysisInputs implementation. These seed values are processed by the
     28  * subsequent
     29  * stages of the rendering pipeline and the output is then fed back into the GrDrawOp in
     30  * the applyPipelineOptimizations call, where the op can use the information to inform decisions
     31  * about GrPrimitiveProcessor creation.
     32  */
     33 
     34 class GrGLSLPrimitiveProcessor;
     35 
     36 /*
     37  * GrPrimitiveProcessor defines an interface which all subclasses must implement.  All
     38  * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
     39  * pipelines, and they must provide some notion of equality
     40  */
     41 class GrPrimitiveProcessor : public GrResourceIOProcessor, public GrProgramElement {
     42 public:
     43     struct Attribute {
     44         enum class InputRate : bool {
     45             kPerVertex,
     46             kPerInstance
     47         };
     48         GrShaderVar asShaderVar() const {
     49             return GrShaderVar(fName, GrVertexAttribTypeToSLType(fType),
     50                                GrShaderVar::kIn_TypeModifier);
     51         }
     52         bool isInitialized() const { return SkToBool(fName); }
     53         Attribute() = default;
     54         Attribute(const char* name, GrVertexAttribType type, int offset, InputRate rate)
     55                 : fName(name), fType(type), fOffsetInRecord(offset), fInputRate(rate) {}
     56         const char*          fName = nullptr;
     57         GrVertexAttribType   fType;
     58         int                  fOffsetInRecord;
     59         InputRate            fInputRate;
     60     };
     61 
     62     GrPrimitiveProcessor(ClassID classID)
     63     : GrResourceIOProcessor(classID) {}
     64 
     65     int numAttribs() const { return fAttribs.count(); }
     66     const Attribute& getAttrib(int index) const { return fAttribs[index]; }
     67 
     68     bool hasVertexAttribs() const { return SkToBool(fVertexStride); }
     69     bool hasInstanceAttribs() const { return SkToBool(fInstanceStride); }
     70 
     71     /**
     72      * These return the strides of the vertex and instance buffers. Attributes are expected to be
     73      * laid out interleaved in their corresponding buffer (vertex or instance). fOffsetInRecord
     74      * indicates an attribute's location in bytes relative to the first attribute. (These are padded
     75      * to the nearest 4 bytes for performance reasons.)
     76      *
     77      * A common practice is to populate the buffer's memory using an implicit array of structs. In
     78      * this case, it is best to assert:
     79      *
     80      *     stride == sizeof(struct) and
     81      *     offsetof(struct, field[i]) == attrib[i].fOffsetInRecord
     82      *
     83      * NOTE: for instanced draws the vertex buffer has a single record that each instance reuses.
     84      */
     85     int getVertexStride() const { return fVertexStride; }
     86     int getInstanceStride() const { return fInstanceStride; }
     87 
     88     // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
     89     // we put these calls on the base class to prevent having to cast
     90     virtual bool willUseGeoShader() const = 0;
     91 
     92     bool willUsePrimitiveRestart() const { return fWillUsePrimitiveRestart; }
     93 
     94     /**
     95      * Computes a transformKey from an array of coord transforms. Will only look at the first
     96      * <numCoords> transforms in the array.
     97      *
     98      * TODO: A better name for this function  would be "compute" instead of "get".
     99      */
    100     uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
    101                              int numCoords) const;
    102 
    103     /**
    104      * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
    105      * processor's GL backend implementation.
    106      *
    107      * TODO: A better name for this function  would be "compute" instead of "get".
    108      */
    109     virtual void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
    110 
    111 
    112     /** Returns a new instance of the appropriate *GL* implementation class
    113         for the given GrProcessor; caller is responsible for deleting
    114         the object. */
    115     virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const = 0;
    116 
    117     virtual bool isPathRendering() const { return false; }
    118 
    119     /**
    120      * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
    121      */
    122     virtual const char* getDestColorOverride() const { return nullptr; }
    123 
    124     virtual float getSampleShading() const {
    125         return 0.0;
    126     }
    127 
    128 protected:
    129     /**
    130      * Subclasses call these from their constructor to register vertex and instance attributes.
    131      */
    132     const Attribute& addVertexAttrib(const char* name, GrVertexAttribType type) {
    133         fAttribs.push_back() = {name, type, fVertexStride, Attribute::InputRate::kPerVertex};
    134         fVertexStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
    135         return fAttribs.back();
    136     }
    137     const Attribute& addInstanceAttrib(const char* name, GrVertexAttribType type) {
    138         fAttribs.push_back() = {name, type, fInstanceStride, Attribute::InputRate::kPerInstance};
    139         fInstanceStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
    140         return fAttribs.back();
    141     }
    142 
    143     void setWillUsePrimitiveRestart() { fWillUsePrimitiveRestart = true; }
    144 
    145 private:
    146     void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); }
    147     void removeRefs() const override { GrResourceIOProcessor::removeRefs(); }
    148     void pendingIOComplete() const override { GrResourceIOProcessor::pendingIOComplete(); }
    149     void notifyRefCntIsZero() const final {}
    150     virtual bool hasExplicitLocalCoords() const = 0;
    151 
    152     SkSTArray<8, Attribute> fAttribs;
    153     int fVertexStride = 0;
    154     int fInstanceStride = 0;
    155     bool fWillUsePrimitiveRestart = false;
    156 
    157     typedef GrProcessor INHERITED;
    158 };
    159 
    160 #endif
    161