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 49 const char* fName; 50 GrVertexAttribType fType; 51 int fOffsetInRecord; 52 GrSLPrecision fPrecision; 53 InputRate fInputRate; 54 }; 55 numAttribs()56 int numAttribs() const { return fAttribs.count(); } getAttrib(int index)57 const Attribute& getAttrib(int index) const { return fAttribs[index]; } 58 hasVertexAttribs()59 bool hasVertexAttribs() const { return SkToBool(fVertexStride); } hasInstanceAttribs()60 bool hasInstanceAttribs() const { return SkToBool(fInstanceStride); } 61 62 /** 63 * These return the strides of the vertex and instance buffers. Attributes are expected to be 64 * laid out interleaved in their corresponding buffer (vertex or instance). fOffsetInRecord 65 * indicates an attribute's location in bytes relative to the first attribute. (These are padded 66 * to the nearest 4 bytes for performance reasons.) 67 * 68 * A common practice is to populate the buffer's memory using an implicit array of structs. In 69 * this case, it is best to assert: 70 * 71 * stride == sizeof(struct) and 72 * offsetof(struct, field[i]) == attrib[i].fOffsetInRecord 73 * 74 * NOTE: for instanced draws the vertex buffer has a single record that each instance reuses. 75 */ getVertexStride()76 int getVertexStride() const { return fVertexStride; } getInstanceStride()77 int getInstanceStride() const { return fInstanceStride; } 78 79 // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but 80 // we put these calls on the base class to prevent having to cast 81 virtual bool willUseGeoShader() const = 0; 82 83 /** 84 * Computes a transformKey from an array of coord transforms. Will only look at the first 85 * <numCoords> transforms in the array. 86 * 87 * TODO: A better name for this function would be "compute" instead of "get". 88 */ 89 uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords, 90 int numCoords) const; 91 92 /** 93 * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry 94 * processor's GL backend implementation. 95 * 96 * TODO: A better name for this function would be "compute" instead of "get". 97 */ 98 virtual void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0; 99 100 101 /** Returns a new instance of the appropriate *GL* implementation class 102 for the given GrProcessor; caller is responsible for deleting 103 the object. */ 104 virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const = 0; 105 isPathRendering()106 virtual bool isPathRendering() const { return false; } 107 108 /** 109 * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor(). 110 */ getDestColorOverride()111 virtual const char* getDestColorOverride() const { return nullptr; } 112 getSampleShading()113 virtual float getSampleShading() const { 114 return 0.0; 115 } 116 117 protected: 118 /** 119 * Subclasses call these from their constructor to register vertex and instance attributes. 120 */ 121 const Attribute& addVertexAttrib(const char* name, GrVertexAttribType type, 122 GrSLPrecision precision = kDefault_GrSLPrecision) { 123 precision = (kDefault_GrSLPrecision == precision) ? kMedium_GrSLPrecision : precision; 124 fAttribs.push_back() = {name, type, fVertexStride, precision, 125 Attribute::InputRate::kPerVertex}; 126 fVertexStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type))); 127 return fAttribs.back(); 128 } 129 const Attribute& addInstanceAttrib(const char* name, GrVertexAttribType type, 130 GrSLPrecision precision = kDefault_GrSLPrecision) { 131 precision = (kDefault_GrSLPrecision == precision) ? kMedium_GrSLPrecision : precision; 132 fAttribs.push_back() = {name, type, fInstanceStride, precision, 133 Attribute::InputRate::kPerInstance}; 134 fInstanceStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type))); 135 return fAttribs.back(); 136 } 137 138 private: addPendingIOs()139 void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); } removeRefs()140 void removeRefs() const override { GrResourceIOProcessor::removeRefs(); } pendingIOComplete()141 void pendingIOComplete() const override { GrResourceIOProcessor::pendingIOComplete(); } notifyRefCntIsZero()142 void notifyRefCntIsZero() const final {} 143 virtual bool hasExplicitLocalCoords() const = 0; 144 145 SkSTArray<8, Attribute> fAttribs; 146 int fVertexStride = 0; 147 int fInstanceStride = 0; 148 149 typedef GrProcessor INHERITED; 150 }; 151 152 #endif 153