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 * getFragmentProcessorAnalysisInputs 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 struct GrInitInvariantOutput; 37 38 /* 39 * This class allows the GrPipeline to communicate information about the pipeline to a GrOp which 40 * inform its decisions for GrPrimitiveProcessor setup. These are not properly part of the pipeline 41 * because they reflect the specific inputs that the op provided to perform the analysis (e.g. that 42 * the GrGeometryProcessor would output an opaque color). 43 * 44 * The pipeline analysis that produced this may have decided to elide some GrProcessors. However, 45 * those elisions may depend upon changing the color output by the GrGeometryProcessor used by the 46 * GrDrawOp. The op must check getOverrideColorIfSet() for this. 47 */ 48 class GrPipelineOptimizations { 49 public: 50 /** Does the pipeline require access to (implicit or explicit) local coordinates? */ readsLocalCoords()51 bool readsLocalCoords() const { 52 return SkToBool(kReadsLocalCoords_Flag & fFlags); 53 } 54 55 /** Does the pipeline allow the GrPrimitiveProcessor to combine color and coverage into one 56 color output ? */ canTweakAlphaForCoverage()57 bool canTweakAlphaForCoverage() const { 58 return SkToBool(kCanTweakAlphaForCoverage_Flag & fFlags); 59 } 60 61 /** Does the pipeline require the GrPrimitiveProcessor to specify a specific color (and if 62 so get the color)? */ getOverrideColorIfSet(GrColor * overrideColor)63 bool getOverrideColorIfSet(GrColor* overrideColor) const { 64 if (SkToBool(kUseOverrideColor_Flag & fFlags)) { 65 if (overrideColor) { 66 *overrideColor = fOverrideColor; 67 } 68 return true; 69 } 70 return false; 71 } 72 73 private: 74 enum { 75 // If this is not set the primitive processor need not produce local coordinates 76 kReadsLocalCoords_Flag = 0x1, 77 78 // If this flag is set then the primitive processor may produce color*coverage as 79 // its color output (and not output a separate coverage). 80 kCanTweakAlphaForCoverage_Flag = 0x2, 81 82 // If this flag is set the GrPrimitiveProcessor must produce fOverrideColor as its 83 // output color. If not set fOverrideColor is to be ignored. 84 kUseOverrideColor_Flag = 0x4, 85 }; 86 87 uint32_t fFlags; 88 GrColor fOverrideColor; 89 90 friend class GrPipeline; // To initialize this 91 }; 92 93 /* 94 * GrPrimitiveProcessor defines an interface which all subclasses must implement. All 95 * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage 96 * pipelines, and they must provide some notion of equality 97 */ 98 class GrPrimitiveProcessor : public GrProcessor { 99 public: 100 // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but 101 // we put these calls on the base class to prevent having to cast 102 virtual bool willUseGeoShader() const = 0; 103 104 struct Attribute { AttributeAttribute105 Attribute() 106 : fName(nullptr) 107 , fType(kFloat_GrVertexAttribType) 108 , fOffset(0) {} AttributeAttribute109 Attribute(const char* name, GrVertexAttribType type, GrSLPrecision precision) 110 : fName(name) 111 , fType(type) 112 , fOffset(SkAlign4(GrVertexAttribTypeSize(type))) 113 , fPrecision(precision) {} 114 const char* fName; 115 GrVertexAttribType fType; 116 size_t fOffset; 117 GrSLPrecision fPrecision; 118 }; 119 numAttribs()120 int numAttribs() const { return fAttribs.count(); } getAttrib(int index)121 const Attribute& getAttrib(int index) const { return fAttribs[index]; } 122 123 // Returns the vertex stride of the GP. A common use case is to request geometry from a 124 // GrOpList based off of the stride, and to populate this memory using an implicit array of 125 // structs. In this case, it is best to assert the vertexstride == sizeof(VertexStruct). getVertexStride()126 size_t getVertexStride() const { return fVertexStride; } 127 128 /** 129 * Computes a transformKey from an array of coord transforms. Will only look at the first 130 * <numCoords> transforms in the array. 131 * 132 * TODO: A better name for this function would be "compute" instead of "get". 133 */ 134 uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords, 135 int numCoords) const; 136 137 /** 138 * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry 139 * processor's GL backend implementation. 140 * 141 * TODO: A better name for this function would be "compute" instead of "get". 142 */ 143 virtual void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0; 144 145 146 /** Returns a new instance of the appropriate *GL* implementation class 147 for the given GrProcessor; caller is responsible for deleting 148 the object. */ 149 virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const = 0; 150 isPathRendering()151 virtual bool isPathRendering() const { return false; } 152 153 /** 154 * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor(). 155 */ getDestColorOverride()156 virtual const char* getDestColorOverride() const { return nullptr; } 157 getSampleShading()158 virtual float getSampleShading() const { 159 return 0.0; 160 } 161 162 /* Sub-class should override and return true if this primitive processor implements the distance 163 * vector field, a field of vectors to the nearest point in the edge of the shape. */ implementsDistanceVector()164 virtual bool implementsDistanceVector() const { return false; } 165 166 protected: GrPrimitiveProcessor()167 GrPrimitiveProcessor() : fVertexStride(0) {} 168 169 enum { kPreallocAttribCnt = 8 }; 170 SkSTArray<kPreallocAttribCnt, Attribute> fAttribs; 171 size_t fVertexStride; 172 173 private: notifyRefCntIsZero()174 void notifyRefCntIsZero() const final {} 175 virtual bool hasExplicitLocalCoords() const = 0; 176 177 typedef GrProcessor INHERITED; 178 }; 179 180 #endif 181