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 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 const char* GrGLShaderBuilder::enableSecondaryOutput() { | 565 const char* GrGLShaderBuilder::enableSecondaryOutput() { |
566 if (!fHasSecondaryOutput) { | 566 if (!fHasSecondaryOutput) { |
567 fFSOutputs.push_back().set(kVec4f_GrSLType, | 567 fFSOutputs.push_back().set(kVec4f_GrSLType, |
568 GrGLShaderVar::kOut_TypeModifier, | 568 GrGLShaderVar::kOut_TypeModifier, |
569 dual_source_output_name()); | 569 dual_source_output_name()); |
570 fHasSecondaryOutput = true; | 570 fHasSecondaryOutput = true; |
571 } | 571 } |
572 return dual_source_output_name(); | 572 return dual_source_output_name(); |
573 } | 573 } |
574 | 574 |
575 | |
576 bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) { | 575 bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) { |
577 SK_TRACE_EVENT0("GrGLShaderBuilder::finish"); | 576 SK_TRACE_EVENT0("GrGLShaderBuilder::finish"); |
578 | 577 |
579 GrGLuint programId = 0; | 578 GrGLuint programId = 0; |
580 GL_CALL_RET(programId, CreateProgram()); | 579 GL_CALL_RET(programId, CreateProgram()); |
581 if (!programId) { | 580 if (!programId) { |
582 return false; | 581 return false; |
583 } | 582 } |
584 | 583 |
585 if (!this->compileAndAttachShaders(programId)) { | 584 SkTDArray<GrGLuint> shadersToDelete; |
| 585 |
| 586 if (!this->compileAndAttachShaders(programId, &shadersToDelete)) { |
586 GL_CALL(DeleteProgram(programId)); | 587 GL_CALL(DeleteProgram(programId)); |
587 return false; | 588 return false; |
588 } | 589 } |
589 | 590 |
590 this->bindProgramLocations(programId); | 591 this->bindProgramLocations(programId); |
591 if (fUniformManager.isUsingBindUniform()) { | 592 if (fUniformManager.isUsingBindUniform()) { |
592 fUniformManager.getUniformLocations(programId, fUniforms); | 593 fUniformManager.getUniformLocations(programId, fUniforms); |
593 } | 594 } |
594 | 595 |
595 GL_CALL(LinkProgram(programId)); | 596 GL_CALL(LinkProgram(programId)); |
(...skipping 22 matching lines...) Expand all Loading... |
618 } | 619 } |
619 SkDEBUGFAIL("Error linking program"); | 620 SkDEBUGFAIL("Error linking program"); |
620 GL_CALL(DeleteProgram(programId)); | 621 GL_CALL(DeleteProgram(programId)); |
621 return false; | 622 return false; |
622 } | 623 } |
623 } | 624 } |
624 | 625 |
625 if (!fUniformManager.isUsingBindUniform()) { | 626 if (!fUniformManager.isUsingBindUniform()) { |
626 fUniformManager.getUniformLocations(programId, fUniforms); | 627 fUniformManager.getUniformLocations(programId, fUniforms); |
627 } | 628 } |
| 629 |
| 630 for (int i = 0; i < shadersToDelete.count(); ++i) { |
| 631 GL_CALL(DeleteShader(shadersToDelete[i])); |
| 632 } |
| 633 |
628 *outProgramId = programId; | 634 *outProgramId = programId; |
629 return true; | 635 return true; |
630 } | 636 } |
631 | 637 |
632 // Compiles a GL shader, attaches it to a program, and releases the shader's ref
erence. | 638 // Compiles a GL shader and attaches it to a program. Returns the shader ID if |
633 // (That way there's no need to hang on to the GL shader id and delete it later.
) | 639 // successful, or 0 if not. |
634 static bool attach_shader(const GrGLContext& glCtx, | 640 static GrGLuint attach_shader(const GrGLContext& glCtx, |
635 GrGLuint programId, | 641 GrGLuint programId, |
636 GrGLenum type, | 642 GrGLenum type, |
637 const SkString& shaderSrc) { | 643 const SkString& shaderSrc) { |
638 const GrGLInterface* gli = glCtx.interface(); | 644 const GrGLInterface* gli = glCtx.interface(); |
639 | 645 |
640 GrGLuint shaderId; | 646 GrGLuint shaderId; |
641 GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); | 647 GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); |
642 if (0 == shaderId) { | 648 if (0 == shaderId) { |
643 return false; | 649 return 0; |
644 } | 650 } |
645 | 651 |
646 const GrGLchar* sourceStr = shaderSrc.c_str(); | 652 const GrGLchar* sourceStr = shaderSrc.c_str(); |
647 GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size()); | 653 GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size()); |
648 GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); | 654 GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); |
649 GR_GL_CALL(gli, CompileShader(shaderId)); | 655 GR_GL_CALL(gli, CompileShader(shaderId)); |
650 | 656 |
651 // Calling GetShaderiv in Chromium is quite expensive. Assume success in rel
ease builds. | 657 // Calling GetShaderiv in Chromium is quite expensive. Assume success in rel
ease builds. |
652 bool checkCompiled = !glCtx.isChromium(); | 658 bool checkCompiled = !glCtx.isChromium(); |
653 #ifdef SK_DEBUG | 659 #ifdef SK_DEBUG |
(...skipping 11 matching lines...) Expand all Loading... |
665 // retrieve length even though we don't need it to workaround bu
g in Chromium cmd | 671 // retrieve length even though we don't need it to workaround bu
g in Chromium cmd |
666 // buffer param validation. | 672 // buffer param validation. |
667 GrGLsizei length = GR_GL_INIT_ZERO; | 673 GrGLsizei length = GR_GL_INIT_ZERO; |
668 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, | 674 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, |
669 &length, (char*)log.get())); | 675 &length, (char*)log.get())); |
670 GrPrintf(shaderSrc.c_str()); | 676 GrPrintf(shaderSrc.c_str()); |
671 GrPrintf("\n%s", log.get()); | 677 GrPrintf("\n%s", log.get()); |
672 } | 678 } |
673 SkDEBUGFAIL("Shader compilation failed!"); | 679 SkDEBUGFAIL("Shader compilation failed!"); |
674 GR_GL_CALL(gli, DeleteShader(shaderId)); | 680 GR_GL_CALL(gli, DeleteShader(shaderId)); |
675 return false; | 681 return 0; |
676 } | 682 } |
677 } | 683 } |
678 if (c_PrintShaders) { | 684 if (c_PrintShaders) { |
679 GrPrintf(shaderSrc.c_str()); | 685 GrPrintf(shaderSrc.c_str()); |
680 GrPrintf("\n"); | 686 GrPrintf("\n"); |
681 } | 687 } |
682 | 688 |
| 689 // Attach the shader, but defer deletion until after we have linked the prog
ram. |
| 690 // This works around a bug in the Android emulator's GLES2 wrapper which |
| 691 // will immediately delete the shader object and free its memory even though
it's |
| 692 // attached to a program, which then causes glLinkProgram to fail. |
683 GR_GL_CALL(gli, AttachShader(programId, shaderId)); | 693 GR_GL_CALL(gli, AttachShader(programId, shaderId)); |
684 GR_GL_CALL(gli, DeleteShader(shaderId)); | 694 |
685 return true; | 695 return shaderId; |
686 } | 696 } |
687 | 697 |
688 bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { | 698 bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray<Gr
GLuint>* shaderIds) const { |
689 SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); | 699 SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); |
690 fragShaderSrc.append(fFSExtensions); | 700 fragShaderSrc.append(fFSExtensions); |
691 append_default_precision_qualifier(kDefaultFragmentPrecision, | 701 append_default_precision_qualifier(kDefaultFragmentPrecision, |
692 fGpu->glStandard(), | 702 fGpu->glStandard(), |
693 &fragShaderSrc); | 703 &fragShaderSrc); |
694 this->appendUniformDecls(kFragment_Visibility, &fragShaderSrc); | 704 this->appendUniformDecls(kFragment_Visibility, &fragShaderSrc); |
695 this->appendDecls(fFSInputs, &fragShaderSrc); | 705 this->appendDecls(fFSInputs, &fragShaderSrc); |
696 // We shouldn't have declared outputs on 1.10 | 706 // We shouldn't have declared outputs on 1.10 |
697 SkASSERT(k110_GrGLSLGeneration != fGpu->glslGeneration() || fFSOutputs.empty
()); | 707 SkASSERT(k110_GrGLSLGeneration != fGpu->glslGeneration() || fFSOutputs.empty
()); |
698 this->appendDecls(fFSOutputs, &fragShaderSrc); | 708 this->appendDecls(fFSOutputs, &fragShaderSrc); |
699 fragShaderSrc.append(fFSFunctions); | 709 fragShaderSrc.append(fFSFunctions); |
700 fragShaderSrc.append("void main() {\n"); | 710 fragShaderSrc.append("void main() {\n"); |
701 fragShaderSrc.append(fFSCode); | 711 fragShaderSrc.append(fFSCode); |
702 fragShaderSrc.append("}\n"); | 712 fragShaderSrc.append("}\n"); |
703 if (!attach_shader(fGpu->glContext(), programId, GR_GL_FRAGMENT_SHADER, frag
ShaderSrc)) { | 713 |
| 714 GrGLuint fragShaderId = attach_shader(fGpu->glContext(), programId, GR_GL_FR
AGMENT_SHADER, fragShaderSrc); |
| 715 if (!fragShaderId) { |
704 return false; | 716 return false; |
705 } | 717 } |
706 | 718 |
| 719 *shaderIds->append() = fragShaderId; |
| 720 |
707 return true; | 721 return true; |
708 } | 722 } |
709 | 723 |
710 void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) const { | 724 void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) const { |
711 if (fHasCustomColorOutput) { | 725 if (fHasCustomColorOutput) { |
712 GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name())
); | 726 GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name())
); |
713 } | 727 } |
714 if (fHasSecondaryOutput) { | 728 if (fHasSecondaryOutput) { |
715 GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_
name())); | 729 GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_
name())); |
716 } | 730 } |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 | 877 |
864 GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt); | 878 GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt); |
865 this->INHERITED::createAndEmitEffects(&programEffectsBuilder, | 879 this->INHERITED::createAndEmitEffects(&programEffectsBuilder, |
866 effectStages, | 880 effectStages, |
867 effectKeys, | 881 effectKeys, |
868 effectCnt, | 882 effectCnt, |
869 inOutFSColor); | 883 inOutFSColor); |
870 return programEffectsBuilder.finish(); | 884 return programEffectsBuilder.finish(); |
871 } | 885 } |
872 | 886 |
873 bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { | 887 bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArra
y<GrGLuint>* shaderIds) const { |
874 const GrGLContext& glCtx = this->gpu()->glContext(); | 888 const GrGLContext& glCtx = this->gpu()->glContext(); |
875 SkString vertShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); | 889 SkString vertShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); |
876 this->appendUniformDecls(kVertex_Visibility, &vertShaderSrc); | 890 this->appendUniformDecls(kVertex_Visibility, &vertShaderSrc); |
877 this->appendDecls(fVSAttrs, &vertShaderSrc); | 891 this->appendDecls(fVSAttrs, &vertShaderSrc); |
878 this->appendDecls(fVSOutputs, &vertShaderSrc); | 892 this->appendDecls(fVSOutputs, &vertShaderSrc); |
879 vertShaderSrc.append("void main() {\n"); | 893 vertShaderSrc.append("void main() {\n"); |
880 vertShaderSrc.append(fVSCode); | 894 vertShaderSrc.append(fVSCode); |
881 vertShaderSrc.append("}\n"); | 895 vertShaderSrc.append("}\n"); |
882 if (!attach_shader(glCtx, programId, GR_GL_VERTEX_SHADER, vertShaderSrc)) { | 896 GrGLuint vertShaderId = attach_shader(glCtx, programId, GR_GL_VERTEX_SHADER,
vertShaderSrc); |
| 897 if (!vertShaderId) { |
883 return false; | 898 return false; |
884 } | 899 } |
| 900 *shaderIds->append() = vertShaderId; |
885 | 901 |
886 #if GR_GL_EXPERIMENTAL_GS | 902 #if GR_GL_EXPERIMENTAL_GS |
887 if (fDesc.getHeader().fExperimentalGS) { | 903 if (fDesc.getHeader().fExperimentalGS) { |
888 SkASSERT(this->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration); | 904 SkASSERT(this->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration); |
889 SkString geomShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); | 905 SkString geomShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); |
890 geomShaderSrc.append("layout(triangles) in;\n" | 906 geomShaderSrc.append("layout(triangles) in;\n" |
891 "layout(triangle_strip, max_vertices = 6) out;\n"); | 907 "layout(triangle_strip, max_vertices = 6) out;\n"); |
892 this->appendDecls(fGSInputs, &geomShaderSrc); | 908 this->appendDecls(fGSInputs, &geomShaderSrc); |
893 this->appendDecls(fGSOutputs, &geomShaderSrc); | 909 this->appendDecls(fGSOutputs, &geomShaderSrc); |
894 geomShaderSrc.append("void main() {\n"); | 910 geomShaderSrc.append("void main() {\n"); |
895 geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n" | 911 geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n" |
896 "\t\tgl_Position = gl_in[i].gl_Position;\n"); | 912 "\t\tgl_Position = gl_in[i].gl_Position;\n"); |
897 if (fDesc.getHeader().fEmitsPointSize) { | 913 if (fDesc.getHeader().fEmitsPointSize) { |
898 geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n"); | 914 geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n"); |
899 } | 915 } |
900 SkASSERT(fGSInputs.count() == fGSOutputs.count()); | 916 SkASSERT(fGSInputs.count() == fGSOutputs.count()); |
901 for (int i = 0; i < fGSInputs.count(); ++i) { | 917 for (int i = 0; i < fGSInputs.count(); ++i) { |
902 geomShaderSrc.appendf("\t\t%s = %s[i];\n", | 918 geomShaderSrc.appendf("\t\t%s = %s[i];\n", |
903 fGSOutputs[i].getName().c_str(), | 919 fGSOutputs[i].getName().c_str(), |
904 fGSInputs[i].getName().c_str()); | 920 fGSInputs[i].getName().c_str()); |
905 } | 921 } |
906 geomShaderSrc.append("\t\tEmitVertex();\n" | 922 geomShaderSrc.append("\t\tEmitVertex();\n" |
907 "\t}\n" | 923 "\t}\n" |
908 "\tEndPrimitive();\n"); | 924 "\tEndPrimitive();\n"); |
909 geomShaderSrc.append("}\n"); | 925 geomShaderSrc.append("}\n"); |
910 if (!attach_shader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSr
c)) { | 926 GrGLuint geomShaderId = attach_shader(glCtx, programId, GR_GL_GEOMETRY_S
HADER, geomShaderSrc); |
| 927 if (!geomShaderId) { |
911 return false; | 928 return false; |
912 } | 929 } |
| 930 *shaderIds->append() = geomShaderId; |
913 } | 931 } |
914 #endif | 932 #endif |
915 | 933 |
916 return this->INHERITED::compileAndAttachShaders(programId); | 934 return this->INHERITED::compileAndAttachShaders(programId, shaderIds); |
917 } | 935 } |
918 | 936 |
919 void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const { | 937 void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const { |
920 this->INHERITED::bindProgramLocations(programId); | 938 this->INHERITED::bindProgramLocations(programId); |
921 | 939 |
922 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | 940 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
923 | 941 |
924 // Bind the attrib locations to same values for all shaders | 942 // Bind the attrib locations to same values for all shaders |
925 SkASSERT(-1 != header.fPositionAttributeIndex); | 943 SkASSERT(-1 != header.fPositionAttributeIndex); |
926 GL_CALL(BindAttribLocation(programId, | 944 GL_CALL(BindAttribLocation(programId, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 GrGLSLExpr4* inOutFSColor) { | 995 GrGLSLExpr4* inOutFSColor) { |
978 | 996 |
979 GrGLTexGenProgramEffectsBuilder texGenEffectsBuilder(this, effectCnt); | 997 GrGLTexGenProgramEffectsBuilder texGenEffectsBuilder(this, effectCnt); |
980 this->INHERITED::createAndEmitEffects(&texGenEffectsBuilder, | 998 this->INHERITED::createAndEmitEffects(&texGenEffectsBuilder, |
981 effectStages, | 999 effectStages, |
982 effectKeys, | 1000 effectKeys, |
983 effectCnt, | 1001 effectCnt, |
984 inOutFSColor); | 1002 inOutFSColor); |
985 return texGenEffectsBuilder.finish(); | 1003 return texGenEffectsBuilder.finish(); |
986 } | 1004 } |
OLD | NEW |