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? */ readsColor()72 bool readsColor() const { return SkToBool(kReadsColor_Flag & fFlags); } 73 74 /** Does the pipeline require the GrPrimitiveProcessor's coverage? */ readsCoverage()75 bool readsCoverage() const { return 76 SkToBool(kReadsCoverage_Flag & fFlags); } 77 78 /** Does the pipeline require access to (implicit or explicit) local coordinates? */ readsLocalCoords()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 ? */ canTweakAlphaForCoverage()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)? */ getOverrideColorIfSet(GrColor * overrideColor)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 */ willColorBlendWithDst()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 { AttributeAttribute161 Attribute() 162 : fName(nullptr) 163 , fType(kFloat_GrVertexAttribType) 164 , fOffset(0) {} 165 Attribute(const char* name, GrVertexAttribType type, 166 GrSLPrecision precision = kDefault_GrSLPrecision) fNameAttribute167 : 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 numAttribs()177 int numAttribs() const { return fNumAttribs; } getAttrib(int index)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). getVertexStride()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 isPathRendering()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 getPixelLocalStorageState()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 */ getDestColorOverride()227 virtual const char* getDestColorOverride() const { return nullptr; } 228 229 protected: GrPrimitiveProcessor()230 GrPrimitiveProcessor() 231 : fNumAttribs(0) 232 , fVertexStride(0) {} 233 234 Attribute fAttribs[kMaxVertexAttribs]; 235 int fNumAttribs; 236 size_t fVertexStride; 237 238 private: notifyRefCntIsZero()239 void notifyRefCntIsZero() const final {}; 240 virtual bool hasExplicitLocalCoords() const = 0; 241 242 typedef GrProcessor INHERITED; 243 }; 244 245 #endif 246