| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #ifndef GrGeometryProcessor_DEFINED | 8 #ifndef GrGeometryProcessor_DEFINED |
| 9 #define GrGeometryProcessor_DEFINED | 9 #define GrGeometryProcessor_DEFINED |
| 10 | 10 |
| 11 #include "GrColor.h" | 11 #include "GrPrimitiveProcessor.h" |
| 12 #include "GrProcessor.h" | |
| 13 #include "GrShaderVar.h" | |
| 14 | |
| 15 /* | |
| 16 * The GrPrimitiveProcessor represents some kind of geometric primitive. This i
ncludes the shape | |
| 17 * of the primitive and the inherent color of the primitive. The GrPrimitivePro
cessor is | |
| 18 * responsible for providing a color and coverage input into the Ganesh renderin
g pipeline. Through | |
| 19 * optimization, Ganesh may decide a different color, no color, and / or no cove
rage are required | |
| 20 * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to su
pport this | |
| 21 * functionality. We also use the GrPrimitiveProcessor to make batching decisio
ns. | |
| 22 * | |
| 23 * There are two feedback loops between the GrFragmentProcessors, the GrXferProc
essor, and the | |
| 24 * GrPrimitiveProcessor. These loops run on the CPU and compute any invariant c
omponents which | |
| 25 * might be useful for correctness / optimization decisions. The GrPrimitivePro
cessor 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 GrP
rimitiveProcessor 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 t
heir 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 tra
nsmitted 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 d
raw, and these | |
| 39 * bundles of data will be owned by an instance of the associated GrPrimitivePro
cessor. Bundles | |
| 40 * can be updated alongside the GrBatchTracker struct itself, ultimately allowin
g the | |
| 41 * GrPrimitiveProcessor complete control of how it gets data into the fragment s
hader 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 shou
ld be | |
| 49 * used carefully as it is being replaced by GrBatch | |
| 50 */ | |
| 51 class GrBatchTracker { | |
| 52 public: | |
| 53 template <typename T> const T& cast() const { | |
| 54 SkASSERT(sizeof(T) <= kMaxSize); | |
| 55 return *reinterpret_cast<const T*>(fData.get()); | |
| 56 } | |
| 57 | |
| 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 GrIndexBufferAllocPool; | |
| 70 class GrGLCaps; | |
| 71 class GrGLPrimitiveProcessor; | |
| 72 class GrVertexBufferAllocPool; | |
| 73 | |
| 74 struct GrInitInvariantOutput; | |
| 75 | |
| 76 /* | |
| 77 * This struct allows the GrPipeline to communicate information about the pipeli
ne. Most of this | |
| 78 * is overrides, but some of it is general information. Logically it should liv
e in GrPipeline.h, | |
| 79 * but this is problematic due to circular dependencies. | |
| 80 */ | |
| 81 struct GrPipelineInfo { | |
| 82 bool fColorIgnored; | |
| 83 bool fCoverageIgnored; | |
| 84 GrColor fOverrideColor; | |
| 85 bool fUsesLocalCoords; | |
| 86 }; | |
| 87 | |
| 88 /* | |
| 89 * This enum is shared by GrPrimitiveProcessors and GrGLPrimitiveProcessors to c
oordinate shaders | |
| 90 * with vertex attributes / uniforms. | |
| 91 */ | |
| 92 enum GrGPInput { | |
| 93 kAllOnes_GrGPInput, | |
| 94 kAttribute_GrGPInput, | |
| 95 kUniform_GrGPInput, | |
| 96 kIgnored_GrGPInput, | |
| 97 }; | |
| 98 | |
| 99 /* | |
| 100 * GrPrimitiveProcessor defines an interface which all subclasses must implement
. All | |
| 101 * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh co
lor / coverage | |
| 102 * pipelines, and they must provide some notion of equality | |
| 103 */ | |
| 104 class GrPrimitiveProcessor : public GrProcessor { | |
| 105 public: | |
| 106 // TODO let the PrimProc itself set this in its setData call, this should re
ally live on the | |
| 107 // bundle of primitive data | |
| 108 const SkMatrix& viewMatrix() const { return fViewMatrix; } | |
| 109 const SkMatrix& localMatrix() const { return fLocalMatrix; } | |
| 110 | |
| 111 virtual void initBatchTracker(GrBatchTracker*, const GrPipelineInfo&) const
= 0; | |
| 112 | |
| 113 virtual bool canMakeEqual(const GrBatchTracker& mine, | |
| 114 const GrPrimitiveProcessor& that, | |
| 115 const GrBatchTracker& theirs) const = 0; | |
| 116 | |
| 117 virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0; | |
| 118 virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const =
0; | |
| 119 | |
| 120 // Only the GrGeometryProcessor subclass actually has a geo shader or vertex
attributes, but | |
| 121 // we put these calls on the base class to prevent having to cast | |
| 122 virtual bool willUseGeoShader() const = 0; | |
| 123 | |
| 124 /* | |
| 125 * This is a safeguard to prevent GrPrimitiveProcessor's from going beyond p
latform specific | |
| 126 * attribute limits. This number can almost certainly be raised if required. | |
| 127 */ | |
| 128 static const int kMaxVertexAttribs = 6; | |
| 129 | |
| 130 struct Attribute { | |
| 131 Attribute() | |
| 132 : fName(NULL) | |
| 133 , fType(kFloat_GrVertexAttribType) | |
| 134 , fOffset(0) {} | |
| 135 Attribute(const char* name, GrVertexAttribType type) | |
| 136 : fName(name) | |
| 137 , fType(type) | |
| 138 , fOffset(SkAlign4(GrVertexAttribTypeSize(type))) {} | |
| 139 const char* fName; | |
| 140 GrVertexAttribType fType; | |
| 141 size_t fOffset; | |
| 142 }; | |
| 143 | |
| 144 int numAttribs() const { return fNumAttribs; } | |
| 145 const Attribute& getAttrib(int index) const { | |
| 146 SkASSERT(index < fNumAttribs); | |
| 147 return fAttribs[index]; | |
| 148 } | |
| 149 | |
| 150 // Returns the vertex stride of the GP. A common use case is to request geo
metry from a | |
| 151 // drawtarget based off of the stride, and to populate this memory using an
implicit array of | |
| 152 // structs. In this case, it is best to assert the vertexstride == sizeof(V
ertexStruct). | |
| 153 size_t getVertexStride() const { return fVertexStride; } | |
| 154 | |
| 155 /** | |
| 156 * Gets a transformKey from an array of coord transforms | |
| 157 */ | |
| 158 uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>&) con
st; | |
| 159 | |
| 160 /** | |
| 161 * Sets a unique key on the GrProcessorKeyBuilder that is directly associate
d with this geometry | |
| 162 * processor's GL backend implementation. | |
| 163 */ | |
| 164 virtual void getGLProcessorKey(const GrBatchTracker& bt, | |
| 165 const GrGLCaps& caps, | |
| 166 GrProcessorKeyBuilder* b) const = 0; | |
| 167 | |
| 168 | |
| 169 /** Returns a new instance of the appropriate *GL* implementation class | |
| 170 for the given GrProcessor; caller is responsible for deleting | |
| 171 the object. */ | |
| 172 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, | |
| 173 const GrGLCaps& caps) const
= 0; | |
| 174 | |
| 175 bool isPathRendering() const { return fIsPathRendering; } | |
| 176 | |
| 177 protected: | |
| 178 GrPrimitiveProcessor(const SkMatrix& viewMatrix, const SkMatrix& localMatrix
, | |
| 179 bool isPathRendering) | |
| 180 : fNumAttribs(0) | |
| 181 , fVertexStride(0) | |
| 182 , fViewMatrix(viewMatrix) | |
| 183 , fLocalMatrix(localMatrix) | |
| 184 , fIsPathRendering(isPathRendering) {} | |
| 185 | |
| 186 /* | |
| 187 * CanCombineOutput will return true if two draws are 'batchable' from a col
or perspective. | |
| 188 * TODO remove this when GPs can upgrade to attribute color | |
| 189 */ | |
| 190 static bool CanCombineOutput(GrGPInput left, GrColor lColor, GrGPInput right
, GrColor rColor) { | |
| 191 if (left != right) { | |
| 192 return false; | |
| 193 } | |
| 194 | |
| 195 if (kUniform_GrGPInput == left && lColor != rColor) { | |
| 196 return false; | |
| 197 } | |
| 198 | |
| 199 return true; | |
| 200 } | |
| 201 | |
| 202 static bool CanCombineLocalMatrices(const GrPrimitiveProcessor& left, | |
| 203 bool leftUsesLocalCoords, | |
| 204 const GrPrimitiveProcessor& right, | |
| 205 bool rightUsesLocalCoords) { | |
| 206 if (leftUsesLocalCoords != rightUsesLocalCoords) { | |
| 207 return false; | |
| 208 } | |
| 209 | |
| 210 if (leftUsesLocalCoords && !left.localMatrix().cheapEqualTo(right.localM
atrix())) { | |
| 211 return false; | |
| 212 } | |
| 213 return true; | |
| 214 } | |
| 215 | |
| 216 Attribute fAttribs[kMaxVertexAttribs]; | |
| 217 int fNumAttribs; | |
| 218 size_t fVertexStride; | |
| 219 | |
| 220 private: | |
| 221 virtual bool hasExplicitLocalCoords() const = 0; | |
| 222 | |
| 223 const SkMatrix fViewMatrix; | |
| 224 SkMatrix fLocalMatrix; | |
| 225 bool fIsPathRendering; | |
| 226 | |
| 227 typedef GrProcessor INHERITED; | |
| 228 }; | |
| 229 | 12 |
| 230 /** | 13 /** |
| 231 * A GrGeometryProcessor is a flexible method for rendering a primitive. The Gr
GeometryProcessor | 14 * A GrGeometryProcessor is a flexible method for rendering a primitive. The Gr
GeometryProcessor |
| 232 * has complete control over vertex attributes and uniforms(aside from the rende
r target) but it | 15 * has complete control over vertex attributes and uniforms(aside from the rende
r target) but it |
| 233 * must obey the same contract as any GrPrimitiveProcessor, specifically it must
emit a color and | 16 * must obey the same contract as any GrPrimitiveProcessor, specifically it must
emit a color and |
| 234 * coverage into the fragment shader. Where this color and coverage come from i
s completely the | 17 * coverage into the fragment shader. Where this color and coverage come from i
s completely the |
| 235 * responsibility of the GrGeometryProcessor. | 18 * responsibility of the GrGeometryProcessor. |
| 236 */ | 19 */ |
| 237 class GrGeometryProcessor : public GrPrimitiveProcessor { | 20 class GrGeometryProcessor : public GrPrimitiveProcessor { |
| 238 public: | 21 public: |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 | 146 |
| 364 GrColor fColor; | 147 GrColor fColor; |
| 365 bool fOpaqueVertexColors; | 148 bool fOpaqueVertexColors; |
| 366 bool fWillUseGeoShader; | 149 bool fWillUseGeoShader; |
| 367 bool fHasVertexColor; | 150 bool fHasVertexColor; |
| 368 bool fHasLocalCoords; | 151 bool fHasLocalCoords; |
| 369 | 152 |
| 370 typedef GrPrimitiveProcessor INHERITED; | 153 typedef GrPrimitiveProcessor INHERITED; |
| 371 }; | 154 }; |
| 372 | 155 |
| 373 /* | |
| 374 * The path equivalent of the GP. For now this just manages color. In the long
term we plan on | |
| 375 * extending this class to handle all nvpr uniform / varying / program work. | |
| 376 */ | |
| 377 class GrPathProcessor : public GrPrimitiveProcessor { | |
| 378 public: | |
| 379 static GrPathProcessor* Create(GrColor color, | |
| 380 const SkMatrix& viewMatrix = SkMatrix::I(), | |
| 381 const SkMatrix& localMatrix = SkMatrix::I())
{ | |
| 382 return SkNEW_ARGS(GrPathProcessor, (color, viewMatrix, localMatrix)); | |
| 383 } | |
| 384 | |
| 385 void initBatchTracker(GrBatchTracker*, const GrPipelineInfo&) const SK_OVERR
IDE; | |
| 386 | |
| 387 bool canMakeEqual(const GrBatchTracker& mine, | |
| 388 const GrPrimitiveProcessor& that, | |
| 389 const GrBatchTracker& theirs) const SK_OVERRIDE; | |
| 390 | |
| 391 const char* name() const SK_OVERRIDE { return "PathProcessor"; } | |
| 392 | |
| 393 GrColor color() const { return fColor; } | |
| 394 | |
| 395 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE; | |
| 396 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID
E; | |
| 397 | |
| 398 bool willUseGeoShader() const SK_OVERRIDE { return false; } | |
| 399 | |
| 400 virtual void getGLProcessorKey(const GrBatchTracker& bt, | |
| 401 const GrGLCaps& caps, | |
| 402 GrProcessorKeyBuilder* b) const SK_OVERRIDE; | |
| 403 | |
| 404 virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, | |
| 405 const GrGLCaps& caps) const
SK_OVERRIDE; | |
| 406 | |
| 407 protected: | |
| 408 GrPathProcessor(GrColor color, const SkMatrix& viewMatrix, const SkMatrix& l
ocalMatrix); | |
| 409 | |
| 410 private: | |
| 411 bool hasExplicitLocalCoords() const SK_OVERRIDE { return false; } | |
| 412 | |
| 413 GrColor fColor; | |
| 414 | |
| 415 typedef GrPrimitiveProcessor INHERITED; | |
| 416 }; | |
| 417 | |
| 418 #endif | 156 #endif |
| OLD | NEW |