| 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 |