| 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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 const GrGLProgramDesc& desc) | 96 const GrGLProgramDesc& desc) |
| 97 : fUniforms(kVarsPerBlock) | 97 : fUniforms(kVarsPerBlock) |
| 98 , fVSAttrs(kVarsPerBlock) | 98 , fVSAttrs(kVarsPerBlock) |
| 99 , fVSOutputs(kVarsPerBlock) | 99 , fVSOutputs(kVarsPerBlock) |
| 100 , fGSInputs(kVarsPerBlock) | 100 , fGSInputs(kVarsPerBlock) |
| 101 , fGSOutputs(kVarsPerBlock) | 101 , fGSOutputs(kVarsPerBlock) |
| 102 , fFSInputs(kVarsPerBlock) | 102 , fFSInputs(kVarsPerBlock) |
| 103 , fFSOutputs(kMaxFSOutputs) | 103 , fFSOutputs(kMaxFSOutputs) |
| 104 , fCtxInfo(ctxInfo) | 104 , fCtxInfo(ctxInfo) |
| 105 , fUniformManager(uniformManager) | 105 , fUniformManager(uniformManager) |
| 106 , fCurrentStageIdx(kNonStageIdx) | |
| 107 , fFSFeaturesAddedMask(0) | 106 , fFSFeaturesAddedMask(0) |
| 108 #if GR_GL_EXPERIMENTAL_GS | 107 #if GR_GL_EXPERIMENTAL_GS |
| 109 , fUsesGS(desc.fExperimentalGS) | 108 , fUsesGS(desc.fExperimentalGS) |
| 110 #else | 109 #else |
| 111 , fUsesGS(false) | 110 , fUsesGS(false) |
| 112 #endif | 111 #endif |
| 113 , fSetupFragPosition(false) | 112 , fSetupFragPosition(false) |
| 114 , fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle) | 113 , fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle) |
| 115 , fDstCopyTopLeftUniform (GrGLUniformManager::kInvalidUniformHandle) | 114 , fDstCopyTopLeftUniform (GrGLUniformManager::kInvalidUniformHandle) |
| 116 , fDstCopyScaleUniform (GrGLUniformManager::kInvalidUniformHandle) { | 115 , fDstCopyScaleUniform (GrGLUniformManager::kInvalidUniformHandle) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 } | 207 } |
| 209 } | 208 } |
| 210 | 209 |
| 211 void GrGLShaderBuilder::addFSFeature(uint32_t featureBit, const char* extensionN
ame) { | 210 void GrGLShaderBuilder::addFSFeature(uint32_t featureBit, const char* extensionN
ame) { |
| 212 if (!(featureBit & fFSFeaturesAddedMask)) { | 211 if (!(featureBit & fFSFeaturesAddedMask)) { |
| 213 fFSExtensions.appendf("#extension %s: require\n", extensionName); | 212 fFSExtensions.appendf("#extension %s: require\n", extensionName); |
| 214 fFSFeaturesAddedMask |= featureBit; | 213 fFSFeaturesAddedMask |= featureBit; |
| 215 } | 214 } |
| 216 } | 215 } |
| 217 | 216 |
| 217 void GrGLShaderBuilder::nameVariable(SkString* out, char prefix, const char* nam
e) { |
| 218 if ('\0' == prefix) { |
| 219 *out = name; |
| 220 } else { |
| 221 out->printf("%c%s", prefix, name); |
| 222 } |
| 223 if (fCodeStage.inStageCode()) { |
| 224 if (out->endsWith('_')) { |
| 225 // Names containing "__" are reserved. |
| 226 out->append("x"); |
| 227 } |
| 228 out->appendf("_Stage%d", fCodeStage.stageIndex()); |
| 229 } |
| 230 } |
| 231 |
| 218 const char* GrGLShaderBuilder::dstColor() { | 232 const char* GrGLShaderBuilder::dstColor() { |
| 219 static const char kFBFetchColorName[] = "gl_LastFragData[0]"; | 233 static const char kFBFetchColorName[] = "gl_LastFragData[0]"; |
| 220 GrGLCaps::FBFetchType fetchType = fCtxInfo.caps()->fbFetchType(); | 234 GrGLCaps::FBFetchType fetchType = fCtxInfo.caps()->fbFetchType(); |
| 221 if (GrGLCaps::kEXT_FBFetchType == fetchType) { | 235 if (GrGLCaps::kEXT_FBFetchType == fetchType) { |
| 222 SkAssertResult(this->enablePrivateFeature(kEXTShaderFramebufferFetch_GLS
LPrivateFeature)); | 236 SkAssertResult(this->enablePrivateFeature(kEXTShaderFramebufferFetch_GLS
LPrivateFeature)); |
| 223 return kFBFetchColorName; | 237 return kFBFetchColorName; |
| 224 } else if (GrGLCaps::kNV_FBFetchType == fetchType) { | 238 } else if (GrGLCaps::kNV_FBFetchType == fetchType) { |
| 225 SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSL
PrivateFeature)); | 239 SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSL
PrivateFeature)); |
| 226 return kFBFetchColorName; | 240 return kFBFetchColorName; |
| 227 } else if (fDstCopySampler.isInitialized()) { | 241 } else if (fDstCopySampler.isInitialized()) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 | 371 |
| 358 BuilderUniform& uni = fUniforms.push_back(); | 372 BuilderUniform& uni = fUniforms.push_back(); |
| 359 UniformHandle h = index_to_handle(fUniforms.count() - 1); | 373 UniformHandle h = index_to_handle(fUniforms.count() - 1); |
| 360 GR_DEBUGCODE(UniformHandle h2 =) | 374 GR_DEBUGCODE(UniformHandle h2 =) |
| 361 fUniformManager.appendUniform(type, count); | 375 fUniformManager.appendUniform(type, count); |
| 362 // We expect the uniform manager to initially have no uniforms and that all
uniforms are added | 376 // We expect the uniform manager to initially have no uniforms and that all
uniforms are added |
| 363 // by this function. Therefore, the handles should match. | 377 // by this function. Therefore, the handles should match. |
| 364 GrAssert(h2 == h); | 378 GrAssert(h2 == h); |
| 365 uni.fVariable.setType(type); | 379 uni.fVariable.setType(type); |
| 366 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); | 380 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); |
| 367 SkString* uniName = uni.fVariable.accessName(); | 381 this->nameVariable(uni.fVariable.accessName(), 'u', name); |
| 368 if (kNonStageIdx == fCurrentStageIdx) { | |
| 369 uniName->printf("u%s", name); | |
| 370 } else { | |
| 371 uniName->printf("u%s%d", name, fCurrentStageIdx); | |
| 372 } | |
| 373 uni.fVariable.setArrayCount(count); | 382 uni.fVariable.setArrayCount(count); |
| 374 uni.fVisibility = visibility; | 383 uni.fVisibility = visibility; |
| 375 | 384 |
| 376 // If it is visible in both the VS and FS, the precision must match. | 385 // If it is visible in both the VS and FS, the precision must match. |
| 377 // We declare a default FS precision, but not a default VS. So set the var | 386 // We declare a default FS precision, but not a default VS. So set the var |
| 378 // to use the default FS precision. | 387 // to use the default FS precision. |
| 379 if ((kVertex_ShaderType | kFragment_ShaderType) == visibility) { | 388 if ((kVertex_ShaderType | kFragment_ShaderType) == visibility) { |
| 380 // the fragment and vertex precisions must match | 389 // the fragment and vertex precisions must match |
| 381 uni.fVariable.setPrecision(kDefaultFragmentPrecision); | 390 uni.fVariable.setPrecision(kDefaultFragmentPrecision); |
| 382 } | 391 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 408 return true; | 417 return true; |
| 409 } | 418 } |
| 410 | 419 |
| 411 void GrGLShaderBuilder::addVarying(GrSLType type, | 420 void GrGLShaderBuilder::addVarying(GrSLType type, |
| 412 const char* name, | 421 const char* name, |
| 413 const char** vsOutName, | 422 const char** vsOutName, |
| 414 const char** fsInName) { | 423 const char** fsInName) { |
| 415 fVSOutputs.push_back(); | 424 fVSOutputs.push_back(); |
| 416 fVSOutputs.back().setType(type); | 425 fVSOutputs.back().setType(type); |
| 417 fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); | 426 fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); |
| 418 if (kNonStageIdx == fCurrentStageIdx) { | 427 this->nameVariable(fVSOutputs.back().accessName(), 'v', name); |
| 419 fVSOutputs.back().accessName()->printf("v%s", name); | 428 |
| 420 } else { | |
| 421 fVSOutputs.back().accessName()->printf("v%s%d", name, fCurrentStageIdx); | |
| 422 } | |
| 423 if (vsOutName) { | 429 if (vsOutName) { |
| 424 *vsOutName = fVSOutputs.back().getName().c_str(); | 430 *vsOutName = fVSOutputs.back().getName().c_str(); |
| 425 } | 431 } |
| 426 // input to FS comes either from VS or GS | 432 // input to FS comes either from VS or GS |
| 427 const SkString* fsName; | 433 const SkString* fsName; |
| 428 if (fUsesGS) { | 434 if (fUsesGS) { |
| 429 // if we have a GS take each varying in as an array | 435 // if we have a GS take each varying in as an array |
| 430 // and output as non-array. | 436 // and output as non-array. |
| 431 fGSInputs.push_back(); | 437 fGSInputs.push_back(); |
| 432 fGSInputs.back().setType(type); | 438 fGSInputs.back().setType(type); |
| 433 fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier)
; | 439 fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier)
; |
| 434 fGSInputs.back().setUnsizedArray(); | 440 fGSInputs.back().setUnsizedArray(); |
| 435 *fGSInputs.back().accessName() = fVSOutputs.back().getName(); | 441 *fGSInputs.back().accessName() = fVSOutputs.back().getName(); |
| 436 fGSOutputs.push_back(); | 442 fGSOutputs.push_back(); |
| 437 fGSOutputs.back().setType(type); | 443 fGSOutputs.back().setType(type); |
| 438 fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifie
r); | 444 fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifie
r); |
| 439 if (kNonStageIdx == fCurrentStageIdx) { | 445 this->nameVariable(fGSOutputs.back().accessName(), 'g', name); |
| 440 fGSOutputs.back().accessName()->printf("g%s", name); | |
| 441 } else { | |
| 442 fGSOutputs.back().accessName()->printf("g%s%d", name, fCurrentStageI
dx); | |
| 443 } | |
| 444 fsName = fGSOutputs.back().accessName(); | 446 fsName = fGSOutputs.back().accessName(); |
| 445 } else { | 447 } else { |
| 446 fsName = fVSOutputs.back().accessName(); | 448 fsName = fVSOutputs.back().accessName(); |
| 447 } | 449 } |
| 448 fFSInputs.push_back(); | 450 fFSInputs.push_back(); |
| 449 fFSInputs.back().setType(type); | 451 fFSInputs.back().setType(type); |
| 450 fFSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier); | 452 fFSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier); |
| 451 fFSInputs.back().setName(*fsName); | 453 fFSInputs.back().setName(*fsName); |
| 452 if (fsInName) { | 454 if (fsInName) { |
| 453 *fsInName = fsName->c_str(); | 455 *fsInName = fsName->c_str(); |
| 454 } | 456 } |
| 455 } | 457 } |
| 456 | 458 |
| 457 const char* GrGLShaderBuilder::fragmentPosition() { | 459 const char* GrGLShaderBuilder::fragmentPosition() { |
| 458 #if 1 | 460 #if 1 |
| 459 if (fCtxInfo.caps()->fragCoordConventionsSupport()) { | 461 if (fCtxInfo.caps()->fragCoordConventionsSupport()) { |
| 460 if (!fSetupFragPosition) { | 462 if (!fSetupFragPosition) { |
| 461 SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSL
PrivateFeature)); | 463 SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSL
PrivateFeature)); |
| 462 fFSInputs.push_back().set(kVec4f_GrSLType, | 464 fFSInputs.push_back().set(kVec4f_GrSLType, |
| 463 GrGLShaderVar::kIn_TypeModifier, | 465 GrGLShaderVar::kIn_TypeModifier, |
| 464 "gl_FragCoord", | 466 "gl_FragCoord", |
| 465 GrGLShaderVar::kDefault_Precision, | 467 GrGLShaderVar::kDefault_Precision, |
| 466 GrGLShaderVar::kUpperLeft_Origin); | 468 GrGLShaderVar::kUpperLeft_Origin); |
| 467 fSetupFragPosition = true; | 469 fSetupFragPosition = true; |
| 468 } | 470 } |
| 469 return "gl_FragCoord"; | 471 return "gl_FragCoord"; |
| 470 } else { | 472 } else { |
| 471 static const char* kCoordName = "fragCoordYDown"; | 473 static const char* kCoordName = "fragCoordYDown"; |
| 472 if (!fSetupFragPosition) { | 474 if (!fSetupFragPosition) { |
| 475 // temporarily change the stage index because we're inserting non-st
age code. |
| 476 CodeStage::AutoStageRestore csar(&fCodeStage, NULL); |
| 477 |
| 473 GrAssert(GrGLUniformManager::kInvalidUniformHandle == fRTHeightUnifo
rm); | 478 GrAssert(GrGLUniformManager::kInvalidUniformHandle == fRTHeightUnifo
rm); |
| 474 const char* rtHeightName; | 479 const char* rtHeightName; |
| 475 | 480 |
| 476 // temporarily change the stage index because we're inserting a unif
orm whose name | |
| 477 // shouldn't be mangled to be stage-specific. | |
| 478 int oldStageIdx = fCurrentStageIdx; | |
| 479 fCurrentStageIdx = kNonStageIdx; | |
| 480 fRTHeightUniform = this->addUniform(kFragment_ShaderType, | 481 fRTHeightUniform = this->addUniform(kFragment_ShaderType, |
| 481 kFloat_GrSLType, | 482 kFloat_GrSLType, |
| 482 "RTHeight", | 483 "RTHeight", |
| 483 &rtHeightName); | 484 &rtHeightName); |
| 484 fCurrentStageIdx = oldStageIdx; | |
| 485 | 485 |
| 486 this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_Fra
gCoord.y, gl_FragCoord.zw);\n", | 486 this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_Fra
gCoord.y, gl_FragCoord.zw);\n", |
| 487 kCoordName, rtHeightName); | 487 kCoordName, rtHeightName); |
| 488 fSetupFragPosition = true; | 488 fSetupFragPosition = true; |
| 489 } | 489 } |
| 490 GrAssert(GrGLUniformManager::kInvalidUniformHandle != fRTHeightUniform); | 490 GrAssert(GrGLUniformManager::kInvalidUniformHandle != fRTHeightUniform); |
| 491 return kCoordName; | 491 return kCoordName; |
| 492 } | 492 } |
| 493 #else | 493 #else |
| 494 // This is the path we'll need to use once we have support for TopLeft | 494 // This is the path we'll need to use once we have support for TopLeft |
| (...skipping 12 matching lines...) Expand all Loading... |
| 507 | 507 |
| 508 void GrGLShaderBuilder::emitFunction(ShaderType shader, | 508 void GrGLShaderBuilder::emitFunction(ShaderType shader, |
| 509 GrSLType returnType, | 509 GrSLType returnType, |
| 510 const char* name, | 510 const char* name, |
| 511 int argCnt, | 511 int argCnt, |
| 512 const GrGLShaderVar* args, | 512 const GrGLShaderVar* args, |
| 513 const char* body, | 513 const char* body, |
| 514 SkString* outName) { | 514 SkString* outName) { |
| 515 GrAssert(kFragment_ShaderType == shader); | 515 GrAssert(kFragment_ShaderType == shader); |
| 516 fFSFunctions.append(GrGLSLTypeString(returnType)); | 516 fFSFunctions.append(GrGLSLTypeString(returnType)); |
| 517 if (kNonStageIdx != fCurrentStageIdx) { | 517 this->nameVariable(outName, '\0', name); |
| 518 outName->printf("%s_%d", name, fCurrentStageIdx); | |
| 519 } else { | |
| 520 *outName = name; | |
| 521 } | |
| 522 fFSFunctions.appendf(" %s", outName->c_str()); | 518 fFSFunctions.appendf(" %s", outName->c_str()); |
| 523 fFSFunctions.append("("); | 519 fFSFunctions.append("("); |
| 524 for (int i = 0; i < argCnt; ++i) { | 520 for (int i = 0; i < argCnt; ++i) { |
| 525 args[i].appendDecl(fCtxInfo, &fFSFunctions); | 521 args[i].appendDecl(fCtxInfo, &fFSFunctions); |
| 526 if (i < argCnt - 1) { | 522 if (i < argCnt - 1) { |
| 527 fFSFunctions.append(", "); | 523 fFSFunctions.append(", "); |
| 528 } | 524 } |
| 529 } | 525 } |
| 530 fFSFunctions.append(") {\n"); | 526 fFSFunctions.append(") {\n"); |
| 531 fFSFunctions.append(body); | 527 fFSFunctions.append(body); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 shaderStr->append(fFSCode); | 612 shaderStr->append(fFSCode); |
| 617 shaderStr->append("}\n"); | 613 shaderStr->append("}\n"); |
| 618 break; | 614 break; |
| 619 } | 615 } |
| 620 } | 616 } |
| 621 | 617 |
| 622 void GrGLShaderBuilder::finished(GrGLuint programID) { | 618 void GrGLShaderBuilder::finished(GrGLuint programID) { |
| 623 fUniformManager.getUniformLocations(programID, fUniforms); | 619 fUniformManager.getUniformLocations(programID, fUniforms); |
| 624 } | 620 } |
| 625 | 621 |
| 626 GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect( | 622 void GrGLShaderBuilder::emitEffects( |
| 627 const GrEffectStage& stage, | 623 const GrEffectStage* effectStages[], |
| 628 GrGLEffect::EffectKey key, | 624 const GrBackendEffectFactory::EffectKey effectKeys[], |
| 629 const char* fsInColor, | 625 int effectCnt, |
| 630 const char* fsOutColor, | 626 SkString* fsInOutColor, |
| 631 SkTArray<GrGLUniformManager::UniformHandle, true
>* samplerHandles) { | 627 GrSLConstantVec* fsInOutColorKnownValue, |
| 632 GrAssert(NULL != stage.getEffect()); | 628 SkTArray<GrGLUniformManager::UniformHandle, true>* effec
tSamplerHandles[], |
| 629 GrGLEffect* glEffects[]) { |
| 630 bool effectEmitted = false; |
| 633 | 631 |
| 634 const GrEffectRef& effect = *stage.getEffect(); | 632 SkString inColor = *fsInOutColor; |
| 635 int numTextures = effect->numTextures(); | 633 SkString outColor; |
| 636 SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers; | |
| 637 textureSamplers.push_back_n(numTextures); | |
| 638 for (int i = 0; i < numTextures; ++i) { | |
| 639 textureSamplers[i].init(this, &effect->textureAccess(i), i); | |
| 640 samplerHandles->push_back(textureSamplers[i].fSamplerUniform); | |
| 641 } | |
| 642 GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords()); | |
| 643 | 634 |
| 644 int numAttributes = stage.getVertexAttribIndexCount(); | 635 for (int e = 0; e < effectCnt; ++e) { |
| 645 const int* attributeIndices = stage.getVertexAttribIndices(); | 636 if (NULL == effectStages[e] || GrGLEffect::kNoEffectKey == effectKeys[e]
) { |
| 646 SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames; | 637 continue; |
| 647 for (int i = 0; i < numAttributes; ++i) { | 638 } |
| 648 SkString attributeName("aAttr"); | |
| 649 attributeName.appendS32(attributeIndices[i]); | |
| 650 | 639 |
| 651 if (this->addAttribute(effect->vertexAttribType(i), attributeName.c_str(
))) { | 640 GrAssert(NULL != effectStages[e]->getEffect()); |
| 652 fEffectAttributes.push_back().set(attributeIndices[i], attributeName
); | 641 const GrEffectStage& stage = *effectStages[e]; |
| 642 const GrEffectRef& effect = *stage.getEffect(); |
| 643 |
| 644 CodeStage::AutoStageRestore csar(&fCodeStage, &stage); |
| 645 |
| 646 int numTextures = effect->numTextures(); |
| 647 SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers; |
| 648 textureSamplers.push_back_n(numTextures); |
| 649 for (int t = 0; t < numTextures; ++t) { |
| 650 textureSamplers[t].init(this, &effect->textureAccess(t), t); |
| 651 effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUnifor
m); |
| 653 } | 652 } |
| 653 GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords()); |
| 654 |
| 655 int numAttributes = stage.getVertexAttribIndexCount(); |
| 656 const int* attributeIndices = stage.getVertexAttribIndices(); |
| 657 SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames; |
| 658 for (int a = 0; a < numAttributes; ++a) { |
| 659 // TODO: Make addAttribute mangle the name. |
| 660 SkString attributeName("aAttr"); |
| 661 attributeName.appendS32(attributeIndices[a]); |
| 662 if (this->addAttribute(effect->vertexAttribType(a), attributeName.c_
str())) { |
| 663 fEffectAttributes.push_back().set(attributeIndices[a], attribute
Name); |
| 664 } |
| 665 } |
| 666 |
| 667 glEffects[e] = effect->getFactory().createGLInstance(drawEffect); |
| 668 |
| 669 if (kZeros_GrSLConstantVec == *fsInOutColorKnownValue) { |
| 670 // Effects have no way to communicate zeros, they treat an empty str
ing as ones. |
| 671 this->nameVariable(&inColor, '\0', "input"); |
| 672 this->fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZero
sVecf(4)); |
| 673 } |
| 674 |
| 675 // create var to hold stage result |
| 676 this->nameVariable(&outColor, '\0', "output"); |
| 677 this->fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); |
| 678 |
| 679 // Enclose custom code in a block to avoid namespace conflicts |
| 680 SkString openBrace; |
| 681 openBrace.printf("\t{ // Stage %d: %s\n", fCodeStage.stageIndex(), glEff
ects[e]->name()); |
| 682 this->fVSCode.append(openBrace); |
| 683 this->fFSCode.append(openBrace); |
| 684 |
| 685 glEffects[e]->emitCode(this, |
| 686 drawEffect, |
| 687 effectKeys[e], |
| 688 outColor.c_str(), |
| 689 inColor.isEmpty() ? NULL : inColor.c_str(), |
| 690 textureSamplers); |
| 691 this->fVSCode.append("\t}\n"); |
| 692 this->fFSCode.append("\t}\n"); |
| 693 |
| 694 inColor = outColor; |
| 695 *fsInOutColorKnownValue = kNone_GrSLConstantVec; |
| 696 effectEmitted = true; |
| 654 } | 697 } |
| 655 | 698 |
| 656 GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect); | 699 if (effectEmitted) { |
| 657 | 700 *fsInOutColor = outColor; |
| 658 // Enclose custom code in a block to avoid namespace conflicts | 701 } |
| 659 this->fVSCode.appendf("\t{ // %s\n", glEffect->name()); | |
| 660 this->fFSCode.appendf("\t{ // %s \n", glEffect->name()); | |
| 661 | |
| 662 glEffect->emitCode(this, | |
| 663 drawEffect, | |
| 664 key, | |
| 665 fsOutColor, | |
| 666 fsInColor, | |
| 667 textureSamplers); | |
| 668 this->fVSCode.appendf("\t}\n"); | |
| 669 this->fFSCode.appendf("\t}\n"); | |
| 670 | |
| 671 return glEffect; | |
| 672 } | 702 } |
| 673 | 703 |
| 674 const SkString* GrGLShaderBuilder::getEffectAttributeName(int attributeIndex) co
nst { | 704 const SkString* GrGLShaderBuilder::getEffectAttributeName(int attributeIndex) co
nst { |
| 675 const AttributePair* attribEnd = this->getEffectAttributes().end(); | 705 const AttributePair* attribEnd = this->getEffectAttributes().end(); |
| 676 for (const AttributePair* attrib = this->getEffectAttributes().begin(); | 706 for (const AttributePair* attrib = this->getEffectAttributes().begin(); |
| 677 attrib != attribEnd; | 707 attrib != attribEnd; |
| 678 ++attrib) { | 708 ++attrib) { |
| 679 if (attrib->fIndex == attributeIndex) { | 709 if (attrib->fIndex == attributeIndex) { |
| 680 return &attrib->fName; | 710 return &attrib->fName; |
| 681 } | 711 } |
| 682 } | 712 } |
| 683 | 713 |
| 684 return NULL; | 714 return NULL; |
| 685 } | 715 } |
| OLD | NEW |