OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 GrGLProgramBuilder_DEFINED | 8 #ifndef GrGLProgramBuilder_DEFINED |
9 #define GrGLProgramBuilder_DEFINED | 9 #define GrGLProgramBuilder_DEFINED |
10 | 10 |
11 #include "GrGLFragmentShaderBuilder.h" | 11 #include "GrGLFragmentShaderBuilder.h" |
12 #include "GrGLGeometryShaderBuilder.h" | 12 #include "GrGLGeometryShaderBuilder.h" |
13 #include "GrGLVertexShaderBuilder.h" | 13 #include "GrGLVertexShaderBuilder.h" |
14 #include "../GrGLProgramDataManager.h" | 14 #include "../GrGLProgramDataManager.h" |
15 #include "../GrGLUniformHandle.h" | 15 #include "../GrGLUniformHandle.h" |
16 | 16 #include "../GrGLGeometryProcessor.h" |
17 class GrGLInstalledProcessors; | |
18 | 17 |
19 /* | 18 /* |
20 * This is the base class for a series of interfaces. This base class *MUST* re
main abstract with | 19 * This is the base class for a series of interfaces. This base class *MUST* re
main abstract with |
21 * NO data members because it is used in multiple interface inheritance. | 20 * NO data members because it is used in multiple interface inheritance. |
22 * Heirarchy: | 21 * Heirarchy: |
23 * GrGLUniformBuilder | 22 * GrGLUniformBuilder |
24 * / \ | 23 * / \ |
25 * GrGLFPBuilder GrGLGPBuilder | 24 * GrGLFPBuilder GrGLGPBuilder |
26 * \ / | 25 * \ / |
27 * GrGLProgramBuilder(internal use only) | 26 * GrGLProgramBuilder(internal use only) |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 /* a specializations for FPs. Lets the user add uniforms and FS code */ | 90 /* a specializations for FPs. Lets the user add uniforms and FS code */ |
92 class GrGLFPBuilder : public virtual GrGLUniformBuilder { | 91 class GrGLFPBuilder : public virtual GrGLUniformBuilder { |
93 public: | 92 public: |
94 virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() = 0; | 93 virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() = 0; |
95 | 94 |
96 /* | 95 /* |
97 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE | 96 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE |
98 */ | 97 */ |
99 }; | 98 }; |
100 | 99 |
| 100 struct GrGLInstalledProc; |
| 101 struct GrGLInstalledGeoProc; |
| 102 struct GrGLInstalledFragProc; |
| 103 struct GrGLInstalledFragProcs; |
| 104 |
101 /* | 105 /* |
102 * Please note - no diamond problems because of virtual inheritance. Also, both
base classes | 106 * Please note - no diamond problems because of virtual inheritance. Also, both
base classes |
103 * are pure virtual with no data members. This is the base class for program bu
ilding. | 107 * are pure virtual with no data members. This is the base class for program bu
ilding. |
104 * Subclasses are nearly identical but each has their own way of emitting transf
orms. State for | 108 * Subclasses are nearly identical but each has their own way of emitting transf
orms. State for |
105 * each of the elements of the shader pipeline, ie vertex, fragment, geometry, e
tc, lives in those | 109 * each of the elements of the shader pipeline, ie vertex, fragment, geometry, e
tc, lives in those |
106 * respective builders | 110 * respective builders |
107 */ | 111 */ |
108 class GrGLProgramBuilder : public GrGLGPBuilder, | 112 class GrGLProgramBuilder : public GrGLGPBuilder, |
109 public GrGLFPBuilder { | 113 public GrGLFPBuilder { |
110 public: | 114 public: |
111 /** Generates a shader program. | 115 /** Generates a shader program. |
112 * | 116 * |
113 * The program implements what is specified in the stages given as input. | 117 * The program implements what is specified in the stages given as input. |
114 * After successful generation, the builder result objects are available | 118 * After successful generation, the builder result objects are available |
115 * to be used. | 119 * to be used. |
116 * @return true if generation was successful. | 120 * @return true if generation was successful. |
117 */ | 121 */ |
118 static GrGLProgram* CreateProgram(const GrOptDrawState&, | 122 static GrGLProgram* CreateProgram(const GrOptDrawState&, |
119 const GrGLProgramDesc&, | 123 const GrGLProgramDesc&, |
120 GrGpu::DrawType, | 124 GrGpu::DrawType, |
121 const GrGeometryStage* inGeometryProcessor
, | |
122 const GrFragmentStage* inColorStages[], | |
123 const GrFragmentStage* inCoverageStages[], | |
124 GrGpuGL* gpu); | 125 GrGpuGL* gpu); |
125 | 126 |
126 virtual UniformHandle addUniform(uint32_t visibility, | 127 virtual UniformHandle addUniform(uint32_t visibility, |
127 GrSLType type, | 128 GrSLType type, |
128 const char* name, | 129 const char* name, |
129 const char** outName = NULL) SK_OVERRIDE { | 130 const char** outName = NULL) SK_OVERRIDE { |
130 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNon
Array, outName); | 131 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNon
Array, outName); |
131 } | 132 } |
132 virtual UniformHandle addUniformArray(uint32_t visibility, | 133 virtual UniformHandle addUniformArray(uint32_t visibility, |
133 GrSLType type, | 134 GrSLType type, |
134 const char* name, | 135 const char* name, |
135 int arrayCount, | 136 int arrayCount, |
136 const char** outName = NULL) SK_OVERRI
DE; | 137 const char** outName = NULL) SK_OVERRI
DE; |
137 | 138 |
138 virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const SK_OV
ERRIDE { | 139 virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const SK_OV
ERRIDE { |
139 return fUniforms[u.toShaderBuilderIndex()].fVariable; | 140 return fUniforms[u.toShaderBuilderIndex()].fVariable; |
140 } | 141 } |
141 | 142 |
142 virtual const char* getUniformCStr(UniformHandle u) const SK_OVERRIDE { | 143 virtual const char* getUniformCStr(UniformHandle u) const SK_OVERRIDE { |
143 return this->getUniformVariable(u).c_str(); | 144 return this->getUniformVariable(u).c_str(); |
144 } | 145 } |
145 | 146 |
146 virtual const GrGLContextInfo& ctxInfo() const SK_OVERRIDE; | 147 virtual const GrGLContextInfo& ctxInfo() const SK_OVERRIDE; |
147 | 148 |
148 virtual GrGpuGL* gpu() const SK_OVERRIDE { return fGpu; } | 149 virtual GrGpuGL* gpu() const SK_OVERRIDE { return fGpu; } |
149 | 150 |
150 virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() SK_OVERRIDE { retu
rn &fFS; } | 151 virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() SK_OVERRIDE { retu
rn &fFS; } |
151 virtual GrGLVertexBuilder* getVertexShaderBuilder() SK_OVERRIDE { return &fV
S; } | 152 virtual GrGLVertexBuilder* getVertexShaderBuilder() SK_OVERRIDE { return &fV
S; } |
152 | 153 |
153 virtual void addVarying(GrSLType type, | 154 virtual void addVarying( |
154 const char* name, | 155 GrSLType type, |
155 const char** vsOutName = NULL, | 156 const char* name, |
156 const char** fsInName = NULL, | 157 const char** vsOutName = NULL, |
157 GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::
kDefault_Precision); | 158 const char** fsInName = NULL, |
| 159 GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precisi
on) SK_OVERRIDE; |
158 | 160 |
159 // Handles for program uniforms (other than per-effect uniforms) | 161 // Handles for program uniforms (other than per-effect uniforms) |
160 struct BuiltinUniformHandles { | 162 struct BuiltinUniformHandles { |
161 UniformHandle fViewMatrixUni; | 163 UniformHandle fViewMatrixUni; |
162 UniformHandle fRTAdjustmentUni; | 164 UniformHandle fRTAdjustmentUni; |
163 UniformHandle fColorUni; | 165 UniformHandle fColorUni; |
164 UniformHandle fCoverageUni; | 166 UniformHandle fCoverageUni; |
165 | 167 |
166 // We use the render target height to provide a y-down frag coord when s
pecifying | 168 // We use the render target height to provide a y-down frag coord when s
pecifying |
167 // origin_upper_left is not supported. | 169 // origin_upper_left is not supported. |
168 UniformHandle fRTHeightUni; | 170 UniformHandle fRTHeightUni; |
169 | 171 |
170 // Uniforms for computing texture coords to do the dst-copy lookup | 172 // Uniforms for computing texture coords to do the dst-copy lookup |
171 UniformHandle fDstCopyTopLeftUni; | 173 UniformHandle fDstCopyTopLeftUni; |
172 UniformHandle fDstCopyScaleUni; | 174 UniformHandle fDstCopyScaleUni; |
173 UniformHandle fDstCopySamplerUni; | 175 UniformHandle fDstCopySamplerUni; |
174 }; | 176 }; |
175 | 177 |
176 protected: | 178 protected: |
| 179 typedef GrGLProgramDesc::ProcKeyProvider ProcKeyProvider; |
| 180 typedef GrGLProgramDataManager::UniformInfo UniformInfo; |
| 181 typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray; |
| 182 |
177 static GrGLProgramBuilder* CreateProgramBuilder(const GrGLProgramDesc&, | 183 static GrGLProgramBuilder* CreateProgramBuilder(const GrGLProgramDesc&, |
178 const GrOptDrawState&, | 184 const GrOptDrawState&, |
179 GrGpu::DrawType, | 185 GrGpu::DrawType, |
180 bool hasGeometryProcessor, | 186 bool hasGeometryProcessor, |
181 GrGpuGL*); | 187 GrGpuGL*); |
182 | 188 |
183 GrGLProgramBuilder(GrGpuGL*, const GrOptDrawState&, const GrGLProgramDesc&); | 189 GrGLProgramBuilder(GrGpuGL*, const GrOptDrawState&, const GrGLProgramDesc&); |
184 | 190 |
185 const GrOptDrawState& optState() const { return fOptState; } | 191 const GrOptDrawState& optState() const { return fOptState; } |
186 const GrGLProgramDesc& desc() const { return fDesc; } | 192 const GrGLProgramDesc& desc() const { return fDesc; } |
187 const GrGLProgramDesc::KeyHeader& header() const { return fDesc.getHeader();
} | 193 const GrGLProgramDesc::KeyHeader& header() const { return fDesc.getHeader();
} |
188 | 194 |
189 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix | 195 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix |
190 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're | 196 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're |
191 // generating stage code. | 197 // generating stage code. |
192 void nameVariable(SkString* out, char prefix, const char* name); | 198 void nameVariable(SkString* out, char prefix, const char* name); |
193 void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExp
r4* inputCoverage); | 199 void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExp
r4* inputCoverage); |
194 void createAndEmitProcessors(const GrGeometryStage* geometryProcessor, | 200 void emitAndInstallProcs(const GrOptDrawState& optState, |
195 const GrFragmentStage* colorStages[], | 201 GrGLSLExpr4* inputColor, |
196 const GrFragmentStage* coverageStages[], | 202 GrGLSLExpr4* inputCoverage); |
197 GrGLSLExpr4* inputColor, | 203 void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOu
t); |
198 GrGLSLExpr4* inputCoverage); | 204 template <class Proc> |
199 template <class ProcessorStage> | 205 void emitAndInstallProc(const Proc&, |
200 void createAndEmitProcessors(const ProcessorStage*[], | 206 int index, |
201 int effectCnt, | 207 const ProcKeyProvider, |
202 const GrGLProgramDesc::EffectKeyProvider&, | 208 const GrGLSLExpr4& input, |
203 GrGLSLExpr4* fsInOutColor, | 209 GrGLSLExpr4* output); |
204 GrGLInstalledProcessors*); | 210 |
| 211 // these emit functions help to keep the createAndEmitProcessors template ge
neral |
| 212 void emitAndInstallProc(const GrFragmentStage&, |
| 213 const GrProcessorKey&, |
| 214 const char* outColor, |
| 215 const char* inColor); |
| 216 void emitAndInstallProc(const GrGeometryProcessor&, |
| 217 const GrProcessorKey&, |
| 218 const char* outColor, |
| 219 const char* inColor); |
205 void verify(const GrGeometryProcessor&); | 220 void verify(const GrGeometryProcessor&); |
206 void verify(const GrFragmentProcessor&); | 221 void verify(const GrFragmentProcessor&); |
207 void emitSamplers(const GrProcessor&, | 222 void emitSamplers(const GrProcessor&, |
208 GrGLProcessor::TextureSamplerArray* outSamplers, | 223 GrGLProcessor::TextureSamplerArray* outSamplers, |
209 GrGLInstalledProcessors*); | 224 GrGLInstalledProc*); |
210 | 225 |
211 // each specific program builder has a distinct transform and must override
this function | 226 // each specific program builder has a distinct transform and must override
this function |
212 virtual void emitTransforms(const GrProcessorStage&, | 227 virtual void emitTransforms(const GrFragmentStage&, |
213 GrGLProcessor::TransformedCoordsArray* outCoords
, | 228 GrGLProcessor::TransformedCoordsArray* outCoords
, |
214 GrGLInstalledProcessors*); | 229 GrGLInstalledFragProc*); |
215 GrGLProgram* finalize(); | 230 GrGLProgram* finalize(); |
216 void bindUniformLocations(GrGLuint programID); | 231 void bindUniformLocations(GrGLuint programID); |
217 bool checkLinkStatus(GrGLuint programID); | 232 bool checkLinkStatus(GrGLuint programID); |
218 void resolveUniformLocations(GrGLuint programID); | 233 void resolveUniformLocations(GrGLuint programID); |
219 | |
220 void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs
); | 234 void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs
); |
221 void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs); | 235 void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs); |
222 | 236 |
223 // Subclasses create different programs | 237 // Subclasses create different programs |
224 virtual GrGLProgram* createProgram(GrGLuint programID); | 238 virtual GrGLProgram* createProgram(GrGLuint programID); |
225 | 239 |
226 void appendUniformDecls(ShaderVisibility, SkString*) const; | 240 void appendUniformDecls(ShaderVisibility, SkString*) const; |
227 | 241 |
228 // reset is called by program creator between each processor's emit code. I
t increments the | 242 // reset is called by program creator between each processor's emit code. I
t increments the |
229 // stage offset for variable name mangling, and also ensures verfication var
iables in the | 243 // stage offset for variable name mangling, and also ensures verfication var
iables in the |
(...skipping 19 matching lines...) Expand all Loading... |
249 public: | 263 public: |
250 AutoStageAdvance(GrGLProgramBuilder* pb) : fPB(pb) { fPB->reset(); } | 264 AutoStageAdvance(GrGLProgramBuilder* pb) : fPB(pb) { fPB->reset(); } |
251 ~AutoStageAdvance() { fPB->exitStage(); } | 265 ~AutoStageAdvance() { fPB->exitStage(); } |
252 private: | 266 private: |
253 GrGLProgramBuilder* fPB; | 267 GrGLProgramBuilder* fPB; |
254 }; | 268 }; |
255 void exitStage() { fOutOfStage = true; } | 269 void exitStage() { fOutOfStage = true; } |
256 void enterStage() { fOutOfStage = false; } | 270 void enterStage() { fOutOfStage = false; } |
257 int stageIndex() const { return fStageIndex; } | 271 int stageIndex() const { return fStageIndex; } |
258 | 272 |
259 typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider; | |
260 typedef GrGLProgramDataManager::UniformInfo UniformInfo; | |
261 typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray; | |
262 | |
263 // number of each input/output type in a single allocation block, used by ma
ny builders | 273 // number of each input/output type in a single allocation block, used by ma
ny builders |
264 static const int kVarsPerBlock; | 274 static const int kVarsPerBlock; |
265 | 275 |
266 BuiltinUniformHandles fUniformHandles; | 276 BuiltinUniformHandles fUniformHandles; |
267 GrGLVertexBuilder fVS; | 277 GrGLVertexBuilder fVS; |
268 GrGLGeometryBuilder fGS; | 278 GrGLGeometryBuilder fGS; |
269 GrGLFragmentShaderBuilder fFS; | 279 GrGLFragmentShaderBuilder fFS; |
270 bool fOutOfStage; | 280 bool fOutOfStage; |
271 int fStageIndex; | 281 int fStageIndex; |
272 | 282 |
273 SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor; | 283 GrGLInstalledGeoProc* fGeometryProcessor; |
274 SkAutoTUnref<GrGLInstalledProcessors> fColorEffects; | 284 SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors; |
275 SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects; | |
276 | 285 |
277 const GrOptDrawState& fOptState; | 286 const GrOptDrawState& fOptState; |
278 const GrGLProgramDesc& fDesc; | 287 const GrGLProgramDesc& fDesc; |
279 GrGpuGL* fGpu; | 288 GrGpuGL* fGpu; |
280 UniformInfoArray fUniforms; | 289 UniformInfoArray fUniforms; |
281 | 290 |
282 friend class GrGLShaderBuilder; | 291 friend class GrGLShaderBuilder; |
283 friend class GrGLVertexBuilder; | 292 friend class GrGLVertexBuilder; |
284 friend class GrGLFragmentShaderBuilder; | 293 friend class GrGLFragmentShaderBuilder; |
285 friend class GrGLGeometryBuilder; | 294 friend class GrGLGeometryBuilder; |
286 }; | 295 }; |
287 | 296 |
288 /** | 297 /** |
289 * This class encapsulates an array of GrGLProcessors and their supporting data
(coord transforms | 298 * The below structs represent processors installed in programs. All processors
can have texture |
290 * and textures). It is built by GrGLProgramBuilder, then used to manage the nec
essary GL | 299 * samplers, but only frag processors have coord transforms, hence the need for
different structs |
291 * state and shader uniforms in GLPrograms. Its just Plain old data, and as suc
h is entirely public | |
292 * | |
293 * TODO We really don't need this class to have an array of processors. It make
s sense for it | |
294 * to just have one, also break out the transforms | |
295 */ | 300 */ |
296 class GrGLInstalledProcessors : public SkRefCnt { | 301 struct GrGLInstalledProc { |
297 public: | 302 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
298 GrGLInstalledProcessors(int reserveCount, bool hasExplicitLocalCoords = fals
e) | |
299 : fGLProcessors(reserveCount) | |
300 , fSamplers(reserveCount) | |
301 , fTransforms(reserveCount) | |
302 , fHasExplicitLocalCoords(hasExplicitLocalCoords) { | |
303 } | |
304 | 303 |
305 virtual ~GrGLInstalledProcessors(); | 304 struct Sampler { |
| 305 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) |
| 306 UniformHandle fUniform; |
| 307 int fTextureUnit; |
| 308 }; |
| 309 SkSTArray<4, Sampler, true> fSamplers; |
| 310 }; |
306 | 311 |
307 typedef GrGLProgramDataManager::UniformHandle UniformHandle; | 312 struct GrGLInstalledGeoProc : public GrGLInstalledProc { |
| 313 SkAutoTDelete<GrGLGeometryProcessor> fGLProc; |
| 314 }; |
308 | 315 |
309 struct Sampler { | 316 struct GrGLInstalledFragProc : public GrGLInstalledProc { |
310 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) | 317 GrGLInstalledFragProc(bool useLocalCoords) : fGLProc(NULL), fLocalCoordAttri
b(useLocalCoords) {} |
311 UniformHandle fUniform; | |
312 int fTextureUnit; | |
313 }; | |
314 | |
315 class ShaderVarHandle { | 318 class ShaderVarHandle { |
316 public: | 319 public: |
317 bool isValid() const { return fHandle > -1; } | 320 bool isValid() const { return fHandle > -1; } |
318 ShaderVarHandle() : fHandle(-1) {} | 321 ShaderVarHandle() : fHandle(-1) {} |
319 ShaderVarHandle(int value) : fHandle(value) { SkASSERT(this->isValid());
} | 322 ShaderVarHandle(int value) : fHandle(value) { SkASSERT(this->isValid());
} |
320 int handle() const { SkASSERT(this->isValid()); return fHandle; } | 323 int handle() const { SkASSERT(this->isValid()); return fHandle; } |
321 UniformHandle convertToUniformHandle() { | 324 UniformHandle convertToUniformHandle() { |
322 SkASSERT(this->isValid()); | 325 SkASSERT(this->isValid()); |
323 return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex
(fHandle); | 326 return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex
(fHandle); |
324 } | 327 } |
325 | 328 |
326 private: | 329 private: |
327 int fHandle; | 330 int fHandle; |
328 }; | 331 }; |
329 | 332 |
330 struct Transform { | 333 struct Transform { |
331 Transform() : fType(kVoid_GrSLType) { fCurrentValue = SkMatrix::InvalidM
atrix(); } | 334 Transform() : fType(kVoid_GrSLType) { fCurrentValue = SkMatrix::InvalidM
atrix(); } |
332 ShaderVarHandle fHandle; | 335 ShaderVarHandle fHandle; |
333 SkMatrix fCurrentValue; | 336 SkMatrix fCurrentValue; |
334 GrSLType fType; | 337 GrSLType fType; |
335 }; | 338 }; |
336 | 339 |
337 void addEffect(GrGLProcessor* effect) { fGLProcessors.push_back(effect); } | 340 SkAutoTDelete<GrGLFragmentProcessor> fGLProc; |
338 SkTArray<Sampler, true>& addSamplers() { return fSamplers.push_back(); } | 341 SkSTArray<2, Transform, true> fTransforms; |
339 SkTArray<Transform, true>& addTransforms() { return fTransforms.push_back();
} | 342 bool fLocalCoordAttrib; |
| 343 }; |
340 | 344 |
341 SkTArray<GrGLProcessor*> fGLProcessors; | 345 struct GrGLInstalledFragProcs : public SkRefCnt { |
342 SkTArray<SkSTArray<4, Sampler, true> > fSamplers; | 346 virtual ~GrGLInstalledFragProcs(); |
343 SkTArray<SkSTArray<2, Transform, true> > fTransforms; | 347 SkSTArray<8, GrGLInstalledFragProc*, true> fProcs; |
344 bool fHasExplicitLocalCoords; | |
345 | |
346 friend class GrGLShaderBuilder; | |
347 friend class GrGLVertexShaderBuilder; | |
348 friend class GrGLFragmentShaderBuilder; | |
349 friend class GrGLGeometryShaderBuilder; | |
350 }; | 348 }; |
351 | 349 |
352 #endif | 350 #endif |
OLD | NEW |