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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 } | 86 } |
87 | 87 |
88 } | 88 } |
89 | 89 |
90 static const char kDstCopyColorName[] = "_dstColor"; | 90 static const char kDstCopyColorName[] = "_dstColor"; |
91 | 91 |
92 /////////////////////////////////////////////////////////////////////////////// | 92 /////////////////////////////////////////////////////////////////////////////// |
93 | 93 |
94 GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, | 94 GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, |
95 GrGLUniformManager& uniformManager, | 95 GrGLUniformManager& uniformManager, |
96 const GrGLProgramDesc& desc) | 96 const GrGLProgramDesc& desc, |
| 97 bool needsVertexShader) |
97 : fUniforms(kVarsPerBlock) | 98 : fUniforms(kVarsPerBlock) |
98 , fVSAttrs(kVarsPerBlock) | |
99 , fVSOutputs(kVarsPerBlock) | |
100 , fGSInputs(kVarsPerBlock) | |
101 , fGSOutputs(kVarsPerBlock) | |
102 , fFSInputs(kVarsPerBlock) | |
103 , fFSOutputs(kMaxFSOutputs) | |
104 , fCtxInfo(ctxInfo) | 99 , fCtxInfo(ctxInfo) |
105 , fUniformManager(uniformManager) | 100 , fUniformManager(uniformManager) |
106 , fFSFeaturesAddedMask(0) | 101 , fFSFeaturesAddedMask(0) |
107 #if GR_GL_EXPERIMENTAL_GS | 102 , fFSInputs(kVarsPerBlock) |
108 , fUsesGS(SkToBool(desc.getHeader().fExperimentalGS)) | 103 , fFSOutputs(kMaxFSOutputs) |
109 #else | |
110 , fUsesGS(false) | |
111 #endif | |
112 , fSetupFragPosition(false) | 104 , fSetupFragPosition(false) |
113 , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFr
agPosKey) { | 105 , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFr
agPosKey) { |
114 | 106 |
115 const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); | 107 const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); |
116 | 108 |
117 fPositionVar = &fVSAttrs.push_back(); | 109 if (needsVertexShader) { |
118 fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "
aPosition"); | 110 fVertexBuilder.reset(SkNEW_ARGS(VertexBuilder, (this, desc))); |
119 if (-1 != header.fLocalCoordAttributeIndex) { | |
120 fLocalCoordsVar = &fVSAttrs.push_back(); | |
121 fLocalCoordsVar->set(kVec2f_GrSLType, | |
122 GrGLShaderVar::kAttribute_TypeModifier, | |
123 "aLocalCoords"); | |
124 } else { | |
125 fLocalCoordsVar = fPositionVar; | |
126 } | 111 } |
| 112 |
127 // Emit code to read the dst copy textue if necessary. | 113 // Emit code to read the dst copy textue if necessary. |
128 if (kNoDstRead_DstReadKey != header.fDstReadKey && | 114 if (kNoDstRead_DstReadKey != header.fDstReadKey && |
129 GrGLCaps::kNone_FBFetchType == ctxInfo.caps()->fbFetchType()) { | 115 GrGLCaps::kNone_FBFetchType == ctxInfo.caps()->fbFetchType()) { |
130 bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKe
y); | 116 bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKe
y); |
131 const char* dstCopyTopLeftName; | 117 const char* dstCopyTopLeftName; |
132 const char* dstCopyCoordScaleName; | 118 const char* dstCopyCoordScaleName; |
133 uint32_t configMask; | 119 uint32_t configMask; |
134 if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) { | 120 if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) { |
135 configMask = kA_GrColorComponentFlag; | 121 configMask = kA_GrColorComponentFlag; |
136 } else { | 122 } else { |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 uni.fVariable.setPrecision(kDefaultFragmentPrecision); | 354 uni.fVariable.setPrecision(kDefaultFragmentPrecision); |
369 } | 355 } |
370 | 356 |
371 if (NULL != outName) { | 357 if (NULL != outName) { |
372 *outName = uni.fVariable.c_str(); | 358 *outName = uni.fVariable.c_str(); |
373 } | 359 } |
374 | 360 |
375 return h; | 361 return h; |
376 } | 362 } |
377 | 363 |
378 bool GrGLShaderBuilder::addAttribute(GrSLType type, | |
379 const char* name) { | |
380 for (int i = 0; i < fVSAttrs.count(); ++i) { | |
381 const GrGLShaderVar& attr = fVSAttrs[i]; | |
382 // if attribute already added, don't add it again | |
383 if (attr.getName().equals(name)) { | |
384 SkASSERT(attr.getType() == type); | |
385 return false; | |
386 } | |
387 } | |
388 fVSAttrs.push_back().set(type, | |
389 GrGLShaderVar::kAttribute_TypeModifier, | |
390 name); | |
391 return true; | |
392 } | |
393 | |
394 void GrGLShaderBuilder::addVarying(GrSLType type, | |
395 const char* name, | |
396 const char** vsOutName, | |
397 const char** fsInName) { | |
398 fVSOutputs.push_back(); | |
399 fVSOutputs.back().setType(type); | |
400 fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); | |
401 this->nameVariable(fVSOutputs.back().accessName(), 'v', name); | |
402 | |
403 if (vsOutName) { | |
404 *vsOutName = fVSOutputs.back().getName().c_str(); | |
405 } | |
406 // input to FS comes either from VS or GS | |
407 const SkString* fsName; | |
408 if (fUsesGS) { | |
409 // if we have a GS take each varying in as an array | |
410 // and output as non-array. | |
411 fGSInputs.push_back(); | |
412 fGSInputs.back().setType(type); | |
413 fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier)
; | |
414 fGSInputs.back().setUnsizedArray(); | |
415 *fGSInputs.back().accessName() = fVSOutputs.back().getName(); | |
416 fGSOutputs.push_back(); | |
417 fGSOutputs.back().setType(type); | |
418 fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifie
r); | |
419 this->nameVariable(fGSOutputs.back().accessName(), 'g', name); | |
420 fsName = fGSOutputs.back().accessName(); | |
421 } else { | |
422 fsName = fVSOutputs.back().accessName(); | |
423 } | |
424 fFSInputs.push_back(); | |
425 fFSInputs.back().setType(type); | |
426 fFSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier); | |
427 fFSInputs.back().setName(*fsName); | |
428 if (fsInName) { | |
429 *fsInName = fsName->c_str(); | |
430 } | |
431 } | |
432 | |
433 const char* GrGLShaderBuilder::fragmentPosition() { | 364 const char* GrGLShaderBuilder::fragmentPosition() { |
434 if (fCodeStage.inStageCode()) { | 365 if (fCodeStage.inStageCode()) { |
435 const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect(); | 366 const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect(); |
436 if (!effect->willReadFragmentPosition()) { | 367 if (!effect->willReadFragmentPosition()) { |
437 GrDebugCrash("GrGLEffect asked for frag position but its generating
GrEffect " | 368 GrDebugCrash("GrGLEffect asked for frag position but its generating
GrEffect " |
438 "did not request access."); | 369 "did not request access."); |
439 return ""; | 370 return ""; |
440 } | 371 } |
441 } | 372 } |
442 if (fTopLeftFragPosRead) { | 373 if (fTopLeftFragPosRead) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 void GrGLShaderBuilder::appendUniformDecls(ShaderVisibility visibility, | 471 void GrGLShaderBuilder::appendUniformDecls(ShaderVisibility visibility, |
541 SkString* out) const { | 472 SkString* out) const { |
542 for (int i = 0; i < fUniforms.count(); ++i) { | 473 for (int i = 0; i < fUniforms.count(); ++i) { |
543 if (fUniforms[i].fVisibility & visibility) { | 474 if (fUniforms[i].fVisibility & visibility) { |
544 fUniforms[i].fVariable.appendDecl(fCtxInfo, out); | 475 fUniforms[i].fVariable.appendDecl(fCtxInfo, out); |
545 out->append(";\n"); | 476 out->append(";\n"); |
546 } | 477 } |
547 } | 478 } |
548 } | 479 } |
549 | 480 |
550 void GrGLShaderBuilder::vsGetShader(SkString* shaderStr) const { | |
551 *shaderStr = GrGetGLSLVersionDecl(fCtxInfo); | |
552 this->appendUniformDecls(kVertex_Visibility, shaderStr); | |
553 this->appendDecls(fVSAttrs, shaderStr); | |
554 this->appendDecls(fVSOutputs, shaderStr); | |
555 shaderStr->append("void main() {\n"); | |
556 shaderStr->append(fVSCode); | |
557 shaderStr->append("}\n"); | |
558 } | |
559 | |
560 void GrGLShaderBuilder::gsGetShader(SkString* shaderStr) const { | |
561 if (!fUsesGS) { | |
562 shaderStr->reset(); | |
563 return; | |
564 } | |
565 | |
566 *shaderStr = GrGetGLSLVersionDecl(fCtxInfo); | |
567 shaderStr->append(fGSHeader); | |
568 this->appendDecls(fGSInputs, shaderStr); | |
569 this->appendDecls(fGSOutputs, shaderStr); | |
570 shaderStr->append("void main() {\n"); | |
571 shaderStr->append(fGSCode); | |
572 shaderStr->append("}\n"); | |
573 } | |
574 | |
575 void GrGLShaderBuilder::fsGetShader(SkString* shaderStr) const { | 481 void GrGLShaderBuilder::fsGetShader(SkString* shaderStr) const { |
576 *shaderStr = GrGetGLSLVersionDecl(fCtxInfo); | 482 *shaderStr = GrGetGLSLVersionDecl(fCtxInfo); |
577 shaderStr->append(fFSExtensions); | 483 shaderStr->append(fFSExtensions); |
578 append_default_precision_qualifier(kDefaultFragmentPrecision, | 484 append_default_precision_qualifier(kDefaultFragmentPrecision, |
579 fCtxInfo.binding(), | 485 fCtxInfo.binding(), |
580 shaderStr); | 486 shaderStr); |
581 this->appendUniformDecls(kFragment_Visibility, shaderStr); | 487 this->appendUniformDecls(kFragment_Visibility, shaderStr); |
582 this->appendDecls(fFSInputs, shaderStr); | 488 this->appendDecls(fFSInputs, shaderStr); |
583 // We shouldn't have declared outputs on 1.10 | 489 // We shouldn't have declared outputs on 1.10 |
584 SkASSERT(k110_GrGLSLGeneration != fCtxInfo.glslGeneration() || fFSOutputs.em
pty()); | 490 SkASSERT(k110_GrGLSLGeneration != fCtxInfo.glslGeneration() || fFSOutputs.em
pty()); |
(...skipping 28 matching lines...) Expand all Loading... |
613 | 519 |
614 CodeStage::AutoStageRestore csar(&fCodeStage, &stage); | 520 CodeStage::AutoStageRestore csar(&fCodeStage, &stage); |
615 | 521 |
616 int numTextures = effect->numTextures(); | 522 int numTextures = effect->numTextures(); |
617 SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers; | 523 SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers; |
618 textureSamplers.push_back_n(numTextures); | 524 textureSamplers.push_back_n(numTextures); |
619 for (int t = 0; t < numTextures; ++t) { | 525 for (int t = 0; t < numTextures; ++t) { |
620 textureSamplers[t].init(this, &effect->textureAccess(t), t); | 526 textureSamplers[t].init(this, &effect->textureAccess(t), t); |
621 effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUnifor
m); | 527 effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUnifor
m); |
622 } | 528 } |
623 GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords()); | 529 GrDrawEffect drawEffect(stage, fVertexBuilder.get() |
| 530 && fVertexBuilder->hasExplicitLocalCoords
()); |
624 | 531 |
625 int numAttributes = stage.getVertexAttribIndexCount(); | 532 int numAttributes = stage.getVertexAttribIndexCount(); |
626 const int* attributeIndices = stage.getVertexAttribIndices(); | 533 const int* attributeIndices = stage.getVertexAttribIndices(); |
627 SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames; | 534 SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames; |
628 for (int a = 0; a < numAttributes; ++a) { | 535 for (int a = 0; a < numAttributes; ++a) { |
629 // TODO: Make addAttribute mangle the name. | 536 // TODO: Make addAttribute mangle the name. |
| 537 SkASSERT(fVertexBuilder.get()); |
630 SkString attributeName("aAttr"); | 538 SkString attributeName("aAttr"); |
631 attributeName.appendS32(attributeIndices[a]); | 539 attributeName.appendS32(attributeIndices[a]); |
632 if (this->addAttribute(effect->vertexAttribType(a), attributeName.c_
str())) { | 540 fVertexBuilder->addEffectAttribute(attributeIndices[a], |
633 fEffectAttributes.push_back().set(attributeIndices[a], attribute
Name); | 541 effect->vertexAttribType(a), |
634 } | 542 attributeName); |
635 } | 543 } |
636 | 544 |
637 glEffects[e] = effect->getFactory().createGLInstance(drawEffect); | 545 glEffects[e] = effect->getFactory().createGLInstance(drawEffect); |
638 | 546 |
639 if (kZeros_GrSLConstantVec == *fsInOutColorKnownValue) { | 547 if (kZeros_GrSLConstantVec == *fsInOutColorKnownValue) { |
640 // Effects have no way to communicate zeros, they treat an empty str
ing as ones. | 548 // Effects have no way to communicate zeros, they treat an empty str
ing as ones. |
641 this->nameVariable(&inColor, '\0', "input"); | 549 this->nameVariable(&inColor, '\0', "input"); |
642 this->fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZero
sVecf(4)); | 550 this->fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZero
sVecf(4)); |
643 } | 551 } |
644 | 552 |
645 // create var to hold stage result | 553 // create var to hold stage result |
646 this->nameVariable(&outColor, '\0', "output"); | 554 this->nameVariable(&outColor, '\0', "output"); |
647 this->fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); | 555 this->fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); |
648 | 556 |
649 // Enclose custom code in a block to avoid namespace conflicts | 557 // Enclose custom code in a block to avoid namespace conflicts |
650 SkString openBrace; | 558 SkString openBrace; |
651 openBrace.printf("\t{ // Stage %d: %s\n", fCodeStage.stageIndex(), glEff
ects[e]->name()); | 559 openBrace.printf("\t{ // Stage %d: %s\n", fCodeStage.stageIndex(), glEff
ects[e]->name()); |
652 this->fVSCode.append(openBrace); | 560 if (fVertexBuilder.get()) { |
653 this->fFSCode.append(openBrace); | 561 fVertexBuilder->vsCodeAppend(openBrace.c_str()); |
| 562 } |
| 563 this->fsCodeAppend(openBrace.c_str()); |
654 | 564 |
655 glEffects[e]->emitCode(this, | 565 glEffects[e]->emitCode(this, |
656 drawEffect, | 566 drawEffect, |
657 effectKeys[e], | 567 effectKeys[e], |
658 outColor.c_str(), | 568 outColor.c_str(), |
659 inColor.isEmpty() ? NULL : inColor.c_str(), | 569 inColor.isEmpty() ? NULL : inColor.c_str(), |
660 textureSamplers); | 570 textureSamplers); |
661 this->fVSCode.append("\t}\n"); | 571 |
662 this->fFSCode.append("\t}\n"); | 572 if (fVertexBuilder.get()) { |
| 573 fVertexBuilder->vsCodeAppend("\t}\n"); |
| 574 } |
| 575 this->fsCodeAppend("\t}\n"); |
663 | 576 |
664 inColor = outColor; | 577 inColor = outColor; |
665 *fsInOutColorKnownValue = kNone_GrSLConstantVec; | 578 *fsInOutColorKnownValue = kNone_GrSLConstantVec; |
666 effectEmitted = true; | 579 effectEmitted = true; |
667 } | 580 } |
668 | 581 |
669 if (effectEmitted) { | 582 if (effectEmitted) { |
670 *fsInOutColor = outColor; | 583 *fsInOutColor = outColor; |
671 } | 584 } |
672 } | 585 } |
673 | 586 |
674 const SkString* GrGLShaderBuilder::getEffectAttributeName(int attributeIndex) co
nst { | 587 //////////////////////////////////////////////////////////////////////////// |
| 588 |
| 589 GrGLShaderBuilder::VertexBuilder::VertexBuilder(GrGLShaderBuilder* parent, |
| 590 const GrGLProgramDesc& desc) |
| 591 : fVSAttrs(kVarsPerBlock) |
| 592 , fVSOutputs(kVarsPerBlock) |
| 593 , fGSInputs(kVarsPerBlock) |
| 594 , fGSOutputs(kVarsPerBlock) |
| 595 , fParent(parent) |
| 596 #if GR_GL_EXPERIMENTAL_GS |
| 597 , fUsesGS(SkToBool(desc.getHeader().fExperimentalGS)) |
| 598 #else |
| 599 , fUsesGS(false) |
| 600 #endif |
| 601 { |
| 602 const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); |
| 603 |
| 604 fPositionVar = &fVSAttrs.push_back(); |
| 605 fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "
aPosition"); |
| 606 if (-1 != header.fLocalCoordAttributeIndex) { |
| 607 fLocalCoordsVar = &fVSAttrs.push_back(); |
| 608 fLocalCoordsVar->set(kVec2f_GrSLType, |
| 609 GrGLShaderVar::kAttribute_TypeModifier, |
| 610 "aLocalCoords"); |
| 611 } else { |
| 612 fLocalCoordsVar = fPositionVar; |
| 613 } |
| 614 } |
| 615 |
| 616 bool GrGLShaderBuilder::VertexBuilder::addAttribute(GrSLType type, |
| 617 const char* name) { |
| 618 for (int i = 0; i < fVSAttrs.count(); ++i) { |
| 619 const GrGLShaderVar& attr = fVSAttrs[i]; |
| 620 // if attribute already added, don't add it again |
| 621 if (attr.getName().equals(name)) { |
| 622 SkASSERT(attr.getType() == type); |
| 623 return false; |
| 624 } |
| 625 } |
| 626 fVSAttrs.push_back().set(type, |
| 627 GrGLShaderVar::kAttribute_TypeModifier, |
| 628 name); |
| 629 return true; |
| 630 } |
| 631 |
| 632 bool GrGLShaderBuilder::VertexBuilder::addEffectAttribute(int attributeIndex, |
| 633 GrSLType type, |
| 634 const SkString& name)
{ |
| 635 if (!this->addAttribute(type, name.c_str())) { |
| 636 return false; |
| 637 } |
| 638 |
| 639 fEffectAttributes.push_back().set(attributeIndex, name); |
| 640 return true; |
| 641 } |
| 642 |
| 643 void GrGLShaderBuilder::VertexBuilder::addVarying(GrSLType type, |
| 644 const char* name, |
| 645 const char** vsOutName, |
| 646 const char** fsInName) { |
| 647 fVSOutputs.push_back(); |
| 648 fVSOutputs.back().setType(type); |
| 649 fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); |
| 650 fParent->nameVariable(fVSOutputs.back().accessName(), 'v', name); |
| 651 |
| 652 if (vsOutName) { |
| 653 *vsOutName = fVSOutputs.back().getName().c_str(); |
| 654 } |
| 655 // input to FS comes either from VS or GS |
| 656 const SkString* fsName; |
| 657 if (fUsesGS) { |
| 658 // if we have a GS take each varying in as an array |
| 659 // and output as non-array. |
| 660 fGSInputs.push_back(); |
| 661 fGSInputs.back().setType(type); |
| 662 fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier)
; |
| 663 fGSInputs.back().setUnsizedArray(); |
| 664 *fGSInputs.back().accessName() = fVSOutputs.back().getName(); |
| 665 fGSOutputs.push_back(); |
| 666 fGSOutputs.back().setType(type); |
| 667 fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifie
r); |
| 668 fParent->nameVariable(fGSOutputs.back().accessName(), 'g', name); |
| 669 fsName = fGSOutputs.back().accessName(); |
| 670 } else { |
| 671 fsName = fVSOutputs.back().accessName(); |
| 672 } |
| 673 fParent->fsInputAppend().set(type, |
| 674 GrGLShaderVar::kVaryingIn_TypeModifier, |
| 675 *fsName); |
| 676 if (fsInName) { |
| 677 *fsInName = fsName->c_str(); |
| 678 } |
| 679 } |
| 680 |
| 681 void GrGLShaderBuilder::VertexBuilder::vsGetShader(SkString* shaderStr) const { |
| 682 *shaderStr = GrGetGLSLVersionDecl(fParent->ctxInfo()); |
| 683 fParent->appendUniformDecls(kVertex_Visibility, shaderStr); |
| 684 fParent->appendDecls(fVSAttrs, shaderStr); |
| 685 fParent->appendDecls(fVSOutputs, shaderStr); |
| 686 shaderStr->append("void main() {\n"); |
| 687 shaderStr->append(fVSCode); |
| 688 shaderStr->append("}\n"); |
| 689 } |
| 690 |
| 691 void GrGLShaderBuilder::VertexBuilder::gsGetShader(SkString* shaderStr) const { |
| 692 if (!fUsesGS) { |
| 693 shaderStr->reset(); |
| 694 return; |
| 695 } |
| 696 |
| 697 *shaderStr = GrGetGLSLVersionDecl(fParent->ctxInfo()); |
| 698 shaderStr->append(fGSHeader); |
| 699 fParent->appendDecls(fGSInputs, shaderStr); |
| 700 fParent->appendDecls(fGSOutputs, shaderStr); |
| 701 shaderStr->append("void main() {\n"); |
| 702 shaderStr->append(fGSCode); |
| 703 shaderStr->append("}\n"); |
| 704 } |
| 705 |
| 706 |
| 707 const SkString* GrGLShaderBuilder::VertexBuilder::getEffectAttributeName(int att
ributeIndex) const { |
675 const AttributePair* attribEnd = this->getEffectAttributes().end(); | 708 const AttributePair* attribEnd = this->getEffectAttributes().end(); |
676 for (const AttributePair* attrib = this->getEffectAttributes().begin(); | 709 for (const AttributePair* attrib = this->getEffectAttributes().begin(); |
677 attrib != attribEnd; | 710 attrib != attribEnd; |
678 ++attrib) { | 711 ++attrib) { |
679 if (attrib->fIndex == attributeIndex) { | 712 if (attrib->fIndex == attributeIndex) { |
680 return &attrib->fName; | 713 return &attrib->fName; |
681 } | 714 } |
682 } | 715 } |
683 | 716 |
684 return NULL; | 717 return NULL; |
685 } | 718 } |
OLD | NEW |