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: cast()53 template <typename T> const T& cast() const { 54 SkASSERT(sizeof(T) <= kMaxSize); 55 return *reinterpret_cast<const T*>(fData.get()); 56 } 57 cast()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 { AttributeAttribute125 Attribute() 126 : fName(NULL) 127 , fType(kFloat_GrVertexAttribType) 128 , fOffset(0) {} 129 Attribute(const char* name, GrVertexAttribType type, 130 GrSLPrecision precision = kDefault_GrSLPrecision) fNameAttribute131 : 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 numAttribs()141 int numAttribs() const { return fNumAttribs; } getAttrib(int index)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). getVertexStride()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 isPathRendering()172 bool isPathRendering() const { return fIsPathRendering; } 173 174 protected: GrPrimitiveProcessor(bool isPathRendering)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