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 #include "gl/GrGLShaderBuilder.h" | 8 #include "gl/GrGLShaderBuilder.h" |
9 #include "gl/GrGLProgram.h" | 9 #include "gl/GrGLProgram.h" |
10 #include "gl/GrGLUniformHandle.h" | 10 #include "gl/GrGLUniformHandle.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 | 22 |
23 typedef GrGLUniformManager::UniformHandle UniformHandle; | 23 typedef GrGLUniformManager::UniformHandle UniformHandle; |
24 /////////////////////////////////////////////////////////////////////////////// | 24 /////////////////////////////////////////////////////////////////////////////// |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen)
{ | 28 inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen)
{ |
29 if (kVec2f_GrSLType == type) { | 29 if (kVec2f_GrSLType == type) { |
30 return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D"; | 30 return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D"; |
31 } else { | 31 } else { |
32 GrAssert(kVec3f_GrSLType == type); | 32 SkASSERT(kVec3f_GrSLType == type); |
33 return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj
"; | 33 return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj
"; |
34 } | 34 } |
35 } | 35 } |
36 | 36 |
37 /** | 37 /** |
38 * Do we need to either map r,g,b->a or a->r. configComponentMask indicates whic
h channels are | 38 * Do we need to either map r,g,b->a or a->r. configComponentMask indicates whic
h channels are |
39 * present in the texture's config. swizzleComponentMask indicates the channels
present in the | 39 * present in the texture's config. swizzleComponentMask indicates the channels
present in the |
40 * shader swizzle. | 40 * shader swizzle. |
41 */ | 41 */ |
42 inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps, | 42 inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps, |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 default: | 286 default: |
287 GrCrash("Invalid shader type"); | 287 GrCrash("Invalid shader type"); |
288 } | 288 } |
289 string->append(str); | 289 string->append(str); |
290 } | 290 } |
291 | 291 |
292 void GrGLShaderBuilder::appendTextureLookup(SkString* out, | 292 void GrGLShaderBuilder::appendTextureLookup(SkString* out, |
293 const GrGLShaderBuilder::TextureSamp
ler& sampler, | 293 const GrGLShaderBuilder::TextureSamp
ler& sampler, |
294 const char* coordName, | 294 const char* coordName, |
295 GrSLType varyingType) const { | 295 GrSLType varyingType) const { |
296 GrAssert(NULL != coordName); | 296 SkASSERT(NULL != coordName); |
297 | 297 |
298 out->appendf("%s(%s, %s)", | 298 out->appendf("%s(%s, %s)", |
299 sample_function_name(varyingType, fCtxInfo.glslGeneration()), | 299 sample_function_name(varyingType, fCtxInfo.glslGeneration()), |
300 this->getUniformCStr(sampler.fSamplerUniform), | 300 this->getUniformCStr(sampler.fSamplerUniform), |
301 coordName); | 301 coordName); |
302 append_swizzle(out, sampler, *fCtxInfo.caps()); | 302 append_swizzle(out, sampler, *fCtxInfo.caps()); |
303 } | 303 } |
304 | 304 |
305 void GrGLShaderBuilder::appendTextureLookup(ShaderType type, | 305 void GrGLShaderBuilder::appendTextureLookup(ShaderType type, |
306 const GrGLShaderBuilder::TextureSamp
ler& sampler, | 306 const GrGLShaderBuilder::TextureSamp
ler& sampler, |
307 const char* coordName, | 307 const char* coordName, |
308 GrSLType varyingType) { | 308 GrSLType varyingType) { |
309 GrAssert(kFragment_ShaderType == type); | 309 SkASSERT(kFragment_ShaderType == type); |
310 this->appendTextureLookup(&fFSCode, sampler, coordName, varyingType); | 310 this->appendTextureLookup(&fFSCode, sampler, coordName, varyingType); |
311 } | 311 } |
312 | 312 |
313 void GrGLShaderBuilder::appendTextureLookupAndModulate( | 313 void GrGLShaderBuilder::appendTextureLookupAndModulate( |
314 ShaderType type, | 314 ShaderType type, |
315 const char* modulation, | 315 const char* modulation, |
316 const GrGLShaderBuilder::TextureSamp
ler& sampler, | 316 const GrGLShaderBuilder::TextureSamp
ler& sampler, |
317 const char* coordName, | 317 const char* coordName, |
318 GrSLType varyingType) { | 318 GrSLType varyingType) { |
319 GrAssert(kFragment_ShaderType == type); | 319 SkASSERT(kFragment_ShaderType == type); |
320 SkString lookup; | 320 SkString lookup; |
321 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); | 321 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); |
322 GrGLSLModulatef<4>(&fFSCode, modulation, lookup.c_str()); | 322 GrGLSLModulatef<4>(&fFSCode, modulation, lookup.c_str()); |
323 } | 323 } |
324 | 324 |
325 GrBackendEffectFactory::EffectKey GrGLShaderBuilder::KeyForTextureAccess( | 325 GrBackendEffectFactory::EffectKey GrGLShaderBuilder::KeyForTextureAccess( |
326 const GrTextureAcces
s& access, | 326 const GrTextureAcces
s& access, |
327 const GrGLCaps& caps
) { | 327 const GrGLCaps& caps
) { |
328 uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture(
)->config()); | 328 uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture(
)->config()); |
329 if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizz
leMask())) { | 329 if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizz
leMask())) { |
330 return 1; | 330 return 1; |
331 } else { | 331 } else { |
332 return 0; | 332 return 0; |
333 } | 333 } |
334 } | 334 } |
335 | 335 |
336 GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture*
dstCopy, | 336 GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture*
dstCopy, |
337 const GrGLCaps& c
aps) { | 337 const GrGLCaps& c
aps) { |
338 uint32_t key = kYesDstRead_DstReadKeyBit; | 338 uint32_t key = kYesDstRead_DstReadKeyBit; |
339 if (GrGLCaps::kNone_FBFetchType != caps.fbFetchType()) { | 339 if (GrGLCaps::kNone_FBFetchType != caps.fbFetchType()) { |
340 return key; | 340 return key; |
341 } | 341 } |
342 GrAssert(NULL != dstCopy); | 342 SkASSERT(NULL != dstCopy); |
343 if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->confi
g())) { | 343 if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->confi
g())) { |
344 // The fact that the config is alpha-only must be considered when genera
ting code. | 344 // The fact that the config is alpha-only must be considered when genera
ting code. |
345 key |= kUseAlphaConfig_DstReadKeyBit; | 345 key |= kUseAlphaConfig_DstReadKeyBit; |
346 } | 346 } |
347 if (kTopLeft_GrSurfaceOrigin == dstCopy->origin()) { | 347 if (kTopLeft_GrSurfaceOrigin == dstCopy->origin()) { |
348 key |= kTopLeftOrigin_DstReadKeyBit; | 348 key |= kTopLeftOrigin_DstReadKeyBit; |
349 } | 349 } |
350 GrAssert(static_cast<DstReadKey>(key) == key); | 350 SkASSERT(static_cast<DstReadKey>(key) == key); |
351 return static_cast<DstReadKey>(key); | 351 return static_cast<DstReadKey>(key); |
352 } | 352 } |
353 | 353 |
354 GrGLShaderBuilder::FragPosKey GrGLShaderBuilder::KeyForFragmentPosition(const Gr
RenderTarget* dst, | 354 GrGLShaderBuilder::FragPosKey GrGLShaderBuilder::KeyForFragmentPosition(const Gr
RenderTarget* dst, |
355 const Gr
GLCaps&) { | 355 const Gr
GLCaps&) { |
356 if (kTopLeft_GrSurfaceOrigin == dst->origin()) { | 356 if (kTopLeft_GrSurfaceOrigin == dst->origin()) { |
357 return kTopLeftFragPosRead_FragPosKey; | 357 return kTopLeftFragPosRead_FragPosKey; |
358 } else { | 358 } else { |
359 return kBottomLeftFragPosRead_FragPosKey; | 359 return kBottomLeftFragPosRead_FragPosKey; |
360 } | 360 } |
(...skipping 14 matching lines...) Expand all Loading... |
375 static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE
, GR_GL_ALPHA }; | 375 static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE
, GR_GL_ALPHA }; |
376 return gStraight; | 376 return gStraight; |
377 } | 377 } |
378 } | 378 } |
379 | 379 |
380 GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t vi
sibility, | 380 GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t vi
sibility, |
381 GrSLType ty
pe, | 381 GrSLType ty
pe, |
382 const char*
name, | 382 const char*
name, |
383 int count, | 383 int count, |
384 const char*
* outName) { | 384 const char*
* outName) { |
385 GrAssert(name && strlen(name)); | 385 SkASSERT(name && strlen(name)); |
386 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_ShaderType | kFr
agment_ShaderType); | 386 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_ShaderType | kFr
agment_ShaderType); |
387 GrAssert(0 == (~kVisibilityMask & visibility)); | 387 SkASSERT(0 == (~kVisibilityMask & visibility)); |
388 GrAssert(0 != visibility); | 388 SkASSERT(0 != visibility); |
389 | 389 |
390 BuilderUniform& uni = fUniforms.push_back(); | 390 BuilderUniform& uni = fUniforms.push_back(); |
391 UniformHandle h = GrGLUniformManager::UniformHandle::CreateFromUniformIndex(
fUniforms.count() - 1); | 391 UniformHandle h = GrGLUniformManager::UniformHandle::CreateFromUniformIndex(
fUniforms.count() - 1); |
392 GR_DEBUGCODE(UniformHandle h2 =) | 392 GR_DEBUGCODE(UniformHandle h2 =) |
393 fUniformManager.appendUniform(type, count); | 393 fUniformManager.appendUniform(type, count); |
394 // We expect the uniform manager to initially have no uniforms and that all
uniforms are added | 394 // We expect the uniform manager to initially have no uniforms and that all
uniforms are added |
395 // by this function. Therefore, the handles should match. | 395 // by this function. Therefore, the handles should match. |
396 GrAssert(h2 == h); | 396 SkASSERT(h2 == h); |
397 uni.fVariable.setType(type); | 397 uni.fVariable.setType(type); |
398 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); | 398 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); |
399 this->nameVariable(uni.fVariable.accessName(), 'u', name); | 399 this->nameVariable(uni.fVariable.accessName(), 'u', name); |
400 uni.fVariable.setArrayCount(count); | 400 uni.fVariable.setArrayCount(count); |
401 uni.fVisibility = visibility; | 401 uni.fVisibility = visibility; |
402 | 402 |
403 // If it is visible in both the VS and FS, the precision must match. | 403 // If it is visible in both the VS and FS, the precision must match. |
404 // We declare a default FS precision, but not a default VS. So set the var | 404 // We declare a default FS precision, but not a default VS. So set the var |
405 // to use the default FS precision. | 405 // to use the default FS precision. |
406 if ((kVertex_ShaderType | kFragment_ShaderType) == visibility) { | 406 if ((kVertex_ShaderType | kFragment_ShaderType) == visibility) { |
407 // the fragment and vertex precisions must match | 407 // the fragment and vertex precisions must match |
408 uni.fVariable.setPrecision(kDefaultFragmentPrecision); | 408 uni.fVariable.setPrecision(kDefaultFragmentPrecision); |
409 } | 409 } |
410 | 410 |
411 if (NULL != outName) { | 411 if (NULL != outName) { |
412 *outName = uni.fVariable.c_str(); | 412 *outName = uni.fVariable.c_str(); |
413 } | 413 } |
414 | 414 |
415 return h; | 415 return h; |
416 } | 416 } |
417 | 417 |
418 bool GrGLShaderBuilder::addAttribute(GrSLType type, | 418 bool GrGLShaderBuilder::addAttribute(GrSLType type, |
419 const char* name) { | 419 const char* name) { |
420 for (int i = 0; i < fVSAttrs.count(); ++i) { | 420 for (int i = 0; i < fVSAttrs.count(); ++i) { |
421 const GrGLShaderVar& attr = fVSAttrs[i]; | 421 const GrGLShaderVar& attr = fVSAttrs[i]; |
422 // if attribute already added, don't add it again | 422 // if attribute already added, don't add it again |
423 if (attr.getName().equals(name)) { | 423 if (attr.getName().equals(name)) { |
424 GrAssert(attr.getType() == type); | 424 SkASSERT(attr.getType() == type); |
425 return false; | 425 return false; |
426 } | 426 } |
427 } | 427 } |
428 fVSAttrs.push_back().set(type, | 428 fVSAttrs.push_back().set(type, |
429 GrGLShaderVar::kAttribute_TypeModifier, | 429 GrGLShaderVar::kAttribute_TypeModifier, |
430 name); | 430 name); |
431 return true; | 431 return true; |
432 } | 432 } |
433 | 433 |
434 void GrGLShaderBuilder::addVarying(GrSLType type, | 434 void GrGLShaderBuilder::addVarying(GrSLType type, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 GrGLShaderVar::kUpperLeft_Origin); | 498 GrGLShaderVar::kUpperLeft_Origin); |
499 fSetupFragPosition = true; | 499 fSetupFragPosition = true; |
500 } | 500 } |
501 return "gl_FragCoord"; | 501 return "gl_FragCoord"; |
502 } else { | 502 } else { |
503 static const char* kCoordName = "fragCoordYDown"; | 503 static const char* kCoordName = "fragCoordYDown"; |
504 if (!fSetupFragPosition) { | 504 if (!fSetupFragPosition) { |
505 // temporarily change the stage index because we're inserting non-st
age code. | 505 // temporarily change the stage index because we're inserting non-st
age code. |
506 CodeStage::AutoStageRestore csar(&fCodeStage, NULL); | 506 CodeStage::AutoStageRestore csar(&fCodeStage, NULL); |
507 | 507 |
508 GrAssert(!fRTHeightUniform.isValid()); | 508 SkASSERT(!fRTHeightUniform.isValid()); |
509 const char* rtHeightName; | 509 const char* rtHeightName; |
510 | 510 |
511 fRTHeightUniform = this->addUniform(kFragment_ShaderType, | 511 fRTHeightUniform = this->addUniform(kFragment_ShaderType, |
512 kFloat_GrSLType, | 512 kFloat_GrSLType, |
513 "RTHeight", | 513 "RTHeight", |
514 &rtHeightName); | 514 &rtHeightName); |
515 | 515 |
516 this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_Fra
gCoord.y, gl_FragCoord.zw);\n", | 516 this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_Fra
gCoord.y, gl_FragCoord.zw);\n", |
517 kCoordName, rtHeightName); | 517 kCoordName, rtHeightName); |
518 fSetupFragPosition = true; | 518 fSetupFragPosition = true; |
519 } | 519 } |
520 GrAssert(fRTHeightUniform.isValid()); | 520 SkASSERT(fRTHeightUniform.isValid()); |
521 return kCoordName; | 521 return kCoordName; |
522 } | 522 } |
523 } | 523 } |
524 | 524 |
525 | 525 |
526 void GrGLShaderBuilder::emitFunction(ShaderType shader, | 526 void GrGLShaderBuilder::emitFunction(ShaderType shader, |
527 GrSLType returnType, | 527 GrSLType returnType, |
528 const char* name, | 528 const char* name, |
529 int argCnt, | 529 int argCnt, |
530 const GrGLShaderVar* args, | 530 const GrGLShaderVar* args, |
531 const char* body, | 531 const char* body, |
532 SkString* outName) { | 532 SkString* outName) { |
533 GrAssert(kFragment_ShaderType == shader); | 533 SkASSERT(kFragment_ShaderType == shader); |
534 fFSFunctions.append(GrGLSLTypeString(returnType)); | 534 fFSFunctions.append(GrGLSLTypeString(returnType)); |
535 this->nameVariable(outName, '\0', name); | 535 this->nameVariable(outName, '\0', name); |
536 fFSFunctions.appendf(" %s", outName->c_str()); | 536 fFSFunctions.appendf(" %s", outName->c_str()); |
537 fFSFunctions.append("("); | 537 fFSFunctions.append("("); |
538 for (int i = 0; i < argCnt; ++i) { | 538 for (int i = 0; i < argCnt; ++i) { |
539 args[i].appendDecl(fCtxInfo, &fFSFunctions); | 539 args[i].appendDecl(fCtxInfo, &fFSFunctions); |
540 if (i < argCnt - 1) { | 540 if (i < argCnt - 1) { |
541 fFSFunctions.append(", "); | 541 fFSFunctions.append(", "); |
542 } | 542 } |
543 } | 543 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 break; | 616 break; |
617 case kFragment_ShaderType: | 617 case kFragment_ShaderType: |
618 *shaderStr = version; | 618 *shaderStr = version; |
619 shaderStr->append(fFSExtensions); | 619 shaderStr->append(fFSExtensions); |
620 append_default_precision_qualifier(kDefaultFragmentPrecision, | 620 append_default_precision_qualifier(kDefaultFragmentPrecision, |
621 fCtxInfo.binding(), | 621 fCtxInfo.binding(), |
622 shaderStr); | 622 shaderStr); |
623 this->appendUniformDecls(kFragment_ShaderType, shaderStr); | 623 this->appendUniformDecls(kFragment_ShaderType, shaderStr); |
624 this->appendDecls(fFSInputs, shaderStr); | 624 this->appendDecls(fFSInputs, shaderStr); |
625 // We shouldn't have declared outputs on 1.10 | 625 // We shouldn't have declared outputs on 1.10 |
626 GrAssert(k110_GrGLSLGeneration != fCtxInfo.glslGeneration() || fFSOu
tputs.empty()); | 626 SkASSERT(k110_GrGLSLGeneration != fCtxInfo.glslGeneration() || fFSOu
tputs.empty()); |
627 this->appendDecls(fFSOutputs, shaderStr); | 627 this->appendDecls(fFSOutputs, shaderStr); |
628 shaderStr->append(fFSFunctions); | 628 shaderStr->append(fFSFunctions); |
629 shaderStr->append("void main() {\n"); | 629 shaderStr->append("void main() {\n"); |
630 shaderStr->append(fFSCode); | 630 shaderStr->append(fFSCode); |
631 shaderStr->append("}\n"); | 631 shaderStr->append("}\n"); |
632 break; | 632 break; |
633 } | 633 } |
634 } | 634 } |
635 | 635 |
636 void GrGLShaderBuilder::finished(GrGLuint programID) { | 636 void GrGLShaderBuilder::finished(GrGLuint programID) { |
637 fUniformManager.getUniformLocations(programID, fUniforms); | 637 fUniformManager.getUniformLocations(programID, fUniforms); |
638 } | 638 } |
639 | 639 |
640 void GrGLShaderBuilder::emitEffects( | 640 void GrGLShaderBuilder::emitEffects( |
641 const GrEffectStage* effectStages[], | 641 const GrEffectStage* effectStages[], |
642 const GrBackendEffectFactory::EffectKey effectKeys[], | 642 const GrBackendEffectFactory::EffectKey effectKeys[], |
643 int effectCnt, | 643 int effectCnt, |
644 SkString* fsInOutColor, | 644 SkString* fsInOutColor, |
645 GrSLConstantVec* fsInOutColorKnownValue, | 645 GrSLConstantVec* fsInOutColorKnownValue, |
646 SkTArray<GrGLUniformManager::UniformHandle, true>* effec
tSamplerHandles[], | 646 SkTArray<GrGLUniformManager::UniformHandle, true>* effec
tSamplerHandles[], |
647 GrGLEffect* glEffects[]) { | 647 GrGLEffect* glEffects[]) { |
648 bool effectEmitted = false; | 648 bool effectEmitted = false; |
649 | 649 |
650 SkString inColor = *fsInOutColor; | 650 SkString inColor = *fsInOutColor; |
651 SkString outColor; | 651 SkString outColor; |
652 | 652 |
653 for (int e = 0; e < effectCnt; ++e) { | 653 for (int e = 0; e < effectCnt; ++e) { |
654 GrAssert(NULL != effectStages[e] && NULL != effectStages[e]->getEffect()
); | 654 SkASSERT(NULL != effectStages[e] && NULL != effectStages[e]->getEffect()
); |
655 const GrEffectStage& stage = *effectStages[e]; | 655 const GrEffectStage& stage = *effectStages[e]; |
656 const GrEffectRef& effect = *stage.getEffect(); | 656 const GrEffectRef& effect = *stage.getEffect(); |
657 | 657 |
658 CodeStage::AutoStageRestore csar(&fCodeStage, &stage); | 658 CodeStage::AutoStageRestore csar(&fCodeStage, &stage); |
659 | 659 |
660 int numTextures = effect->numTextures(); | 660 int numTextures = effect->numTextures(); |
661 SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers; | 661 SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers; |
662 textureSamplers.push_back_n(numTextures); | 662 textureSamplers.push_back_n(numTextures); |
663 for (int t = 0; t < numTextures; ++t) { | 663 for (int t = 0; t < numTextures; ++t) { |
664 textureSamplers[t].init(this, &effect->textureAccess(t), t); | 664 textureSamplers[t].init(this, &effect->textureAccess(t), t); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 for (const AttributePair* attrib = this->getEffectAttributes().begin(); | 720 for (const AttributePair* attrib = this->getEffectAttributes().begin(); |
721 attrib != attribEnd; | 721 attrib != attribEnd; |
722 ++attrib) { | 722 ++attrib) { |
723 if (attrib->fIndex == attributeIndex) { | 723 if (attrib->fIndex == attributeIndex) { |
724 return &attrib->fName; | 724 return &attrib->fName; |
725 } | 725 } |
726 } | 726 } |
727 | 727 |
728 return NULL; | 728 return NULL; |
729 } | 729 } |
OLD | NEW |