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(new VertexBuilder(this, desc)); |
bsalomon
2013/08/30 17:59:17
SkNEW_ARGS(VertexBuilder, (this, desc));
Chris Dalton
2013/08/30 19:10:30
Done.
| |
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.binding(), fCtxInfo.glslGeneratio n()); | |
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.binding(), fCtxInfo.glslGeneratio n()); | |
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.binding(), fCtxInfo.glslGeneratio n()); | 482 *shaderStr = GrGetGLSLVersionDecl(fCtxInfo.binding(), fCtxInfo.glslGeneratio n()); |
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().binding(), | |
683 fParent->ctxInfo().glslGeneration()); | |
684 fParent->appendUniformDecls(kVertex_Visibility, shaderStr); | |
685 fParent->appendDecls(fVSAttrs, shaderStr); | |
686 fParent->appendDecls(fVSOutputs, shaderStr); | |
687 shaderStr->append("void main() {\n"); | |
688 shaderStr->append(fVSCode); | |
689 shaderStr->append("}\n"); | |
690 } | |
691 | |
692 void GrGLShaderBuilder::VertexBuilder::gsGetShader(SkString* shaderStr) const { | |
693 if (!fUsesGS) { | |
694 shaderStr->reset(); | |
695 return; | |
696 } | |
697 | |
698 *shaderStr = GrGetGLSLVersionDecl(fParent->ctxInfo().binding(), | |
699 fParent->ctxInfo().glslGeneration()); | |
700 shaderStr->append(fGSHeader); | |
701 fParent->appendDecls(fGSInputs, shaderStr); | |
702 fParent->appendDecls(fGSOutputs, shaderStr); | |
703 shaderStr->append("void main() {\n"); | |
704 shaderStr->append(fGSCode); | |
705 shaderStr->append("}\n"); | |
706 } | |
707 | |
708 | |
709 const SkString* GrGLShaderBuilder::VertexBuilder::getEffectAttributeName(int att ributeIndex) const { | |
675 const AttributePair* attribEnd = this->getEffectAttributes().end(); | 710 const AttributePair* attribEnd = this->getEffectAttributes().end(); |
676 for (const AttributePair* attrib = this->getEffectAttributes().begin(); | 711 for (const AttributePair* attrib = this->getEffectAttributes().begin(); |
677 attrib != attribEnd; | 712 attrib != attribEnd; |
678 ++attrib) { | 713 ++attrib) { |
679 if (attrib->fIndex == attributeIndex) { | 714 if (attrib->fIndex == attributeIndex) { |
680 return &attrib->fName; | 715 return &attrib->fName; |
681 } | 716 } |
682 } | 717 } |
683 | 718 |
684 return NULL; | 719 return NULL; |
685 } | 720 } |
721 | |
OLD | NEW |