Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: src/gpu/GrGeometryProcessor.h

Issue 746423007: Draft change to start pulling uniform color into GP (Closed) Base URL: https://skia.googlesource.com/skia.git@no_factories
Patch Set: rebase Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrDefaultGeoProcFactory.cpp ('k') | src/gpu/GrGeometryProcessor.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "GrColor.h"
12 #include "GrGeometryData.h" 12 #include "GrGeometryData.h"
13 #include "GrProcessor.h" 13 #include "GrProcessor.h"
14 #include "GrShaderVar.h" 14 #include "GrShaderVar.h"
15 15
16 /* 16 /*
17 * The GrPrimitiveProcessor represents some kind of geometric primitive. This i ncludes the shape
18 * of the primitive and the inherent color of the primitive. The GrPrimitivePro cessor is
19 * responsible for providing a color and coverage input into the Ganesh renderin g pipeline. Through
20 * optimization, Ganesh may decide a different color, no color, and / or no cove rage are required
21 * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to su pport this
22 * functionality. We also use the GrPrimitiveProcessor to make batching decisio ns.
23 *
24 * There are two feedback loops between the GrFragmentProcessors, the GrXferProc essor, and the
25 * GrPrimitiveProcessor. These loops run on the CPU and compute any invariant c omponents which
26 * might be useful for correctness / optimization decisions. The GrPrimitivePro cessor seeds these
27 * loops, one with initial color and one with initial coverage, in its
28 * onComputeInvariantColor / Coverage calls. These seed values are processed by the subsequent
29 * stages of the rendering pipeline and the output is then fed back into the GrP rimitiveProcessor in
30 * the initBatchTracker call, where the GrPrimitiveProcessor can then initialize the GrBatchTracker
31 * struct with the appropriate values.
32 *
33 * We are evolving this system to move towards generating geometric meshes and t heir associated
34 * vertex data after we have batched and reordered draws. This system, known as 'deferred geometry'
35 * will allow the GrPrimitiveProcessor much greater control over how data is tra nsmitted to shaders.
36 *
37 * In a deferred geometry world, the GrPrimitiveProcessor can always 'batch' To do this, each
38 * primitive type is associated with one GrPrimitiveProcessor, who has complete control of how
39 * it draws. Each primitive draw will bundle all required data to perform the d raw, and these
40 * bundles of data will be owned by an instance of the associated GrPrimitivePro cessor. Bundles
41 * can be updated alongside the GrBatchTracker struct itself, ultimately allowin g the
42 * GrPrimitiveProcessor complete control of how it gets data into the fragment s hader as long as
43 * it emits the appropriate color, or none at all, as directed.
44 */
45
46 /*
17 * A struct for tracking batching decisions. While this lives on GrOptState, it is managed 47 * A struct for tracking batching decisions. While this lives on GrOptState, it is managed
18 * entirely by the derived classes of the GP. 48 * entirely by the derived classes of the GP.
19 */ 49 */
20 class GrBatchTracker { 50 class GrBatchTracker {
21 public: 51 public:
22 template <typename T> const T& cast() const { 52 template <typename T> const T& cast() const {
23 SkASSERT(sizeof(T) <= kMaxSize); 53 SkASSERT(sizeof(T) <= kMaxSize);
24 return *reinterpret_cast<const T*>(fData); 54 return *reinterpret_cast<const T*>(fData.get());
25 } 55 }
26 56
27 template <typename T> T* cast() { 57 template <typename T> T* cast() {
28 SkASSERT(sizeof(T) <= kMaxSize); 58 SkASSERT(sizeof(T) <= kMaxSize);
29 return reinterpret_cast<T*>(fData); 59 return reinterpret_cast<T*>(fData.get());
30 } 60 }
31 61
32 static const size_t kMaxSize = 32; 62 static const size_t kMaxSize = 32;
33 63
34 private: 64 private:
35 uint8_t fData[kMaxSize]; 65 SkAlignedSStorage<kMaxSize> fData;
36 }; 66 };
37 67
38 class GrGLCaps; 68 class GrGLCaps;
39 class GrGLGeometryProcessor; 69 class GrGLGeometryProcessor;
40 class GrOptDrawState; 70 class GrOptDrawState;
41 71
42 struct GrInitInvariantOutput; 72 struct GrInitInvariantOutput;
43 73
74
44 /* 75 /*
45 * GrGeometryProcessors and GrPathProcessors may effect invariantColor 76 * This enum is shared by GrPrimitiveProcessors and GrGLPrimitiveProcessors to c oordinate shaders
77 * with vertex attributes / uniforms.
78 */
79 enum GrGPInput {
80 kAllOnes_GrGPInput,
81 kAttribute_GrGPInput,
82 kUniform_GrGPInput,
83 kIgnored_GrGPInput,
84 };
85
86 /*
87 * GrPrimitiveProcessor defines an interface which all subclasses must implement . All
88 * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh co lor / coverage
89 * pipelines, and they must provide some notion of equality
46 */ 90 */
47 class GrPrimitiveProcessor : public GrProcessor { 91 class GrPrimitiveProcessor : public GrProcessor {
48 public: 92 public:
49 // TODO GPs and PPs have to provide an initial coverage because the coverage invariant code is 93 /*
50 // broken right now 94 * This struct allows the optstate to communicate requirements to the GrPrim itiveProcessor.
51 virtual uint8_t coverage() const = 0; 95 */
96 struct InitBT {
97 bool fColorIgnored;
98 bool fCoverageIgnored;
99 GrColor fOverrideColor;
100 };
101
102 virtual void initBatchTracker(GrBatchTracker*, const InitBT&) const = 0;
103
104 virtual bool canMakeEqual(const GrBatchTracker& mine,
105 const GrPrimitiveProcessor& that,
106 const GrBatchTracker& theirs) const = 0;
107
108 /*
109 * We always call canMakeEqual before makeEqual so there is no need to do an y kind of equality
110 * testing here
111 * TODO make this pure virtual when primProcs can actually use it
112 */
113 virtual void makeEqual(GrBatchTracker*, const GrBatchTracker&) const {}
114
52 virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0; 115 virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0;
53 virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0; 116 virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0;
54 117
55 private:
56 typedef GrProcessor INHERITED;
57 };
58
59 /**
60 * A GrGeometryProcessor is used to perform computation in the vertex shader and
61 * add support for custom vertex attributes. A GrGemeotryProcessor is typically
62 * tied to the code that does a specific type of high-level primitive rendering
63 * (e.g. anti-aliased circle rendering). The GrGeometryProcessor used for a draw is
64 * specified using GrDrawState. There can only be one geometry processor active for
65 * a draw. The custom vertex attributes required by the geometry processor must be
66 * added to the vertex attribute array specified on the GrDrawState.
67 * GrGeometryProcessor subclasses should be immutable after construction.
68 */
69 class GrGeometryProcessor : public GrPrimitiveProcessor {
70 public:
71 // TODO the Hint can be handled in a much more clean way when we have deferr ed geometry or
72 // atleast bundles
73 GrGeometryProcessor(GrColor color, bool opaqueVertexColors = false, uint8_t coverage = 0xff)
74 : fVertexStride(0)
75 , fColor(color)
76 , fCoverage(coverage)
77 , fOpaqueVertexColors(opaqueVertexColors)
78 , fWillUseGeoShader(false)
79 , fHasVertexColor(false)
80 , fHasVertexCoverage(false)
81 , fHasLocalCoords(false) {}
82
83 /** 118 /**
84 * Sets a unique key on the GrProcessorKeyBuilder that is directly associate d with this geometry 119 * Sets a unique key on the GrProcessorKeyBuilder that is directly associate d with this geometry
85 * processor's GL backend implementation. 120 * processor's GL backend implementation.
86 */ 121 */
87 virtual void getGLProcessorKey(const GrBatchTracker& bt, 122 virtual void getGLProcessorKey(const GrBatchTracker& bt,
88 const GrGLCaps& caps, 123 const GrGLCaps& caps,
89 GrProcessorKeyBuilder* b) const = 0; 124 GrProcessorKeyBuilder* b) const = 0;
90 125
91 126
92 /** Returns a new instance of the appropriate *GL* implementation class 127 /** Returns a new instance of the appropriate *GL* implementation class
93 for the given GrProcessor; caller is responsible for deleting 128 for the given GrProcessor; caller is responsible for deleting
94 the object. */ 129 the object. */
95 virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) co nst = 0; 130 virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) co nst = 0;
96 131
132 protected:
133 /*
134 * CanCombineOutput will return true if two draws are 'batchable' from a col or perspective.
135 * TODO remove this when GPs can upgrade to attribute color
136 */
137 static bool CanCombineOutput(GrGPInput left, GrColor lColor, GrGPInput right , GrColor rColor) {
138 if (left != right) {
139 return false;
140 }
141
142 if (kUniform_GrGPInput == left && lColor != rColor) {
143 return false;
144 }
145
146 return true;
147 }
148
149 private:
150 typedef GrProcessor INHERITED;
151 };
152
153 /**
154 * A GrGeometryProcessor is a flexible method for rendering a primitive. The Gr GeometryProcessor
155 * has complete control over vertex attributes and uniforms(aside from the rende r target) but it
156 * must obey the same contract as any GrPrimitiveProcessor, specifically it must emit a color and
157 * coverage into the fragment shader. Where this color and coverage come from i s completely the
158 * responsibility of the GrGeometryProcessor.
159 */
160 class GrGeometryProcessor : public GrPrimitiveProcessor {
161 public:
162 // TODO the Hint can be handled in a much more clean way when we have deferr ed geometry or
163 // atleast bundles
164 GrGeometryProcessor(GrColor color, bool opaqueVertexColors = false)
165 : fVertexStride(0)
166 , fColor(color)
167 , fOpaqueVertexColors(opaqueVertexColors)
168 , fWillUseGeoShader(false)
169 , fHasVertexColor(false)
170 , fHasLocalCoords(false) {}
171
172 virtual const char* name() const = 0;
173
97 /* 174 /*
98 * This is a safeguard to prevent GPs from going beyond platform specific at tribute limits. 175 * This is a safeguard to prevent GPs from going beyond platform specific at tribute limits.
99 * This number can almost certainly be raised if required. 176 * This number can almost certainly be raised if required.
100 */ 177 */
101 static const int kMaxVertexAttribs = 6; 178 static const int kMaxVertexAttribs = 6;
102 179
103 struct GrAttribute { 180 struct GrAttribute {
104 GrAttribute(const char* name, GrVertexAttribType type) 181 GrAttribute(const char* name, GrVertexAttribType type)
105 : fName(name) 182 : fName(name)
106 , fType(type) 183 , fType(type)
107 , fOffset(SkAlign4(GrVertexAttribTypeSize(type))) {} 184 , fOffset(SkAlign4(GrVertexAttribTypeSize(type))) {}
108 const char* fName; 185 const char* fName;
109 GrVertexAttribType fType; 186 GrVertexAttribType fType;
110 size_t fOffset; 187 size_t fOffset;
111 }; 188 };
112 189
113 typedef SkTArray<GrAttribute, true> VertexAttribArray; 190 typedef SkTArray<GrAttribute, true> VertexAttribArray;
114 191
115 const VertexAttribArray& getAttribs() const { return fAttribs; } 192 const VertexAttribArray& getAttribs() const { return fAttribs; }
116 193
117 // Returns the vertex stride of the GP. A common use case is to request geo metry from a 194 // Returns the vertex stride of the GP. A common use case is to request geo metry from a
118 // drawtarget based off of the stride, and to populate this memory using an implicit array of 195 // drawtarget based off of the stride, and to populate this memory using an implicit array of
119 // structs. In this case, it is best to assert the vertexstride == sizeof(V ertexStruct). 196 // structs. In this case, it is best to assert the vertexstride == sizeof(V ertexStruct).
120 size_t getVertexStride() const { return fVertexStride; } 197 size_t getVertexStride() const { return fVertexStride; }
121 198
122 bool willUseGeoShader() const { return fWillUseGeoShader; } 199 bool willUseGeoShader() const { return fWillUseGeoShader; }
123 200
124 /** Returns true if this and other processor conservatively draw identically . It can only return 201 /*
125 true when the two prcoessors are of the same subclass (i.e. they return the same object from 202 * In an ideal world, two GrGeometryProcessors with the same class id and te xture accesses
126 from getFactory()). 203 * would ALWAYS be able to batch together. If two GrGeometryProcesosrs are the same then we
127 A return value of true from isEqual() should not be used to test whether the processors 204 * will only keep one of them. The remaining GrGeometryProcessor then updat es its
128 would generate the same shader code. To test for identical code generati on use the 205 * GrBatchTracker to incorporate the draw information from the GrGeometryPro cessor we discard.
129 processors' keys computed by the GrBackendEffectFactory. */ 206 * Any bundles associated with the discarded GrGeometryProcessor will be att ached to the
130 bool isEqual(const GrGeometryProcessor& that) const { 207 * remaining GrGeometryProcessor.
208 */
209 bool canMakeEqual(const GrBatchTracker& mine,
210 const GrPrimitiveProcessor& that,
211 const GrBatchTracker& theirs) const SK_OVERRIDE {
131 if (this->classID() != that.classID() || !this->hasSameTextureAccesses(t hat)) { 212 if (this->classID() != that.classID() || !this->hasSameTextureAccesses(t hat)) {
132 return false; 213 return false;
133 } 214 }
134 215
135 // TODO remove the hint 216 // TODO remove the hint
136 if (fHasVertexColor && fOpaqueVertexColors != that.fOpaqueVertexColors) { 217 const GrGeometryProcessor& other = that.cast<GrGeometryProcessor>();
218 if (fHasVertexColor && fOpaqueVertexColors != other.fOpaqueVertexColors) {
137 return false; 219 return false;
138 } 220 }
139 221
140 if (!fHasVertexColor && this->color() != that.color()) { 222 // TODO this equality test should really be broken up, some of this can live on the batch
223 // tracker test and some of this should be in bundles
224 if (!this->onIsEqual(other)) {
141 return false; 225 return false;
142 } 226 }
143 227
144 // TODO this is fragile, most gps set their coverage to 0xff so this is okay. In the long 228 return this->onCanMakeEqual(mine, theirs);
145 // term this should move to subclasses which set explicit coverage
146 if (!fHasVertexCoverage && this->coverage() != that.coverage()) {
147 return false;
148 }
149 return this->onIsEqual(that);
150 } 229 }
151 230
152 struct InitBT { 231
153 bool fOutputColor; 232 // TODO we can remove color from the GrGeometryProcessor base class once we have bundles of
154 bool fOutputCoverage; 233 // primitive data
155 GrColor fColor; 234 GrColor color() const { return fColor; }
156 GrColor fCoverage;
157 };
158 235
159 virtual void initBatchTracker(GrBatchTracker*, const InitBT&) const {} 236 // TODO this is a total hack until the gp can do deferred geometry
237 bool hasVertexColor() const { return fHasVertexColor; }
160 238
161 GrColor color() const { return fColor; } 239 // TODO this is a total hack until gp can setup and manage local coords
162 uint8_t coverage() const SK_OVERRIDE { return fCoverage; }
163
164 // TODO this is a total hack until the gp can own whether or not it uses uni form
165 // color / coverage
166 bool hasVertexColor() const { return fHasVertexColor; }
167 bool hasVertexCoverage() const { return fHasVertexCoverage; }
168 bool hasLocalCoords() const { return fHasLocalCoords; } 240 bool hasLocalCoords() const { return fHasLocalCoords; }
169 241
170 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE; 242 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE;
171 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E; 243 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E;
172 244
173 protected: 245 protected:
246 /*
247 * An optional simple helper function to determine by what means the GrGeome tryProcessor should
248 * use to provide color. If we are given an override color(ie the given ove rridecolor is NOT
249 * GrColor_ILLEGAL) then we must always emit that color(currently overrides are only supported
250 * via uniform, but with deferred Geometry we could use attributes). Otherw ise, if our color is
251 * ignored then we should not emit a color. Lastly, if we don't have vertex colors then we must
252 * emit a color via uniform
253 * TODO this function changes quite a bit with deferred geometry. There the GrGeometryProcessor
254 * can upload a new color via attribute if needed.
255 */
256 static GrGPInput GetColorInputType(GrColor* color, GrColor primitiveColor, c onst InitBT& init,
257 bool hasVertexColor) {
258 if (init.fColorIgnored) {
259 *color = GrColor_ILLEGAL;
260 return kIgnored_GrGPInput;
261 } else if (GrColor_ILLEGAL != init.fOverrideColor) {
262 *color = init.fOverrideColor;
263 return kUniform_GrGPInput;
264 }
265
266 *color = primitiveColor;
267 if (hasVertexColor) {
268 return kAttribute_GrGPInput;
269 } else {
270 return kUniform_GrGPInput;
271 }
272 }
273
174 /** 274 /**
175 * Subclasses call this from their constructor to register vertex attributes . Attributes 275 * Subclasses call this from their constructor to register vertex attributes . Attributes
176 * will be padded to the nearest 4 bytes for performance reasons. 276 * will be padded to the nearest 4 bytes for performance reasons.
177 * TODO After deferred geometry, we should do all of this inline in Generate Geometry alongside 277 * TODO After deferred geometry, we should do all of this inline in Generate Geometry alongside
178 * the struct used to actually populate the attributes 278 * the struct used to actually populate the attributes. This is all extreme ly fragile, vertex
279 * attributes have to be added in the order they will appear in the struct w hich maps memory.
280 * The processor key should reflect the vertex attributes, or there lack the reof in the
281 * GrGeometryProcessor.
179 */ 282 */
180 const GrAttribute& addVertexAttrib(const GrAttribute& attribute) { 283 const GrAttribute& addVertexAttrib(const GrAttribute& attribute) {
181 fVertexStride += attribute.fOffset; 284 fVertexStride += attribute.fOffset;
182 return fAttribs.push_back(attribute); 285 return fAttribs.push_back(attribute);
183 } 286 }
184 287
185 void setWillUseGeoShader() { fWillUseGeoShader = true; } 288 void setWillUseGeoShader() { fWillUseGeoShader = true; }
186 289
187 // TODO hack see above 290 // TODO hack see above
188 void setHasVertexColor() { fHasVertexColor = true; } 291 void setHasVertexColor() { fHasVertexColor = true; }
189 void setHasVertexCoverage() { fHasVertexCoverage = true; }
190 void setHasLocalCoords() { fHasLocalCoords = true; } 292 void setHasLocalCoords() { fHasLocalCoords = true; }
191 293
192 virtual void onGetInvariantOutputColor(GrInitInvariantOutput*) const {} 294 virtual void onGetInvariantOutputColor(GrInitInvariantOutput*) const {}
193 virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const = 0; 295 virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const = 0;
194 296
195 private: 297 private:
298 virtual bool onCanMakeEqual(const GrBatchTracker& mine, const GrBatchTracker & theirs) const = 0;
299 // TODO delete this when we have more advanced equality testing via bundles and the BT
196 virtual bool onIsEqual(const GrGeometryProcessor&) const = 0; 300 virtual bool onIsEqual(const GrGeometryProcessor&) const = 0;
197 301
198 SkSTArray<kMaxVertexAttribs, GrAttribute, true> fAttribs; 302 SkSTArray<kMaxVertexAttribs, GrAttribute, true> fAttribs;
199 size_t fVertexStride; 303 size_t fVertexStride;
200 GrColor fColor; 304 GrColor fColor;
201 uint8_t fCoverage;
202 bool fOpaqueVertexColors; 305 bool fOpaqueVertexColors;
203 bool fWillUseGeoShader; 306 bool fWillUseGeoShader;
204 bool fHasVertexColor; 307 bool fHasVertexColor;
205 bool fHasVertexCoverage;
206 bool fHasLocalCoords; 308 bool fHasLocalCoords;
207 309
208 typedef GrProcessor INHERITED; 310 typedef GrProcessor INHERITED;
209 }; 311 };
210 312
211 /* 313 /*
212 * The path equivalent of the GP. For now this just manages color. In the long term we plan on 314 * The path equivalent of the GP. For now this just manages color. In the long term we plan on
213 * extending this class to handle all nvpr uniform / varying / program work. 315 * extending this class to handle all nvpr uniform / varying / program work.
214 */ 316 */
215 class GrPathProcessor : public GrPrimitiveProcessor { 317 class GrPathProcessor : public GrPrimitiveProcessor {
216 public: 318 public:
217 static GrPathProcessor* Create(GrColor color) { 319 static GrPathProcessor* Create(GrColor color) {
218 return SkNEW_ARGS(GrPathProcessor, (color)); 320 return SkNEW_ARGS(GrPathProcessor, (color));
219 } 321 }
322
323 void initBatchTracker(GrBatchTracker*, const InitBT&) const SK_OVERRIDE;
324
325 bool canMakeEqual(const GrBatchTracker& mine,
326 const GrPrimitiveProcessor& that,
327 const GrBatchTracker& theirs) const SK_OVERRIDE;
220 328
221 const char* name() const SK_OVERRIDE { return "PathProcessor"; } 329 const char* name() const SK_OVERRIDE { return "PathProcessor"; }
222 uint8_t coverage() const SK_OVERRIDE { return 0xff; } 330
331 GrColor color() const { return fColor; }
332
223 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE; 333 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE;
224 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E; 334 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E;
225 335
336 virtual void getGLProcessorKey(const GrBatchTracker& bt,
337 const GrGLCaps& caps,
338 GrProcessorKeyBuilder* b) const SK_OVERRIDE;
339
340 virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) co nst SK_OVERRIDE;
341
226 private: 342 private:
227 GrPathProcessor(GrColor color) : fColor(color) {} 343 GrPathProcessor(GrColor color);
228 GrColor fColor; 344 GrColor fColor;
229 345
230 typedef GrProcessor INHERITED; 346 typedef GrProcessor INHERITED;
231 }; 347 };
232 #endif 348 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrDefaultGeoProcFactory.cpp ('k') | src/gpu/GrGeometryProcessor.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698