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 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 } | 583 } |
584 | 584 |
585 if (!this->compileAndAttachShaders(programId)) { | 585 if (!this->compileAndAttachShaders(programId)) { |
586 GL_CALL(DeleteProgram(programId)); | 586 GL_CALL(DeleteProgram(programId)); |
587 return false; | 587 return false; |
588 } | 588 } |
589 | 589 |
590 this->bindProgramLocations(programId); | 590 this->bindProgramLocations(programId); |
591 | 591 |
592 GL_CALL(LinkProgram(programId)); | 592 GL_CALL(LinkProgram(programId)); |
593 GrGLint linked = GR_GL_INIT_ZERO; | 593 |
594 GL_CALL(GetProgramiv(programId, GR_GL_LINK_STATUS, &linked)); | 594 // Calling GetProgramiv is expensive in Chromium. Assume success in release
builds. |
595 if (!linked) { | 595 bool checkLinked = !fGpu->ctxInfo().isChromium(); |
596 GrGLint infoLen = GR_GL_INIT_ZERO; | 596 #ifdef SK_DEBUG |
597 GL_CALL(GetProgramiv(programId, GR_GL_INFO_LOG_LENGTH, &infoLen)); | 597 checkLinked = true; |
598 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger | 598 #endif |
599 if (infoLen > 0) { | 599 if (checkLinked) { |
600 // retrieve length even though we don't need it to workaround | 600 GrGLint linked = GR_GL_INIT_ZERO; |
601 // bug in chrome cmd buffer param validation. | 601 GL_CALL(GetProgramiv(programId, GR_GL_LINK_STATUS, &linked)); |
602 GrGLsizei length = GR_GL_INIT_ZERO; | 602 if (!linked) { |
603 GL_CALL(GetProgramInfoLog(programId, | 603 GrGLint infoLen = GR_GL_INIT_ZERO; |
604 infoLen+1, | 604 GL_CALL(GetProgramiv(programId, GR_GL_INFO_LOG_LENGTH, &infoLen)); |
605 &length, | 605 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debug
ger |
606 (char*)log.get())); | 606 if (infoLen > 0) { |
607 GrPrintf((char*)log.get()); | 607 // retrieve length even though we don't need it to workaround |
| 608 // bug in chrome cmd buffer param validation. |
| 609 GrGLsizei length = GR_GL_INIT_ZERO; |
| 610 GL_CALL(GetProgramInfoLog(programId, |
| 611 infoLen+1, |
| 612 &length, |
| 613 (char*)log.get())); |
| 614 GrPrintf((char*)log.get()); |
| 615 } |
| 616 SkDEBUGFAIL("Error linking program"); |
| 617 GL_CALL(DeleteProgram(programId)); |
| 618 return false; |
608 } | 619 } |
609 SkDEBUGFAIL("Error linking program"); | |
610 GL_CALL(DeleteProgram(programId)); | |
611 return false; | |
612 } | 620 } |
613 | 621 |
614 fUniformManager.getUniformLocations(programId, fUniforms); | 622 fUniformManager.getUniformLocations(programId, fUniforms); |
615 *outProgramId = programId; | 623 *outProgramId = programId; |
616 return true; | 624 return true; |
617 } | 625 } |
618 | 626 |
619 namespace { | |
620 // Compiles a GL shader, attaches it to a program, and releases the shader's ref
erence. | 627 // Compiles a GL shader, attaches it to a program, and releases the shader's ref
erence. |
621 // (That way there's no need to hang on to the GL shader id and delete it later.
) | 628 // (That way there's no need to hang on to the GL shader id and delete it later.
) |
622 bool attach_shader(const GrGLInterface* gli, | 629 static bool attach_shader(const GrGLContext& glCtx, |
623 GrGLuint programId, | 630 GrGLuint programId, |
624 GrGLenum type, | 631 GrGLenum type, |
625 const SkString& shaderSrc) { | 632 const SkString& shaderSrc) { |
| 633 const GrGLInterface* gli = glCtx.interface(); |
| 634 |
626 GrGLuint shaderId; | 635 GrGLuint shaderId; |
627 GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); | 636 GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); |
628 if (0 == shaderId) { | 637 if (0 == shaderId) { |
629 return false; | 638 return false; |
630 } | 639 } |
631 | 640 |
632 const GrGLchar* sourceStr = shaderSrc.c_str(); | 641 const GrGLchar* sourceStr = shaderSrc.c_str(); |
633 GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size()); | 642 GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size()); |
634 GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); | 643 GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); |
| 644 GR_GL_CALL(gli, CompileShader(shaderId)); |
635 | 645 |
636 GrGLint compiled = GR_GL_INIT_ZERO; | 646 // Calling GetShaderiv in Chromium is quite expensive. Assume success in rel
ease builds. |
637 GR_GL_CALL(gli, CompileShader(shaderId)); | 647 bool checkCompiled = !glCtx.info().isChromium(); |
638 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled)); | 648 #ifdef SK_DEBUG |
| 649 checkCompiled = true; |
| 650 #endif |
| 651 if (checkCompiled) { |
| 652 GrGLint compiled = GR_GL_INIT_ZERO; |
| 653 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled)); |
639 | 654 |
640 if (!compiled) { | 655 if (!compiled) { |
641 GrGLint infoLen = GR_GL_INIT_ZERO; | 656 GrGLint infoLen = GR_GL_INIT_ZERO; |
642 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen)); | 657 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLe
n)); |
643 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger | 658 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugg
er |
644 if (infoLen > 0) { | 659 if (infoLen > 0) { |
645 // retrieve length even though we don't need it to workaround bug in
chrome cmd buffer | 660 // retrieve length even though we don't need it to workaround bu
g in Chromium cmd |
646 // param validation. | 661 // buffer param validation. |
647 GrGLsizei length = GR_GL_INIT_ZERO; | 662 GrGLsizei length = GR_GL_INIT_ZERO; |
648 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, | 663 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, |
649 &length, (char*)log.get())); | 664 &length, (char*)log.get())); |
650 GrPrintf(shaderSrc.c_str()); | 665 GrPrintf(shaderSrc.c_str()); |
651 GrPrintf("\n%s", log.get()); | 666 GrPrintf("\n%s", log.get()); |
| 667 } |
| 668 SkDEBUGFAIL("Shader compilation failed!"); |
| 669 GR_GL_CALL(gli, DeleteShader(shaderId)); |
| 670 return false; |
652 } | 671 } |
653 SkDEBUGFAIL("Shader compilation failed!"); | 672 } |
654 GR_GL_CALL(gli, DeleteShader(shaderId)); | 673 if (c_PrintShaders) { |
655 return false; | |
656 } else if (c_PrintShaders) { | |
657 GrPrintf(shaderSrc.c_str()); | 674 GrPrintf(shaderSrc.c_str()); |
658 GrPrintf("\n"); | 675 GrPrintf("\n"); |
659 } | 676 } |
660 | 677 |
661 GR_GL_CALL(gli, AttachShader(programId, shaderId)); | 678 GR_GL_CALL(gli, AttachShader(programId, shaderId)); |
662 GR_GL_CALL(gli, DeleteShader(shaderId)); | 679 GR_GL_CALL(gli, DeleteShader(shaderId)); |
663 return true; | 680 return true; |
664 } | 681 } |
665 | 682 |
666 } | |
667 | |
668 bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { | 683 bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { |
669 SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); | 684 SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); |
670 fragShaderSrc.append(fFSExtensions); | 685 fragShaderSrc.append(fFSExtensions); |
671 append_default_precision_qualifier(kDefaultFragmentPrecision, | 686 append_default_precision_qualifier(kDefaultFragmentPrecision, |
672 fGpu->glBinding(), | 687 fGpu->glBinding(), |
673 &fragShaderSrc); | 688 &fragShaderSrc); |
674 this->appendUniformDecls(kFragment_Visibility, &fragShaderSrc); | 689 this->appendUniformDecls(kFragment_Visibility, &fragShaderSrc); |
675 this->appendDecls(fFSInputs, &fragShaderSrc); | 690 this->appendDecls(fFSInputs, &fragShaderSrc); |
676 // We shouldn't have declared outputs on 1.10 | 691 // We shouldn't have declared outputs on 1.10 |
677 SkASSERT(k110_GrGLSLGeneration != fGpu->glslGeneration() || fFSOutputs.empty
()); | 692 SkASSERT(k110_GrGLSLGeneration != fGpu->glslGeneration() || fFSOutputs.empty
()); |
678 this->appendDecls(fFSOutputs, &fragShaderSrc); | 693 this->appendDecls(fFSOutputs, &fragShaderSrc); |
679 fragShaderSrc.append(fFSFunctions); | 694 fragShaderSrc.append(fFSFunctions); |
680 fragShaderSrc.append("void main() {\n"); | 695 fragShaderSrc.append("void main() {\n"); |
681 fragShaderSrc.append(fFSCode); | 696 fragShaderSrc.append(fFSCode); |
682 fragShaderSrc.append("}\n"); | 697 fragShaderSrc.append("}\n"); |
683 if (!attach_shader(fGpu->glInterface(), programId, GR_GL_FRAGMENT_SHADER, fr
agShaderSrc)) { | 698 if (!attach_shader(fGpu->glContext(), programId, GR_GL_FRAGMENT_SHADER, frag
ShaderSrc)) { |
684 return false; | 699 return false; |
685 } | 700 } |
686 | 701 |
687 return true; | 702 return true; |
688 } | 703 } |
689 | 704 |
690 void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) const { | 705 void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) const { |
691 if (fHasCustomColorOutput) { | 706 if (fHasCustomColorOutput) { |
692 GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name())
); | 707 GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name())
); |
693 } | 708 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
844 GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt); | 859 GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt); |
845 this->INHERITED::createAndEmitEffects(&programEffectsBuilder, | 860 this->INHERITED::createAndEmitEffects(&programEffectsBuilder, |
846 effectStages, | 861 effectStages, |
847 effectKeys, | 862 effectKeys, |
848 effectCnt, | 863 effectCnt, |
849 inOutFSColor); | 864 inOutFSColor); |
850 return programEffectsBuilder.finish(); | 865 return programEffectsBuilder.finish(); |
851 } | 866 } |
852 | 867 |
853 bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { | 868 bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { |
854 const GrGLInterface* glInterface = this->gpu()->glInterface(); | 869 const GrGLContext& glCtx = this->gpu()->glContext(); |
855 SkString vertShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); | 870 SkString vertShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); |
856 this->appendUniformDecls(kVertex_Visibility, &vertShaderSrc); | 871 this->appendUniformDecls(kVertex_Visibility, &vertShaderSrc); |
857 this->appendDecls(fVSAttrs, &vertShaderSrc); | 872 this->appendDecls(fVSAttrs, &vertShaderSrc); |
858 this->appendDecls(fVSOutputs, &vertShaderSrc); | 873 this->appendDecls(fVSOutputs, &vertShaderSrc); |
859 vertShaderSrc.append("void main() {\n"); | 874 vertShaderSrc.append("void main() {\n"); |
860 vertShaderSrc.append(fVSCode); | 875 vertShaderSrc.append(fVSCode); |
861 vertShaderSrc.append("}\n"); | 876 vertShaderSrc.append("}\n"); |
862 if (!attach_shader(glInterface, programId, GR_GL_VERTEX_SHADER, vertShaderSr
c)) { | 877 if (!attach_shader(glCtx, programId, GR_GL_VERTEX_SHADER, vertShaderSrc)) { |
863 return false; | 878 return false; |
864 } | 879 } |
865 | 880 |
866 #if GR_GL_EXPERIMENTAL_GS | 881 #if GR_GL_EXPERIMENTAL_GS |
867 if (fDesc.getHeader().fExperimentalGS) { | 882 if (fDesc.getHeader().fExperimentalGS) { |
868 SkASSERT(this->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration); | 883 SkASSERT(this->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration); |
869 SkString geomShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); | 884 SkString geomShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); |
870 geomShaderSrc.append("layout(triangles) in;\n" | 885 geomShaderSrc.append("layout(triangles) in;\n" |
871 "layout(triangle_strip, max_vertices = 6) out;\n"); | 886 "layout(triangle_strip, max_vertices = 6) out;\n"); |
872 this->appendDecls(fGSInputs, &geomShaderSrc); | 887 this->appendDecls(fGSInputs, &geomShaderSrc); |
873 this->appendDecls(fGSOutputs, &geomShaderSrc); | 888 this->appendDecls(fGSOutputs, &geomShaderSrc); |
874 geomShaderSrc.append("void main() {\n"); | 889 geomShaderSrc.append("void main() {\n"); |
875 geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n" | 890 geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n" |
876 "\t\tgl_Position = gl_in[i].gl_Position;\n"); | 891 "\t\tgl_Position = gl_in[i].gl_Position;\n"); |
877 if (fDesc.getHeader().fEmitsPointSize) { | 892 if (fDesc.getHeader().fEmitsPointSize) { |
878 geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n"); | 893 geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n"); |
879 } | 894 } |
880 SkASSERT(fGSInputs.count() == fGSOutputs.count()); | 895 SkASSERT(fGSInputs.count() == fGSOutputs.count()); |
881 for (int i = 0; i < fGSInputs.count(); ++i) { | 896 for (int i = 0; i < fGSInputs.count(); ++i) { |
882 geomShaderSrc.appendf("\t\t%s = %s[i];\n", | 897 geomShaderSrc.appendf("\t\t%s = %s[i];\n", |
883 fGSOutputs[i].getName().c_str(), | 898 fGSOutputs[i].getName().c_str(), |
884 fGSInputs[i].getName().c_str()); | 899 fGSInputs[i].getName().c_str()); |
885 } | 900 } |
886 geomShaderSrc.append("\t\tEmitVertex();\n" | 901 geomShaderSrc.append("\t\tEmitVertex();\n" |
887 "\t}\n" | 902 "\t}\n" |
888 "\tEndPrimitive();\n"); | 903 "\tEndPrimitive();\n"); |
889 geomShaderSrc.append("}\n"); | 904 geomShaderSrc.append("}\n"); |
890 if (!attach_shader(glInterface, programId, GR_GL_GEOMETRY_SHADER, geomSh
aderSrc)) { | 905 if (!attach_shader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSr
c)) { |
891 return false; | 906 return false; |
892 } | 907 } |
893 } | 908 } |
894 #endif | 909 #endif |
895 | 910 |
896 return this->INHERITED::compileAndAttachShaders(programId); | 911 return this->INHERITED::compileAndAttachShaders(programId); |
897 } | 912 } |
898 | 913 |
899 void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const { | 914 void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const { |
900 this->INHERITED::bindProgramLocations(programId); | 915 this->INHERITED::bindProgramLocations(programId); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 GrGLSLExpr4* inOutFSColor) { | 972 GrGLSLExpr4* inOutFSColor) { |
958 | 973 |
959 GrGLTexGenProgramEffectsBuilder texGenEffectsBuilder(this, effectCnt); | 974 GrGLTexGenProgramEffectsBuilder texGenEffectsBuilder(this, effectCnt); |
960 this->INHERITED::createAndEmitEffects(&texGenEffectsBuilder, | 975 this->INHERITED::createAndEmitEffects(&texGenEffectsBuilder, |
961 effectStages, | 976 effectStages, |
962 effectKeys, | 977 effectKeys, |
963 effectCnt, | 978 effectCnt, |
964 inOutFSColor); | 979 inOutFSColor); |
965 return texGenEffectsBuilder.finish(); | 980 return texGenEffectsBuilder.finish(); |
966 } | 981 } |
OLD | NEW |