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 "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 |
OLD | NEW |