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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 } | 89 } |
90 | 90 |
91 uint32_t fConfigComponentMask; | 91 uint32_t fConfigComponentMask; |
92 char fSwizzle[5]; | 92 char fSwizzle[5]; |
93 GrGLUniformManager::UniformHandle fSamplerUniform; | 93 GrGLUniformManager::UniformHandle fSamplerUniform; |
94 | 94 |
95 friend class GrGLShaderBuilder; // to call init(). | 95 friend class GrGLShaderBuilder; // to call init(). |
96 }; | 96 }; |
97 | 97 |
98 typedef SkTArray<TextureSampler> TextureSamplerArray; | 98 typedef SkTArray<TextureSampler> TextureSamplerArray; |
| 99 typedef GrTAllocator<GrGLShaderVar> VarArray; |
99 | 100 |
100 enum ShaderVisibility { | 101 enum ShaderVisibility { |
101 kVertex_Visibility = 0x1, | 102 kVertex_Visibility = 0x1, |
102 kGeometry_Visibility = 0x2, | 103 kGeometry_Visibility = 0x2, |
103 kFragment_Visibility = 0x4, | 104 kFragment_Visibility = 0x4, |
104 }; | 105 }; |
105 | 106 |
106 GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, const GrGLPro
gramDesc&); | 107 GrGLShaderBuilder(const GrGLContextInfo&, |
| 108 GrGLUniformManager&, |
| 109 const GrGLProgramDesc&, |
| 110 bool needsVertexShader); |
107 | 111 |
108 /** | 112 /** |
109 * Use of these features may require a GLSL extension to be enabled. Shaders
may not compile | 113 * Use of these features may require a GLSL extension to be enabled. Shaders
may not compile |
110 * if code is added that uses one of these features without calling enableFe
ature() | 114 * if code is added that uses one of these features without calling enableFe
ature() |
111 */ | 115 */ |
112 enum GLSLFeature { | 116 enum GLSLFeature { |
113 kStandardDerivatives_GLSLFeature = 0, | 117 kStandardDerivatives_GLSLFeature = 0, |
114 | 118 |
115 kLastGLSLFeature = kStandardDerivatives_GLSLFeature | 119 kLastGLSLFeature = kStandardDerivatives_GLSLFeature |
116 }; | 120 }; |
117 | 121 |
118 /** | 122 /** |
119 * If the feature is supported then true is returned and any necessary #exte
nsion declarations | 123 * If the feature is supported then true is returned and any necessary #exte
nsion declarations |
120 * are added to the shaders. If the feature is not supported then false will
be returned. | 124 * are added to the shaders. If the feature is not supported then false will
be returned. |
121 */ | 125 */ |
122 bool enableFeature(GLSLFeature); | 126 bool enableFeature(GLSLFeature); |
123 | 127 |
124 /** | 128 /** |
125 * Called by GrGLEffects to add code to one of the shaders. | 129 * Called by GrGLEffects to add code the fragment shader. |
126 */ | 130 */ |
127 void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { | |
128 va_list args; | |
129 va_start(args, format); | |
130 fVSCode.appendf(format, args); | |
131 va_end(args); | |
132 } | |
133 | |
134 void gsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { | |
135 va_list args; | |
136 va_start(args, format); | |
137 fGSCode.appendf(format, args); | |
138 va_end(args); | |
139 } | |
140 | |
141 void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { | 131 void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { |
142 va_list args; | 132 va_list args; |
143 va_start(args, format); | 133 va_start(args, format); |
144 fFSCode.appendf(format, args); | 134 fFSCode.appendf(format, args); |
145 va_end(args); | 135 va_end(args); |
146 } | 136 } |
147 | 137 |
148 void vsCodeAppend(const char* str) { fVSCode.append(str); } | |
149 void gsCodeAppend(const char* str) { fGSCode.append(str); } | |
150 void fsCodeAppend(const char* str) { fFSCode.append(str); } | 138 void fsCodeAppend(const char* str) { fFSCode.append(str); } |
151 | 139 |
152 /** Appends a 2D texture sample with projection if necessary. coordType must
either be Vec2f or | 140 /** Appends a 2D texture sample with projection if necessary. coordType must
either be Vec2f or |
153 Vec3f. The latter is interpreted as projective texture coords. The vec l
ength and swizzle | 141 Vec3f. The latter is interpreted as projective texture coords. The vec l
ength and swizzle |
154 order of the result depends on the GrTextureAccess associated with the T
extureSampler. */ | 142 order of the result depends on the GrTextureAccess associated with the T
extureSampler. */ |
155 void appendTextureLookup(SkString* out, | 143 void appendTextureLookup(SkString* out, |
156 const TextureSampler&, | 144 const TextureSampler&, |
157 const char* coordName, | 145 const char* coordName, |
158 GrSLType coordType = kVec2f_GrSLType) const; | 146 GrSLType coordType = kVec2f_GrSLType) const; |
159 | 147 |
(...skipping 13 matching lines...) Expand all Loading... |
173 GrSLType coordType = kVec2f_GrSLType); | 161 GrSLType coordType = kVec2f_GrSLType); |
174 | 162 |
175 /** Emits a helper function outside of main() in the fragment shader. */ | 163 /** Emits a helper function outside of main() in the fragment shader. */ |
176 void fsEmitFunction(GrSLType returnType, | 164 void fsEmitFunction(GrSLType returnType, |
177 const char* name, | 165 const char* name, |
178 int argCnt, | 166 int argCnt, |
179 const GrGLShaderVar* args, | 167 const GrGLShaderVar* args, |
180 const char* body, | 168 const char* body, |
181 SkString* outName); | 169 SkString* outName); |
182 | 170 |
| 171 /** Add input/output variable declarations (i.e. 'varying') to the fragment
shader. */ |
| 172 GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); } |
| 173 GrGLShaderVar& fsOutputAppend() { return fFSOutputs.push_back(); } |
| 174 GrGLShaderVar& fsInputAppend(const GrGLShaderVar& var) { return fFSInputs.pu
sh_back(var); } |
| 175 GrGLShaderVar& fsOutputAppend(const GrGLShaderVar& var) { return fFSOutputs.
push_back(var); } |
| 176 |
183 /** Generates a EffectKey for the shader code based on the texture access pa
rameters and the | 177 /** Generates a EffectKey for the shader code based on the texture access pa
rameters and the |
184 capabilities of the GL context. This is useful for keying the shader pr
ograms that may | 178 capabilities of the GL context. This is useful for keying the shader pr
ograms that may |
185 have multiple representations, based on the type/format of textures used
. */ | 179 have multiple representations, based on the type/format of textures used
. */ |
186 static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTexture
Access&, | 180 static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTexture
Access&, |
187 const GrGLCaps&
); | 181 const GrGLCaps&
); |
188 | 182 |
189 typedef uint8_t DstReadKey; | 183 typedef uint8_t DstReadKey; |
190 typedef uint8_t FragPosKey; | 184 typedef uint8_t FragPosKey; |
191 | 185 |
192 /** Returns a key for adding code to read the copy-of-dst color in service
of effects that | 186 /** Returns a key for adding code to read the copy-of-dst color in service
of effects that |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 return fUniformManager.getBuilderUniform(fUniforms, u).fVariable; | 220 return fUniformManager.getBuilderUniform(fUniforms, u).fVariable; |
227 } | 221 } |
228 | 222 |
229 /** | 223 /** |
230 * Shortcut for getUniformVariable(u).c_str() | 224 * Shortcut for getUniformVariable(u).c_str() |
231 */ | 225 */ |
232 const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const { | 226 const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const { |
233 return this->getUniformVariable(u).c_str(); | 227 return this->getUniformVariable(u).c_str(); |
234 } | 228 } |
235 | 229 |
236 /** Add a vertex attribute to the current program that is passed in from the
vertex data. | |
237 Returns false if the attribute was already there, true otherwise. */ | |
238 bool addAttribute(GrSLType type, const char* name); | |
239 | |
240 /** Add a varying variable to the current program to pass values between vert
ex and fragment | |
241 shaders. If the last two parameters are non-NULL, they are filled in wit
h the name | |
242 generated. */ | |
243 void addVarying(GrSLType type, | |
244 const char* name, | |
245 const char** vsOutName = NULL, | |
246 const char** fsInName = NULL); | |
247 | |
248 /** Returns a variable name that represents the position of the fragment in
the FS. The position | 230 /** Returns a variable name that represents the position of the fragment in
the FS. The position |
249 is in device space (e.g. 0,0 is the top left and pixel centers are at ha
lf-integers). */ | 231 is in device space (e.g. 0,0 is the top left and pixel centers are at ha
lf-integers). */ |
250 const char* fragmentPosition(); | 232 const char* fragmentPosition(); |
251 | 233 |
252 /** Returns a vertex attribute that represents the vertex position in the VS
. This is the | |
253 pre-matrix position and is commonly used by effects to compute texture c
oords via a matrix. | |
254 */ | |
255 const GrGLShaderVar& positionAttribute() const { return *fPositionVar; } | |
256 | |
257 /** Returns a vertex attribute that represents the local coords in the VS. T
his may be the same | |
258 as positionAttribute() or it may not be. It depends upon whether the ren
dering code | |
259 specified explicit local coords or not in the GrDrawState. */ | |
260 const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar;
} | |
261 | |
262 /** Returns the color of the destination pixel. This may be NULL if no effec
t advertised | 234 /** Returns the color of the destination pixel. This may be NULL if no effec
t advertised |
263 that it will read the destination. */ | 235 that it will read the destination. */ |
264 const char* dstColor(); | 236 const char* dstColor(); |
265 | 237 |
266 /** | 238 /** |
267 * Are explicit local coordinates provided as input to the vertex shader. | |
268 */ | |
269 bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVa
r); } | |
270 | |
271 /** | |
272 * Interfaces used by GrGLProgram. | 239 * Interfaces used by GrGLProgram. |
273 * TODO: Hide these from the GrEffects using friend or splitting this into t
wo related classes. | 240 * TODO: Hide these from the GrEffects using friend or splitting this into t
wo related classes. |
274 * Also, GrGLProgram's shader string construction should be moved to this cl
ass. | 241 * Also, GrGLProgram's shader string construction should be moved to this cl
ass. |
275 */ | 242 */ |
276 | 243 |
277 /** Called after building is complete to get the final shader string. */ | 244 /** Called after building is complete to get the final shader string. To acc
es the vertex |
278 void vsGetShader(SkString*) const; | 245 and geometry shaders, use the VertexBuilder. */ |
279 void gsGetShader(SkString*) const; | |
280 void fsGetShader(SkString*) const; | 246 void fsGetShader(SkString*) const; |
281 | 247 |
282 /** | 248 /** |
283 * Adds code for effects. effectStages contains the effects to add. effectKe
ys[i] is the key | 249 * Adds code for effects. effectStages contains the effects to add. effectKe
ys[i] is the key |
284 * generated from effectStages[i]. An entry in effectStages can be NULL, in
which case it is | 250 * generated from effectStages[i]. An entry in effectStages can be NULL, in
which case it is |
285 * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey th
en it is skipped. | 251 * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey th
en it is skipped. |
286 * inOutFSColor specifies the input color to the first stage and is updated
to be the | 252 * inOutFSColor specifies the input color to the first stage and is updated
to be the |
287 * output color of the last stage. fsInOutColorKnownValue specifies whether
the input color | 253 * output color of the last stage. fsInOutColorKnownValue specifies whether
the input color |
288 * has a known constant value and is updated to refer to the status of the o
utput color. | 254 * has a known constant value and is updated to refer to the status of the o
utput color. |
289 * The handles to texture samplers for effectStage[i] are added to effectSam
plerHandles[i]. The | 255 * The handles to texture samplers for effectStage[i] are added to effectSam
plerHandles[i]. The |
(...skipping 12 matching lines...) Expand all Loading... |
302 GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const { | 268 GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const { |
303 return fDstCopyTopLeftUniform; | 269 return fDstCopyTopLeftUniform; |
304 } | 270 } |
305 GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const { | 271 GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const { |
306 return fDstCopyScaleUniform; | 272 return fDstCopyScaleUniform; |
307 } | 273 } |
308 GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const { | 274 GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const { |
309 return fDstCopySampler.fSamplerUniform; | 275 return fDstCopySampler.fSamplerUniform; |
310 } | 276 } |
311 | 277 |
312 struct AttributePair { | 278 /** Helper class used to build the vertex and geometry shaders. This functio
nality |
313 void set(int index, const SkString& name) { | 279 is kept separate from the rest of GrGLShaderBuilder to allow for shaders
programs |
314 fIndex = index; fName = name; | 280 that only use the fragment shader. */ |
| 281 class VertexBuilder { |
| 282 public: |
| 283 VertexBuilder(GrGLShaderBuilder* parent, const GrGLProgramDesc&); |
| 284 |
| 285 /** |
| 286 * Called by GrGLEffects to add code to one of the shaders. |
| 287 */ |
| 288 void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { |
| 289 va_list args; |
| 290 va_start(args, format); |
| 291 fVSCode.appendf(format, args); |
| 292 va_end(args); |
315 } | 293 } |
316 int fIndex; | 294 |
317 SkString fName; | 295 void gsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { |
| 296 va_list args; |
| 297 va_start(args, format); |
| 298 fGSCode.appendf(format, args); |
| 299 va_end(args); |
| 300 } |
| 301 |
| 302 void vsCodeAppend(const char* str) { fVSCode.append(str); } |
| 303 void gsCodeAppend(const char* str) { fGSCode.append(str); } |
| 304 |
| 305 /** Add a vertex attribute to the current program that is passed in from
the vertex data. |
| 306 Returns false if the attribute was already there, true otherwise. */ |
| 307 bool addAttribute(GrSLType type, const char* name); |
| 308 |
| 309 /** Add a varying variable to the current program to pass values between
vertex and fragment |
| 310 shaders. If the last two parameters are non-NULL, they are filled in
with the name |
| 311 generated. */ |
| 312 void addVarying(GrSLType type, |
| 313 const char* name, |
| 314 const char** vsOutName = NULL, |
| 315 const char** fsInName = NULL); |
| 316 |
| 317 /** Returns a vertex attribute that represents the vertex position in th
e VS. This is the |
| 318 pre-matrix position and is commonly used by effects to compute textu
re coords via a matrix. |
| 319 */ |
| 320 const GrGLShaderVar& positionAttribute() const { return *fPositionVar; } |
| 321 |
| 322 /** Returns a vertex attribute that represents the local coords in the V
S. This may be the same |
| 323 as positionAttribute() or it may not be. It depends upon whether the
rendering code |
| 324 specified explicit local coords or not in the GrDrawState. */ |
| 325 const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoords
Var; } |
| 326 |
| 327 /** |
| 328 * Are explicit local coordinates provided as input to the vertex shader
. |
| 329 */ |
| 330 bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositi
onVar); } |
| 331 |
| 332 /** Called after building is complete to get the final shader string. */ |
| 333 void vsGetShader(SkString*) const; |
| 334 void gsGetShader(SkString*) const; |
| 335 |
| 336 struct AttributePair { |
| 337 void set(int index, const SkString& name) { |
| 338 fIndex = index; fName = name; |
| 339 } |
| 340 int fIndex; |
| 341 SkString fName; |
| 342 }; |
| 343 const SkTArray<AttributePair, true>& getEffectAttributes() const { |
| 344 return fEffectAttributes; |
| 345 } |
| 346 bool addEffectAttribute(int attributeIndex, GrSLType type, const SkStrin
g& name); |
| 347 const SkString* getEffectAttributeName(int attributeIndex) const; |
| 348 |
| 349 // TODO: Everything below here private. |
| 350 public: |
| 351 |
| 352 VarArray fVSAttrs; |
| 353 VarArray fVSOutputs; |
| 354 VarArray fGSInputs; |
| 355 VarArray fGSOutputs; |
| 356 SkString fGSHeader; // layout qualifiers specific to GS |
| 357 |
| 358 private: |
| 359 GrGLShaderBuilder* fParent; |
| 360 |
| 361 bool fUsesGS; |
| 362 |
| 363 SkString fVSCode; |
| 364 SkString fGSCode; |
| 365 |
| 366 SkSTArray<10, AttributePair, true> fEffectAttributes; |
| 367 |
| 368 GrGLShaderVar* fPositionVar; |
| 369 GrGLShaderVar* fLocalCoordsVar; |
318 }; | 370 }; |
319 const SkTArray<AttributePair, true>& getEffectAttributes() const { | 371 |
320 return fEffectAttributes; | 372 /** Gets the vertex builder that is used to construct the vertex and geometr
y shaders. |
321 } | 373 It may be NULL if this shader program is only meant to have a fragment s
hader. */ |
322 const SkString* getEffectAttributeName(int attributeIndex) const; | 374 VertexBuilder* getVertexBuilder() const { return fVertexBuilder.get(); } |
323 | 375 |
324 // TODO: Make this do all the compiling, linking, etc. | 376 // TODO: Make this do all the compiling, linking, etc. |
325 void finished(GrGLuint programID); | 377 void finished(GrGLuint programID); |
326 | 378 |
327 const GrGLContextInfo& ctxInfo() const { return fCtxInfo; } | 379 const GrGLContextInfo& ctxInfo() const { return fCtxInfo; } |
328 | 380 |
329 private: | 381 private: |
330 typedef GrTAllocator<GrGLShaderVar> VarArray; | |
331 | |
332 void appendDecls(const VarArray&, SkString*) const; | 382 void appendDecls(const VarArray&, SkString*) const; |
333 void appendUniformDecls(ShaderVisibility, SkString*) const; | 383 void appendUniformDecls(ShaderVisibility, SkString*) const; |
334 | 384 |
335 typedef GrGLUniformManager::BuilderUniform BuilderUniform; | 385 typedef GrGLUniformManager::BuilderUniform BuilderUniform; |
336 GrGLUniformManager::BuilderUniformArray fUniforms; | 386 GrGLUniformManager::BuilderUniformArray fUniforms; |
337 | 387 |
338 // TODO: Everything below here private. | |
339 public: | |
340 | |
341 VarArray fVSAttrs; | |
342 VarArray fVSOutputs; | |
343 VarArray fGSInputs; | |
344 VarArray fGSOutputs; | |
345 VarArray fFSInputs; | |
346 SkString fGSHeader; // layout qualifiers specific to GS | |
347 VarArray fFSOutputs; | |
348 | |
349 private: | 388 private: |
350 class CodeStage : GrNoncopyable { | 389 class CodeStage : GrNoncopyable { |
351 public: | 390 public: |
352 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {} | 391 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {} |
353 | 392 |
354 bool inStageCode() const { | 393 bool inStageCode() const { |
355 this->validate(); | 394 this->validate(); |
356 return NULL != fEffectStage; | 395 return NULL != fEffectStage; |
357 } | 396 } |
358 | 397 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 kNoFragPosRead_FragPosKey = 0, // The fragment positition wil
l not be needed. | 468 kNoFragPosRead_FragPosKey = 0, // The fragment positition wil
l not be needed. |
430 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to t
op-left. | 469 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to t
op-left. |
431 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to b
ottom-left. | 470 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to b
ottom-left. |
432 }; | 471 }; |
433 | 472 |
434 const GrGLContextInfo& fCtxInfo; | 473 const GrGLContextInfo& fCtxInfo; |
435 GrGLUniformManager& fUniformManager; | 474 GrGLUniformManager& fUniformManager; |
436 uint32_t fFSFeaturesAddedMask; | 475 uint32_t fFSFeaturesAddedMask; |
437 SkString fFSFunctions; | 476 SkString fFSFunctions; |
438 SkString fFSExtensions; | 477 SkString fFSExtensions; |
439 | 478 VarArray fFSInputs; |
440 bool fUsesGS; | 479 VarArray fFSOutputs; |
441 | 480 |
442 SkString fFSCode; | 481 SkString fFSCode; |
443 SkString fVSCode; | |
444 SkString fGSCode; | |
445 | 482 |
446 bool fSetupFragPosition; | 483 bool fSetupFragPosition; |
447 TextureSampler fDstCopySampler; | 484 TextureSampler fDstCopySampler; |
448 | 485 |
449 GrGLUniformManager::UniformHandle fRTHeightUniform; | 486 GrGLUniformManager::UniformHandle fRTHeightUniform; |
450 GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform; | 487 GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform; |
451 GrGLUniformManager::UniformHandle fDstCopyScaleUniform; | 488 GrGLUniformManager::UniformHandle fDstCopyScaleUniform; |
452 | 489 |
453 bool fTopLeftFragPosRead; | 490 bool fTopLeftFragPosRead; |
454 | 491 |
455 SkSTArray<10, AttributePair, true> fEffectAttributes; | 492 SkAutoTDelete<VertexBuilder> fVertexBuilder; |
456 | |
457 GrGLShaderVar* fPositionVar; | |
458 GrGLShaderVar* fLocalCoordsVar; | |
459 | |
460 }; | 493 }; |
461 | 494 |
462 #endif | 495 #endif |
OLD | NEW |