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