Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: src/gpu/gl/GrGLShaderBuilder.cpp

Issue 164973002: Defer deletion of our shaders until after linking the gl program to work around an Android emulator… (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/gl/GrGLShaderBuilder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/gpu/gl/GrGLShaderBuilder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698