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 struct Attribute { AttributeAttribute155 Attribute() 156 : fName(nullptr) 157 , fType(kFloat_GrVertexAttribType) 158 , fOffset(0) {} AttributeAttribute159 Attribute(const char* name, GrVertexAttribType type, GrSLPrecision precision) 160 : fName(name) 161 , fType(type) 162 , fOffset(SkAlign4(GrVertexAttribTypeSize(type))) 163 , fPrecision(precision) {} 164 const char* fName; 165 GrVertexAttribType fType; 166 size_t fOffset; 167 GrSLPrecision fPrecision; 168 }; 169 numAttribs()170 int numAttribs() const { return fAttribs.count(); } getAttrib(int index)171 const Attribute& getAttrib(int index) const { return fAttribs[index]; } 172 173 // Returns the vertex stride of the GP. A common use case is to request geometry from a 174 // drawtarget based off of the stride, and to populate this memory using an implicit array of 175 // structs. In this case, it is best to assert the vertexstride == sizeof(VertexStruct). getVertexStride()176 size_t getVertexStride() const { return fVertexStride; } 177 178 /** 179 * Computes a transformKey from an array of coord transforms. Will only look at the first 180 * <numCoords> transforms in the array. 181 * 182 * TODO: A better name for this function would be "compute" instead of "get". 183 */ 184 uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords, 185 int numCoords) const; 186 187 /** 188 * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry 189 * processor's GL backend implementation. 190 * 191 * TODO: A better name for this function would be "compute" instead of "get". 192 */ 193 virtual void getGLSLProcessorKey(const GrGLSLCaps& caps, 194 GrProcessorKeyBuilder* b) const = 0; 195 196 197 /** Returns a new instance of the appropriate *GL* implementation class 198 for the given GrProcessor; caller is responsible for deleting 199 the object. */ 200 virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps& caps) const = 0; 201 isPathRendering()202 virtual bool isPathRendering() const { return false; } 203 getPixelLocalStorageState()204 virtual GrPixelLocalStorageState getPixelLocalStorageState() const { 205 return kDisabled_GrPixelLocalStorageState; 206 } 207 208 /** 209 * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor(). 210 */ getDestColorOverride()211 virtual const char* getDestColorOverride() const { return nullptr; } 212 getSampleShading()213 virtual float getSampleShading() const { 214 return 0.0; 215 } 216 217 /* Sub-class should override and return true if this primitive processor implements the distance 218 * vector field, a field of vectors to the nearest point in the edge of the shape. */ implementsDistanceVector()219 virtual bool implementsDistanceVector() const { return false; } 220 221 protected: GrPrimitiveProcessor()222 GrPrimitiveProcessor() : fVertexStride(0) {} 223 224 enum { kPreallocAttribCnt = 8 }; 225 SkSTArray<kPreallocAttribCnt, Attribute> fAttribs; 226 size_t fVertexStride; 227 228 private: notifyRefCntIsZero()229 void notifyRefCntIsZero() const final {} 230 virtual bool hasExplicitLocalCoords() const = 0; 231 232 typedef GrProcessor INHERITED; 233 }; 234 235 #endif 236