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

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: missed some places to update uniform cache 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
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
bsalomon 2014/12/15 15:31:13 This comment is great! Two minor suggestions: ma
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. The GrPrimitiveProcessor seeds these loops, one with i nitial color and one
26 * with initial coverage, in its onComputeInvariantColor / Coverage calls. Thes e seed values are
27 * processed by the subsequent stages of the rendering pipeline and the output i s then fed back
28 * into the GrPrimitiveProcessor in the initBatchTracker call, where the GrPrimi tiveProcessor can
29 * then initialize the GrBatchTracker struct with the appropriate values.
30 *
31 * In a deferred geometry world, the GrPrimitiveProcessor can always 'batch' To do this, each
32 * primitive type is associated with one GrPrimitiveProcessor, who has complete control of how
33 * it draws. Each primitive draw will bundle all required data to perform the d raw, and these
34 * bundles of data will be owned by an instance of the associated GrPrimitivePro cessor. Bundles
35 * can be updated alongside the GrBatchTracker struct itself, ultimately allowin g the
36 * GrPrimitiveProcessor complete control of how it gets data into the fragment s hader as long as
37 * it emits the appropriate color, or none at all, as directed.
38 */
39
40 /*
17 * A struct for tracking batching decisions. While this lives on GrOptState, it is managed 41 * A struct for tracking batching decisions. While this lives on GrOptState, it is managed
18 * entirely by the derived classes of the GP. 42 * entirely by the derived classes of the GP.
19 */ 43 */
20 class GrBatchTracker { 44 class GrBatchTracker {
21 public: 45 public:
22 template <typename T> const T& cast() const { 46 template <typename T> const T& cast() const {
23 SkASSERT(sizeof(T) <= kMaxSize); 47 SkASSERT(sizeof(T) <= kMaxSize);
24 return *reinterpret_cast<const T*>(fData); 48 return *reinterpret_cast<const T*>(fData.get());
25 } 49 }
26 50
27 template <typename T> T* cast() { 51 template <typename T> T* cast() {
28 SkASSERT(sizeof(T) <= kMaxSize); 52 SkASSERT(sizeof(T) <= kMaxSize);
29 return reinterpret_cast<T*>(fData); 53 return reinterpret_cast<T*>(fData.get());
30 } 54 }
31 55
32 static const size_t kMaxSize = 32; 56 static const size_t kMaxSize = 32;
33 57
34 private: 58 private:
35 uint8_t fData[kMaxSize]; 59 mutable SkAlignedSStorage<kMaxSize> fData;
bsalomon 2014/12/15 15:31:13 still unclear to me why this is mutable and the th
36 }; 60 };
37 61
38 class GrGLCaps; 62 class GrGLCaps;
39 class GrGLGeometryProcessor; 63 class GrGLGeometryProcessor;
40 class GrOptDrawState; 64 class GrOptDrawState;
41 65
42 struct GrInitInvariantOutput; 66 struct GrInitInvariantOutput;
43 67
44 /* 68 /*
45 * GrGeometryProcessors and GrPathProcessors may effect invariantColor 69 * GrPrimitiveProcessor defines an interface which all subclasses must implement . All
70 * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh co lor / coverage
71 * pipelines, and they must provide some notion of equality
46 */ 72 */
47 class GrPrimitiveProcessor : public GrProcessor { 73 class GrPrimitiveProcessor : public GrProcessor {
48 public: 74 public:
49 // TODO GPs and PPs have to provide an initial coverage because the coverage invariant code is 75 virtual bool canMakeEqual(const GrBatchTracker& mine,
50 // broken right now 76 const GrPrimitiveProcessor& that,
51 virtual uint8_t coverage() const = 0; 77 const GrBatchTracker& theirs) const = 0;
78
79 /*
80 * We always call canMakeEqual before makeEqual so there is no need to do an y kind of equality
81 * testing here
82 * TODO make this pure virtual when primProcs can actually use it
83 */
84 virtual void makeEqual(GrBatchTracker*, const GrBatchTracker&) const {}
85
52 virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0; 86 virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0;
53 virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0; 87 virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0;
54 88
55 private: 89 private:
56 typedef GrProcessor INHERITED; 90 typedef GrProcessor INHERITED;
57 }; 91 };
58 92
93 /*
94 * This enum is shared by GrPrimitiveProcessors and GrGLPrimitiveProcessors to c oordinate shaders
95 * with vertex attributes / uniforms.
96 */
97 enum GrGPInput {
98 kAllOnes_GrGPInput,
99 kAttribute_GrGPInput,
100 kUniform_GrGPInput,
101 kIgnored_GrGPInput,
102 };
103
59 /** 104 /**
60 * A GrGeometryProcessor is used to perform computation in the vertex shader and 105 * A GrGeometryProcessor is a flexible method for rendering a primitive. The Gr GeometryProcessor
61 * add support for custom vertex attributes. A GrGemeotryProcessor is typically 106 * has complete control over vertex attributes and uniforms(aside from the rende r target) but it
62 * tied to the code that does a specific type of high-level primitive rendering 107 * must obey the same contract as any GrPrimitiveProcessor, specifically it must emit a color and
63 * (e.g. anti-aliased circle rendering). The GrGeometryProcessor used for a draw is 108 * coverage into the fragment shader. Where this color and coverage come from i s completely the
64 * specified using GrDrawState. There can only be one geometry processor active for 109 * responsibility of the GrGeometryProcessor.
bsalomon 2014/12/15 15:31:13 nice
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 */ 110 */
69 class GrGeometryProcessor : public GrPrimitiveProcessor { 111 class GrGeometryProcessor : public GrPrimitiveProcessor {
70 public: 112 public:
71 // TODO the Hint can be handled in a much more clean way when we have deferr ed geometry or 113 // TODO the Hint can be handled in a much more clean way when we have deferr ed geometry or
72 // atleast bundles 114 // atleast bundles
73 GrGeometryProcessor(GrColor color, bool opaqueVertexColors = false, uint8_t coverage = 0xff) 115 GrGeometryProcessor(GrColor color, bool opaqueVertexColors = false)
74 : fVertexStride(0) 116 : fVertexStride(0)
75 , fColor(color) 117 , fColor(color)
76 , fCoverage(coverage)
77 , fOpaqueVertexColors(opaqueVertexColors) 118 , fOpaqueVertexColors(opaqueVertexColors)
78 , fWillUseGeoShader(false) 119 , fWillUseGeoShader(false)
79 , fHasVertexColor(false) 120 , fHasVertexColor(false)
80 , fHasVertexCoverage(false)
81 , fHasLocalCoords(false) {} 121 , fHasLocalCoords(false) {}
82 122
83 virtual const char* name() const = 0; 123 virtual const char* name() const = 0;
84 124
85 /** 125 /**
86 * Sets a unique key on the GrProcessorKeyBuilder that is directly associate d with this geometry 126 * Sets a unique key on the GrProcessorKeyBuilder that is directly associate d with this geometry
87 * processor's GL backend implementation. 127 * processor's GL backend implementation.
88 */ 128 */
89 virtual void getGLProcessorKey(const GrBatchTracker& bt, 129 virtual void getGLProcessorKey(const GrBatchTracker& bt,
90 const GrGLCaps& caps, 130 const GrGLCaps& caps,
(...skipping 25 matching lines...) Expand all
116 156
117 const VertexAttribArray& getAttribs() const { return fAttribs; } 157 const VertexAttribArray& getAttribs() const { return fAttribs; }
118 158
119 // Returns the vertex stride of the GP. A common use case is to request geo metry from a 159 // Returns the vertex stride of the GP. A common use case is to request geo metry from a
120 // drawtarget based off of the stride, and to populate this memory using an implicit array of 160 // drawtarget based off of the stride, and to populate this memory using an implicit array of
121 // structs. In this case, it is best to assert the vertexstride == sizeof(V ertexStruct). 161 // structs. In this case, it is best to assert the vertexstride == sizeof(V ertexStruct).
122 size_t getVertexStride() const { return fVertexStride; } 162 size_t getVertexStride() const { return fVertexStride; }
123 163
124 bool willUseGeoShader() const { return fWillUseGeoShader; } 164 bool willUseGeoShader() const { return fWillUseGeoShader; }
125 165
126 /** Returns true if this and other processor conservatively draw identically . It can only return 166 /*
127 true when the two prcoessors are of the same subclass (i.e. they return the same object from 167 * In an ideal world, two GrGeometryProcessors with the same class id and te xture accesses
128 from getFactory()). 168 * would ALWAYS be able to batch together. If two GrGeometryProcesosrs are the same then we
129 A return value of true from isEqual() should not be used to test whether the processors 169 * will only keep one of them. The remaining GrGeometryProcessor then updat es its
130 would generate the same shader code. To test for identical code generati on use the 170 * GrBatchTracker to incorporate the draw information from the GrGeometryPro cessor we discard.
131 processors' keys computed by the GrBackendEffectFactory. */ 171 * Any bundles associated with the discarded GrGeometryProcessor will be att ached to the
132 bool isEqual(const GrGeometryProcessor& that) const { 172 * remaining GrGeometryProcessor.
173 */
174 bool canMakeEqual(const GrBatchTracker& mine,
175 const GrPrimitiveProcessor& that,
176 const GrBatchTracker& theirs) const SK_OVERRIDE {
133 if (this->classID() != that.classID() || !this->hasSameTextureAccesses(t hat)) { 177 if (this->classID() != that.classID() || !this->hasSameTextureAccesses(t hat)) {
134 return false; 178 return false;
135 } 179 }
136 180
137 // TODO remove the hint 181 // TODO remove the hint
138 if (fHasVertexColor && fOpaqueVertexColors != that.fOpaqueVertexColors) { 182 const GrGeometryProcessor& other = that.cast<GrGeometryProcessor>();
183 if (fHasVertexColor && fOpaqueVertexColors != other.fOpaqueVertexColors) {
139 return false; 184 return false;
140 } 185 }
141 186
142 if (!fHasVertexColor && this->color() != that.color()) { 187 if (!fHasVertexColor && this->color() != other.color()) {
143 return false; 188 return false;
144 } 189 }
145 190 return this->onCanMakeEqual(mine, theirs);
146 // TODO this is fragile, most gps set their coverage to 0xff so this is okay. In the long
147 // term this should move to subclasses which set explicit coverage
148 if (!fHasVertexCoverage && this->coverage() != that.coverage()) {
149 return false;
150 }
151 return this->onIsEqual(that);
152 } 191 }
153 192
193 virtual bool onCanMakeEqual(const GrBatchTracker& mine, const GrBatchTracker & theirs) const = 0;
bsalomon 2014/12/15 15:31:13 move to private?
194
195 /*
196 * This struct allows the optstate to communicate requirements to the GP.
197 */
154 struct InitBT { 198 struct InitBT {
155 bool fOutputColor; 199 bool fColorIgnored;
156 bool fOutputCoverage; 200 bool fCoverageIgnored;
157 GrColor fColor; 201 GrColor fOverrideColor;
158 GrColor fCoverage;
159 }; 202 };
160 203
161 virtual void initBatchTracker(GrBatchTracker*, const InitBT&) const {} 204 virtual void initBatchTracker(GrBatchTracker*, const InitBT&) const = 0;
205
206 // TODO we can remove color from the GrGeometryProcessor base class once we have bundles of
207 // primitive data
208 GrColor color() const { return fColor; }
162 209
163 GrColor color() const { return fColor; } 210 // TODO this is a total hack until the gp can do deferred geometry
164 uint8_t coverage() const { return fCoverage; } 211 bool hasVertexColor() const { return fHasVertexColor; }
165 212
166 // TODO this is a total hack until the gp can own whether or not it uses uni form 213 // TODO this is a total hack until gp can setup and manage local coords
167 // color / coverage
168 bool hasVertexColor() const { return fHasVertexColor; }
169 bool hasVertexCoverage() const { return fHasVertexCoverage; }
170 bool hasLocalCoords() const { return fHasLocalCoords; } 214 bool hasLocalCoords() const { return fHasLocalCoords; }
171 215
172 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE; 216 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE;
173 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E; 217 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E;
174 218
175 protected: 219 protected:
220 /*
221 * A simple helper function to determine by what means the GrGeometryProcess or should use to
bsalomon 2014/12/15 15:31:13 Can you throw in the word "optional" ? Just want t
222 * provide color. If we are given an override color(ie the given overrideco lor is NOT illegal)
bsalomon 2014/12/15 15:31:13 can you say GrColor_ILLEGAL? I think it might be c
223 * then we must always emit that color via a uniform. Otherwise, if our col or is ignored
bsalomon 2014/12/15 15:31:13 Does it have to be via a uniform? A GP could rewr
224 * then we should not emit a color. Lastly, if we don't have vertex colors then we must emit
225 * a color via uniform
226 * TODO this function changes quite a bit with deferred geometry. There the GrGeometryProcessor
227 * can upload a new color via attribute if needed.
228 */
229 static GrGPInput GetColorInputType(GrColor* color, GrColor primitiveColor, c onst InitBT& init,
230 bool hasVertexColor) {
231 if (GrColor_ILLEGAL != init.fOverrideColor) {
232 *color = init.fOverrideColor;
233 return kUniform_GrGPInput;
234 } else if (init.fColorIgnored) {
235 *color = GrColor_ILLEGAL;
236 return kIgnored_GrGPInput;
237 }
238
239 *color = primitiveColor;
240 if (hasVertexColor) {
241 return kAttribute_GrGPInput;
242 } else {
243 return kUniform_GrGPInput;
244 }
245 }
246
247 /*
248 * CanCombineOutput will return true if two draws are 'batchable' from a col or perspective.
249 * TODO remove this when GPs can upgrade to attribute color
250 */
251 static bool CanCombineOutput(GrGPInput left, GrColor lColor, GrGPInput right , GrColor rColor) {
252 if (left != right) {
253 return false;
254 }
255
256 if (kUniform_GrGPInput == left && lColor != rColor) {
257 return false;
258 }
259
260 return true;
261 }
262
176 /** 263 /**
177 * Subclasses call this from their constructor to register vertex attributes . Attributes 264 * Subclasses call this from their constructor to register vertex attributes . Attributes
178 * will be padded to the nearest 4 bytes for performance reasons. 265 * will be padded to the nearest 4 bytes for performance reasons.
179 * TODO After deferred geometry, we should do all of this inline in Generate Geometry alongside 266 * TODO After deferred geometry, we should do all of this inline in Generate Geometry alongside
180 * the struct used to actually populate the attributes 267 * the struct used to actually populate the attributes
181 */ 268 */
182 const GrAttribute& addVertexAttrib(const GrAttribute& attribute) { 269 const GrAttribute& addVertexAttrib(const GrAttribute& attribute) {
183 fVertexStride += attribute.fOffset; 270 fVertexStride += attribute.fOffset;
184 return fAttribs.push_back(attribute); 271 return fAttribs.push_back(attribute);
185 } 272 }
186 273
187 void setWillUseGeoShader() { fWillUseGeoShader = true; } 274 void setWillUseGeoShader() { fWillUseGeoShader = true; }
188 275
189 // TODO hack see above 276 // TODO hack see above
190 void setHasVertexColor() { fHasVertexColor = true; } 277 void setHasVertexColor() { fHasVertexColor = true; }
191 void setHasVertexCoverage() { fHasVertexCoverage = true; }
192 void setHasLocalCoords() { fHasLocalCoords = true; } 278 void setHasLocalCoords() { fHasLocalCoords = true; }
193 279
194 virtual void onGetInvariantOutputColor(GrInitInvariantOutput*) const {} 280 virtual void onGetInvariantOutputColor(GrInitInvariantOutput*) const {}
195 virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const = 0; 281 virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const = 0;
196 282
197 private: 283 private:
198 virtual bool onIsEqual(const GrGeometryProcessor&) const = 0; 284 virtual bool onIsEqual(const GrGeometryProcessor&) const = 0;
199 285
200 SkSTArray<kMaxVertexAttribs, GrAttribute, true> fAttribs; 286 SkSTArray<kMaxVertexAttribs, GrAttribute, true> fAttribs;
201 size_t fVertexStride; 287 size_t fVertexStride;
202 GrColor fColor; 288 GrColor fColor;
203 uint8_t fCoverage;
204 bool fOpaqueVertexColors; 289 bool fOpaqueVertexColors;
205 bool fWillUseGeoShader; 290 bool fWillUseGeoShader;
206 bool fHasVertexColor; 291 bool fHasVertexColor;
207 bool fHasVertexCoverage;
208 bool fHasLocalCoords; 292 bool fHasLocalCoords;
209 293
210 typedef GrProcessor INHERITED; 294 typedef GrProcessor INHERITED;
211 }; 295 };
212 296
213 /* 297 /*
214 * The path equivalent of the GP. For now this just manages color. In the long term we plan on 298 * The path equivalent of the GP. For now this just manages color. In the long term we plan on
215 * extending this class to handle all nvpr uniform / varying / program work. 299 * extending this class to handle all nvpr uniform / varying / program work.
216 */ 300 */
217 class GrPathProcessor : public GrPrimitiveProcessor { 301 class GrPathProcessor : public GrPrimitiveProcessor {
218 public: 302 public:
219 static GrPathProcessor* Create(GrColor color) { 303 static GrPathProcessor* Create(GrColor color) {
220 return SkNEW_ARGS(GrPathProcessor, (color)); 304 return SkNEW_ARGS(GrPathProcessor, (color));
221 } 305 }
222 306
307 bool canMakeEqual(const GrBatchTracker& mine,
308 const GrPrimitiveProcessor& that,
309 const GrBatchTracker& theirs) const SK_OVERRIDE {
310 if (this->classID() != that.classID() || !this->hasSameTextureAccesses(t hat)) {
bsalomon 2014/12/15 15:31:13 Seems a little weird that path procs can even have
311 return false;
312 }
313 const GrPathProcessor& other = that.cast<GrPathProcessor>();
314 return other.color() == this->color();
bsalomon 2014/12/15 15:31:13 So if there is an override these two colors would
315 }
316
223 const char* name() const SK_OVERRIDE { return "PathProcessor"; } 317 const char* name() const SK_OVERRIDE { return "PathProcessor"; }
224 uint8_t coverage() const SK_OVERRIDE { return 0xff; } 318 GrColor color() const { return fColor; }
225 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE; 319 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE;
226 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E; 320 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E;
227 321
228 private: 322 private:
229 GrPathProcessor(GrColor color) : fColor(color) {} 323 GrPathProcessor(GrColor color);
230 GrColor fColor; 324 GrColor fColor;
231 325
232 typedef GrProcessor INHERITED; 326 typedef GrProcessor INHERITED;
233 }; 327 };
234 #endif 328 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698