OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 GrGLShaderBuilder_DEFINED | 8 #ifndef GrGLShaderBuilder_DEFINED |
9 #define GrGLShaderBuilder_DEFINED | 9 #define GrGLShaderBuilder_DEFINED |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... |
26 | 26 |
27 /** | 27 /** |
28 Contains all the incremental state of a shader as it is being built,as well as
helpers to | 28 Contains all the incremental state of a shader as it is being built,as well as
helpers to |
29 manipulate that state. | 29 manipulate that state. |
30 */ | 30 */ |
31 class GrGLShaderBuilder { | 31 class GrGLShaderBuilder { |
32 public: | 32 public: |
33 typedef GrTAllocator<GrGLShaderVar> VarArray; | 33 typedef GrTAllocator<GrGLShaderVar> VarArray; |
34 typedef GrGLProgramEffects::TextureSampler TextureSampler; | 34 typedef GrGLProgramEffects::TextureSampler TextureSampler; |
35 typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray; | 35 typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray; |
36 typedef GrGLProgramDataManager::BuilderUniform BuilderUniform; | |
37 | 36 |
38 enum ShaderVisibility { | 37 enum ShaderVisibility { |
39 kVertex_Visibility = 0x1, | 38 kVertex_Visibility = 0x1, |
40 kGeometry_Visibility = 0x2, | 39 kGeometry_Visibility = 0x2, |
41 kFragment_Visibility = 0x4, | 40 kFragment_Visibility = 0x4, |
42 }; | 41 }; |
43 | 42 |
44 typedef GrGLProgramDataManager::UniformHandle UniformHandle; | 43 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
45 | 44 |
46 // Handles for program uniforms (other than per-effect uniforms) | 45 // Handles for program uniforms (other than per-effect uniforms) |
47 struct UniformHandles { | 46 struct BuiltinUniformHandles { |
48 UniformHandle fViewMatrixUni; | 47 UniformHandle fViewMatrixUni; |
49 UniformHandle fRTAdjustmentUni; | 48 UniformHandle fRTAdjustmentUni; |
50 UniformHandle fColorUni; | 49 UniformHandle fColorUni; |
51 UniformHandle fCoverageUni; | 50 UniformHandle fCoverageUni; |
52 | 51 |
53 // We use the render target height to provide a y-down frag coord when s
pecifying | 52 // We use the render target height to provide a y-down frag coord when s
pecifying |
54 // origin_upper_left is not supported. | 53 // origin_upper_left is not supported. |
55 UniformHandle fRTHeightUni; | 54 UniformHandle fRTHeightUni; |
56 | 55 |
57 // Uniforms for computing texture coords to do the dst-copy lookup | 56 // Uniforms for computing texture coords to do the dst-copy lookup |
58 UniformHandle fDstCopyTopLeftUni; | 57 UniformHandle fDstCopyTopLeftUni; |
59 UniformHandle fDstCopyScaleUni; | 58 UniformHandle fDstCopyScaleUni; |
60 UniformHandle fDstCopySamplerUni; | 59 UniformHandle fDstCopySamplerUni; |
61 }; | 60 }; |
62 | 61 |
63 struct GenProgramOutput { | 62 struct UniformInfo { |
64 GenProgramOutput() | 63 GrGLShaderVar fVariable; |
65 : fColorEffects(NULL) | 64 uint32_t fVisibility; |
66 , fCoverageEffects(NULL) | 65 GrGLint fLocation; |
67 , fHasVertexShader(false) | |
68 , fTexCoordSetCnt(0) | |
69 , fProgramID(0) {} | |
70 | |
71 GenProgramOutput(const GenProgramOutput& other) { | |
72 *this = other; | |
73 } | |
74 | |
75 GenProgramOutput& operator=(const GenProgramOutput& other) { | |
76 fColorEffects.reset(SkRef(other.fColorEffects.get())); | |
77 fCoverageEffects.reset(SkRef(other.fCoverageEffects.get())); | |
78 fUniformHandles = other.fUniformHandles; | |
79 fHasVertexShader = other.fHasVertexShader; | |
80 fTexCoordSetCnt = other.fTexCoordSetCnt; | |
81 fProgramID = other.fProgramID; | |
82 return *this; | |
83 } | |
84 | |
85 SkAutoTUnref<GrGLProgramEffects> fColorEffects; | |
86 SkAutoTUnref<GrGLProgramEffects> fCoverageEffects; | |
87 UniformHandles fUniformHandles; | |
88 bool fHasVertexShader; | |
89 int fTexCoordSetCnt; | |
90 GrGLuint fProgramID; | |
91 }; | 66 }; |
92 | 67 |
93 static bool GenProgram(GrGpuGL* gpu, | 68 // This uses an allocator rather than array so that the GrGLShaderVars don't
move in memory |
94 GrGLProgramDataManager* pdman, | 69 // after they are inserted. Users of GrGLShaderBuilder get refs to the vars
and ptrs to their |
95 const GrGLProgramDesc& desc, | 70 // name strings. Otherwise, we'd have to hand out copies. |
96 const GrEffectStage* inColorStages[], | 71 typedef GrTAllocator<UniformInfo> UniformInfoArray; |
97 const GrEffectStage* inCoverageStages[], | 72 |
98 GenProgramOutput* output); | 73 /** Generates a shader program. |
| 74 * |
| 75 * The program implements what is specified in the stages given as input. |
| 76 * After successful generation, the builder result objects are available |
| 77 * to be used. |
| 78 * @return true if generation was successful. |
| 79 */ |
| 80 bool genProgram(const GrEffectStage* inColorStages[], |
| 81 const GrEffectStage* inCoverageStages[]); |
| 82 |
| 83 // Below are the results of the shader generation. |
| 84 |
| 85 GrGLProgramEffects* getColorEffects() const { SkASSERT(fProgramID); return f
ColorEffects.get(); } |
| 86 GrGLProgramEffects* getCoverageEffects() const { SkASSERT(fProgramID); retur
n fCoverageEffects.get(); } |
| 87 const BuiltinUniformHandles& getBuiltinUniformHandles() const { |
| 88 SkASSERT(fProgramID); |
| 89 return fUniformHandles; |
| 90 } |
| 91 GrGLuint getProgramID() const { SkASSERT(fProgramID); return fProgramID; } |
| 92 bool hasVertexShader() const { SkASSERT(fProgramID); return fHasVertexShader
; } |
| 93 int getTexCoordSetCount() const { SkASSERT(fProgramID); return fTexCoordSetC
nt; } |
| 94 const UniformInfoArray& getUniformInfos() const { return fUniforms; } |
99 | 95 |
100 virtual ~GrGLShaderBuilder() {} | 96 virtual ~GrGLShaderBuilder() {} |
101 | 97 |
102 /** | 98 /** |
103 * Use of these features may require a GLSL extension to be enabled. Shaders
may not compile | 99 * Use of these features may require a GLSL extension to be enabled. Shaders
may not compile |
104 * if code is added that uses one of these features without calling enableFe
ature() | 100 * if code is added that uses one of these features without calling enableFe
ature() |
105 */ | 101 */ |
106 enum GLSLFeature { | 102 enum GLSLFeature { |
107 kStandardDerivatives_GLSLFeature = 0, | 103 kStandardDerivatives_GLSLFeature = 0, |
108 | 104 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 const char** outName = NULL
) { | 183 const char** outName = NULL
) { |
188 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNon
Array, outName); | 184 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNon
Array, outName); |
189 } | 185 } |
190 GrGLProgramDataManager::UniformHandle addUniformArray(uint32_t visibility, | 186 GrGLProgramDataManager::UniformHandle addUniformArray(uint32_t visibility, |
191 GrSLType type, | 187 GrSLType type, |
192 const char* name, | 188 const char* name, |
193 int arrayCount, | 189 int arrayCount, |
194 const char** outName =
NULL); | 190 const char** outName =
NULL); |
195 | 191 |
196 const GrGLShaderVar& getUniformVariable(GrGLProgramDataManager::UniformHandl
e u) const { | 192 const GrGLShaderVar& getUniformVariable(GrGLProgramDataManager::UniformHandl
e u) const { |
197 return fProgramDataManager->getBuilderUniform(fUniforms, u).fVariable; | 193 return fUniforms[u.toShaderBuilderIndex()].fVariable; |
198 } | 194 } |
199 | 195 |
200 /** | 196 /** |
201 * Shortcut for getUniformVariable(u).c_str() | 197 * Shortcut for getUniformVariable(u).c_str() |
202 */ | 198 */ |
203 const char* getUniformCStr(GrGLProgramDataManager::UniformHandle u) const { | 199 const char* getUniformCStr(GrGLProgramDataManager::UniformHandle u) const { |
204 return this->getUniformVariable(u).c_str(); | 200 return this->getUniformVariable(u).c_str(); |
205 } | 201 } |
206 | 202 |
207 /** | 203 /** |
(...skipping 26 matching lines...) Expand all Loading... |
234 } | 230 } |
235 | 231 |
236 ~FSBlock() { | 232 ~FSBlock() { |
237 fBuilder->fsCodeAppend("\t}\n"); | 233 fBuilder->fsCodeAppend("\t}\n"); |
238 } | 234 } |
239 private: | 235 private: |
240 GrGLShaderBuilder* fBuilder; | 236 GrGLShaderBuilder* fBuilder; |
241 }; | 237 }; |
242 | 238 |
243 protected: | 239 protected: |
244 GrGLShaderBuilder(GrGpuGL*, GrGLProgramDataManager*, const GrGLProgramDesc&)
; | 240 GrGLShaderBuilder(GrGpuGL*, const GrGLProgramDesc&); |
245 | 241 |
246 GrGpuGL* gpu() const { return fGpu; } | 242 GrGpuGL* gpu() const { return fGpu; } |
247 | 243 |
248 const GrGLProgramDesc& desc() const { return fDesc; } | 244 const GrGLProgramDesc& desc() const { return fDesc; } |
249 | 245 |
250 /** Add input/output variable declarations (i.e. 'varying') to the fragment
shader. */ | 246 /** Add input/output variable declarations (i.e. 'varying') to the fragment
shader. */ |
251 GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); } | 247 GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); } |
252 | 248 |
253 // Helper for emitEffects(). | 249 // Helper for emitEffects(). |
254 void createAndEmitEffects(GrGLProgramEffectsBuilder*, | 250 void createAndEmitEffects(GrGLProgramEffectsBuilder*, |
255 const GrEffectStage* effectStages[], | 251 const GrEffectStage* effectStages[], |
256 int effectCnt, | 252 int effectCnt, |
257 const GrGLProgramDesc::EffectKeyProvider&, | 253 const GrGLProgramDesc::EffectKeyProvider&, |
258 GrGLSLExpr4* inOutFSColor); | 254 GrGLSLExpr4* inOutFSColor); |
259 | 255 |
260 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix | 256 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix |
261 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're | 257 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're |
262 // generating stage code. | 258 // generating stage code. |
263 void nameVariable(SkString* out, char prefix, const char* name); | 259 void nameVariable(SkString* out, char prefix, const char* name); |
264 | 260 |
265 virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>
* shaderIds) const; | 261 virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>
* shaderIds) const; |
266 | 262 |
267 virtual void bindProgramLocations(GrGLuint programId) const; | 263 virtual void bindProgramLocations(GrGLuint programId); |
| 264 void resolveProgramLocations(GrGLuint programId); |
268 | 265 |
269 void appendDecls(const VarArray&, SkString*) const; | 266 void appendDecls(const VarArray&, SkString*) const; |
270 void appendUniformDecls(ShaderVisibility, SkString*) const; | 267 void appendUniformDecls(ShaderVisibility, SkString*) const; |
271 | 268 |
272 const GenProgramOutput& getOutput() const { return fOutput; } | 269 SkAutoTUnref<GrGLProgramEffects> fColorEffects; |
273 | 270 SkAutoTUnref<GrGLProgramEffects> fCoverageEffects; |
274 GenProgramOutput fOutput; | 271 BuiltinUniformHandles fUniformHandles; |
275 | 272 bool fHasVertexShader; |
| 273 int fTexCoordSetCnt; |
| 274 GrGLuint fProgramID; |
276 private: | 275 private: |
277 class CodeStage : SkNoncopyable { | 276 class CodeStage : SkNoncopyable { |
278 public: | 277 public: |
279 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {} | 278 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {} |
280 | 279 |
281 bool inStageCode() const { | 280 bool inStageCode() const { |
282 this->validate(); | 281 this->validate(); |
283 return NULL != fEffectStage; | 282 return NULL != fEffectStage; |
284 } | 283 } |
285 | 284 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 int fSavedIndex; | 317 int fSavedIndex; |
319 const GrEffectStage* fSavedEffectStage; | 318 const GrEffectStage* fSavedEffectStage; |
320 }; | 319 }; |
321 private: | 320 private: |
322 void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurre
ntIndex)); } | 321 void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurre
ntIndex)); } |
323 int fNextIndex; | 322 int fNextIndex; |
324 int fCurrentIndex; | 323 int fCurrentIndex; |
325 const GrEffectStage* fEffectStage; | 324 const GrEffectStage* fEffectStage; |
326 } fCodeStage; | 325 } fCodeStage; |
327 | 326 |
328 bool genProgram(const GrEffectStage* colorStages[], const GrEffectStage* cov
erageStages[]); | |
329 | |
330 /** | 327 /** |
331 * The base class will emit the fragment code that precedes the per-effect c
ode and then call | 328 * The base class will emit the fragment code that precedes the per-effect c
ode and then call |
332 * this function. The subclass can use it to insert additional fragment code
that should | 329 * this function. The subclass can use it to insert additional fragment code
that should |
333 * execute before the effects' code and/or emit other shaders (e.g. geometry
, vertex). | 330 * execute before the effects' code and/or emit other shaders (e.g. geometry
, vertex). |
334 * | 331 * |
335 * The subclass can modify the initial color or coverage | 332 * The subclass can modify the initial color or coverage |
336 */ | 333 */ |
337 virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage
) = 0; | 334 virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage
) = 0; |
338 | 335 |
339 /** | 336 /** |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 }; | 385 }; |
389 | 386 |
390 enum { | 387 enum { |
391 kNoFragPosRead_FragPosKey = 0, // The fragment positition wil
l not be needed. | 388 kNoFragPosRead_FragPosKey = 0, // The fragment positition wil
l not be needed. |
392 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to t
op-left. | 389 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to t
op-left. |
393 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to b
ottom-left. | 390 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to b
ottom-left. |
394 }; | 391 }; |
395 | 392 |
396 const GrGLProgramDesc& fDesc; | 393 const GrGLProgramDesc& fDesc; |
397 GrGpuGL* fGpu; | 394 GrGpuGL* fGpu; |
398 SkAutoTUnref<GrGLProgramDataManager> fProgramDataManager; | |
399 uint32_t fFSFeaturesAddedMask; | 395 uint32_t fFSFeaturesAddedMask; |
400 SkString fFSFunctions; | 396 SkString fFSFunctions; |
401 SkString fFSExtensions; | 397 SkString fFSExtensions; |
402 VarArray fFSInputs; | 398 VarArray fFSInputs; |
403 VarArray fFSOutputs; | 399 VarArray fFSOutputs; |
404 GrGLProgramDataManager::BuilderUniformArray fUniforms; | 400 UniformInfoArray fUniforms; |
405 | 401 |
406 SkString fFSCode; | 402 SkString fFSCode; |
407 | 403 |
408 bool fSetupFragPosition; | 404 bool fSetupFragPosition; |
409 bool fTopLeftFragPosRead; | 405 bool fTopLeftFragPosRead; |
410 | 406 |
411 bool fHasCustomColorOutput; | 407 bool fHasCustomColorOutput; |
412 bool fHasSecondaryOutput; | 408 bool fHasSecondaryOutput; |
413 }; | 409 }; |
414 | 410 |
415 //////////////////////////////////////////////////////////////////////////////// | 411 //////////////////////////////////////////////////////////////////////////////// |
416 | 412 |
417 class GrGLFullShaderBuilder : public GrGLShaderBuilder { | 413 class GrGLFullShaderBuilder : public GrGLShaderBuilder { |
418 public: | 414 public: |
419 GrGLFullShaderBuilder(GrGpuGL*, GrGLProgramDataManager*, const GrGLProgramDe
sc&); | 415 GrGLFullShaderBuilder(GrGpuGL*, const GrGLProgramDesc&); |
420 | 416 |
421 /** | 417 /** |
422 * Called by GrGLEffects to add code to one of the shaders. | 418 * Called by GrGLEffects to add code to one of the shaders. |
423 */ | 419 */ |
424 void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { | 420 void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { |
425 va_list args; | 421 va_list args; |
426 va_start(args, format); | 422 va_start(args, format); |
427 fVSCode.appendVAList(format, args); | 423 fVSCode.appendVAList(format, args); |
428 va_end(args); | 424 va_end(args); |
429 } | 425 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effect
Stages[], | 462 virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effect
Stages[], |
467 int effectCnt, | 463 int effectCnt, |
468 const GrGLProgramDesc::Effe
ctKeyProvider&, | 464 const GrGLProgramDesc::Effe
ctKeyProvider&, |
469 GrGLSLExpr4* inOutFSColor)
SK_OVERRIDE; | 465 GrGLSLExpr4* inOutFSColor)
SK_OVERRIDE; |
470 | 466 |
471 virtual void emitCodeAfterEffects() SK_OVERRIDE; | 467 virtual void emitCodeAfterEffects() SK_OVERRIDE; |
472 | 468 |
473 virtual bool compileAndAttachShaders(GrGLuint programId, | 469 virtual bool compileAndAttachShaders(GrGLuint programId, |
474 SkTDArray<GrGLuint>* shaderIds) const S
K_OVERRIDE; | 470 SkTDArray<GrGLuint>* shaderIds) const S
K_OVERRIDE; |
475 | 471 |
476 virtual void bindProgramLocations(GrGLuint programId) const SK_OVERRIDE; | 472 virtual void bindProgramLocations(GrGLuint programId) SK_OVERRIDE; |
477 | 473 |
478 VarArray fVSAttrs; | 474 VarArray fVSAttrs; |
479 VarArray fVSOutputs; | 475 VarArray fVSOutputs; |
480 VarArray fGSInputs; | 476 VarArray fGSInputs; |
481 VarArray fGSOutputs; | 477 VarArray fGSOutputs; |
482 | 478 |
483 SkString fVSCode; | 479 SkString fVSCode; |
484 | 480 |
485 struct AttributePair { | 481 struct AttributePair { |
486 void set(int index, const SkString& name) { | 482 void set(int index, const SkString& name) { |
487 fIndex = index; fName = name; | 483 fIndex = index; fName = name; |
488 } | 484 } |
489 int fIndex; | 485 int fIndex; |
490 SkString fName; | 486 SkString fName; |
491 }; | 487 }; |
492 SkSTArray<10, AttributePair, true> fEffectAttributes; | 488 SkSTArray<10, AttributePair, true> fEffectAttributes; |
493 | 489 |
494 GrGLShaderVar* fPositionVar; | 490 GrGLShaderVar* fPositionVar; |
495 GrGLShaderVar* fLocalCoordsVar; | 491 GrGLShaderVar* fLocalCoordsVar; |
496 | 492 |
497 typedef GrGLShaderBuilder INHERITED; | 493 typedef GrGLShaderBuilder INHERITED; |
498 }; | 494 }; |
499 | 495 |
500 //////////////////////////////////////////////////////////////////////////////// | 496 //////////////////////////////////////////////////////////////////////////////// |
501 | 497 |
502 class GrGLFragmentOnlyShaderBuilder : public GrGLShaderBuilder { | 498 class GrGLFragmentOnlyShaderBuilder : public GrGLShaderBuilder { |
503 public: | 499 public: |
504 GrGLFragmentOnlyShaderBuilder(GrGpuGL*, GrGLProgramDataManager*, const GrGLP
rogramDesc&); | 500 GrGLFragmentOnlyShaderBuilder(GrGpuGL*, const GrGLProgramDesc&); |
505 | 501 |
506 int addTexCoordSets(int count); | 502 int addTexCoordSets(int count); |
507 | 503 |
508 private: | 504 private: |
509 virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage
) SK_OVERRIDE {} | 505 virtual void emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage
) SK_OVERRIDE {} |
510 | 506 |
511 virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effect
Stages[], | 507 virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effect
Stages[], |
512 int effectCnt, | 508 int effectCnt, |
513 const GrGLProgramDesc::Effe
ctKeyProvider&, | 509 const GrGLProgramDesc::Effe
ctKeyProvider&, |
514 GrGLSLExpr4* inOutFSColor)
SK_OVERRIDE; | 510 GrGLSLExpr4* inOutFSColor)
SK_OVERRIDE; |
515 | 511 |
516 virtual void emitCodeAfterEffects() SK_OVERRIDE {} | 512 virtual void emitCodeAfterEffects() SK_OVERRIDE {} |
517 | 513 |
518 typedef GrGLShaderBuilder INHERITED; | 514 typedef GrGLShaderBuilder INHERITED; |
519 }; | 515 }; |
520 | 516 |
521 #endif | 517 #endif |
OLD | NEW |