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 |