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" |
11 #include "GrCoordTransform.h" | 11 #include "GrCoordTransform.h" |
12 #include "GrDrawEffect.h" | 12 #include "GrDrawEffect.h" |
13 #include "GrGpuGL.h" | 13 #include "GrGpuGL.h" |
14 #include "GrTexture.h" | 14 #include "GrTexture.h" |
15 #include "SkRTConf.h" | 15 #include "SkRTConf.h" |
16 #include "SkTraceEvent.h" | 16 #include "SkTraceEvent.h" |
17 | 17 |
18 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) | 18 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) |
19 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) | 19 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) |
20 | 20 |
21 // number of each input/output type in a single allocation block | 21 // number of each input/output type in a single allocation block |
22 static const int kVarsPerBlock = 8; | 22 static const int kVarsPerBlock = 8; |
23 | 23 |
24 // except FS outputs where we expect 2 at most. | 24 // except FS outputs where we expect 2 at most. |
25 static const int kMaxFSOutputs = 2; | 25 static const int kMaxFSOutputs = 2; |
26 | 26 |
27 // ES2 FS only guarantees mediump and lowp support | 27 // ES2 FS only guarantees mediump and lowp support |
28 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar:
:kMedium_Precision; | 28 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar:
:kMedium_Precision; |
29 | 29 |
30 typedef GrGLUniformManager::UniformHandle UniformHandle; | 30 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
31 | 31 |
32 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, | 32 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, |
33 "Print the source code for all shaders generated."); | 33 "Print the source code for all shaders generated."); |
34 | 34 |
35 /////////////////////////////////////////////////////////////////////////////// | 35 /////////////////////////////////////////////////////////////////////////////// |
36 | 36 |
37 namespace { | 37 namespace { |
38 | 38 |
39 inline const char* color_attribute_name() { return "aColor"; } | 39 inline const char* color_attribute_name() { return "aColor"; } |
40 inline const char* coverage_attribute_name() { return "aCoverage"; } | 40 inline const char* coverage_attribute_name() { return "aCoverage"; } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 } | 83 } |
84 } | 84 } |
85 | 85 |
86 } | 86 } |
87 | 87 |
88 static const char kDstCopyColorName[] = "_dstColor"; | 88 static const char kDstCopyColorName[] = "_dstColor"; |
89 | 89 |
90 /////////////////////////////////////////////////////////////////////////////// | 90 /////////////////////////////////////////////////////////////////////////////// |
91 | 91 |
92 bool GrGLShaderBuilder::GenProgram(GrGpuGL* gpu, | 92 bool GrGLShaderBuilder::GenProgram(GrGpuGL* gpu, |
93 GrGLUniformManager* uman, | 93 GrGLProgramDataManager* pdman, |
94 const GrGLProgramDesc& desc, | 94 const GrGLProgramDesc& desc, |
95 const GrEffectStage* inColorStages[], | 95 const GrEffectStage* inColorStages[], |
96 const GrEffectStage* inCoverageStages[], | 96 const GrEffectStage* inCoverageStages[], |
97 GenProgramOutput* output) { | 97 GenProgramOutput* output) { |
98 SkAutoTDelete<GrGLShaderBuilder> builder; | 98 SkAutoTDelete<GrGLShaderBuilder> builder; |
99 if (desc.getHeader().fHasVertexCode ||!gpu->shouldUseFixedFunctionTexturing(
)) { | 99 if (desc.getHeader().fHasVertexCode ||!gpu->shouldUseFixedFunctionTexturing(
)) { |
100 builder.reset(SkNEW_ARGS(GrGLFullShaderBuilder, (gpu, uman, desc))); | 100 builder.reset(SkNEW_ARGS(GrGLFullShaderBuilder, (gpu, pdman, desc))); |
101 } else { | 101 } else { |
102 builder.reset(SkNEW_ARGS(GrGLFragmentOnlyShaderBuilder, (gpu, uman, desc
))); | 102 builder.reset(SkNEW_ARGS(GrGLFragmentOnlyShaderBuilder, (gpu, pdman, des
c))); |
103 } | 103 } |
104 if (builder->genProgram(inColorStages, inCoverageStages)) { | 104 if (builder->genProgram(inColorStages, inCoverageStages)) { |
105 *output = builder->getOutput(); | 105 *output = builder->getOutput(); |
106 return true; | 106 return true; |
107 } | 107 } |
108 return false; | 108 return false; |
109 } | 109 } |
110 | 110 |
111 bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[], | 111 bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[], |
112 const GrEffectStage* coverageStages[]) { | 112 const GrEffectStage* coverageStages[]) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 if (!this->finish()) { | 241 if (!this->finish()) { |
242 return false; | 242 return false; |
243 } | 243 } |
244 | 244 |
245 return true; | 245 return true; |
246 } | 246 } |
247 | 247 |
248 ////////////////////////////////////////////////////////////////////////////// | 248 ////////////////////////////////////////////////////////////////////////////// |
249 | 249 |
250 GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, | 250 GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, |
251 GrGLUniformManager* uniformManager, | 251 GrGLProgramDataManager* programResourceMana
ger, |
252 const GrGLProgramDesc& desc) | 252 const GrGLProgramDesc& desc) |
253 : fDesc(desc) | 253 : fDesc(desc) |
254 , fGpu(gpu) | 254 , fGpu(gpu) |
255 , fUniformManager(SkRef(uniformManager)) | 255 , fProgramDataManager(SkRef(programResourceManager)) |
256 , fFSFeaturesAddedMask(0) | 256 , fFSFeaturesAddedMask(0) |
257 , fFSInputs(kVarsPerBlock) | 257 , fFSInputs(kVarsPerBlock) |
258 , fFSOutputs(kMaxFSOutputs) | 258 , fFSOutputs(kMaxFSOutputs) |
259 , fUniforms(kVarsPerBlock) | 259 , fUniforms(kVarsPerBlock) |
260 , fSetupFragPosition(false) | 260 , fSetupFragPosition(false) |
261 , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFr
agPosKey) | 261 , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFr
agPosKey) |
262 , fHasCustomColorOutput(false) | 262 , fHasCustomColorOutput(false) |
263 , fHasSecondaryOutput(false) { | 263 , fHasSecondaryOutput(false) { |
264 } | 264 } |
265 | 265 |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA, | 423 static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA, |
424 GR_GL_ALPHA, GR_GL_ALPHA }; | 424 GR_GL_ALPHA, GR_GL_ALPHA }; |
425 return gAlphaSmear; | 425 return gAlphaSmear; |
426 } | 426 } |
427 } else { | 427 } else { |
428 static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE
, GR_GL_ALPHA }; | 428 static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE
, GR_GL_ALPHA }; |
429 return gStraight; | 429 return gStraight; |
430 } | 430 } |
431 } | 431 } |
432 | 432 |
433 GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t vi
sibility, | 433 GrGLProgramDataManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_
t visibility, |
434 GrSLType ty
pe, | 434 GrSLTyp
e type, |
435 const char*
name, | 435 const c
har* name, |
436 int count, | 436 int cou
nt, |
437 const char*
* outName) { | 437 const c
har** outName) { |
438 SkASSERT(name && strlen(name)); | 438 SkASSERT(name && strlen(name)); |
439 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); | 439 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); |
440 SkASSERT(0 == (~kVisibilityMask & visibility)); | 440 SkASSERT(0 == (~kVisibilityMask & visibility)); |
441 SkASSERT(0 != visibility); | 441 SkASSERT(0 != visibility); |
442 | 442 |
443 BuilderUniform& uni = fUniforms.push_back(); | 443 BuilderUniform& uni = fUniforms.push_back(); |
444 UniformHandle h = GrGLUniformManager::UniformHandle::CreateFromUniformIndex(
fUniforms.count() - 1); | 444 UniformHandle h = GrGLProgramDataManager::UniformHandle::CreateFromUniformIn
dex(fUniforms.count() - 1); |
445 SkDEBUGCODE(UniformHandle h2 =) | 445 SkDEBUGCODE(UniformHandle h2 =) |
446 fUniformManager->appendUniform(type, count); | 446 fProgramDataManager->appendUniform(type, count); |
447 // We expect the uniform manager to initially have no uniforms and that all
uniforms are added | 447 // We expect the uniform manager to initially have no uniforms and that all
uniforms are added |
448 // by this function. Therefore, the handles should match. | 448 // by this function. Therefore, the handles should match. |
449 SkASSERT(h2 == h); | 449 SkASSERT(h2 == h); |
450 uni.fVariable.setType(type); | 450 uni.fVariable.setType(type); |
451 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); | 451 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); |
452 this->nameVariable(uni.fVariable.accessName(), 'u', name); | 452 this->nameVariable(uni.fVariable.accessName(), 'u', name); |
453 uni.fVariable.setArrayCount(count); | 453 uni.fVariable.setArrayCount(count); |
454 uni.fVisibility = visibility; | 454 uni.fVisibility = visibility; |
455 | 455 |
456 // If it is visible in both the VS and FS, the precision must match. | 456 // If it is visible in both the VS and FS, the precision must match. |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
666 } | 666 } |
667 | 667 |
668 SkTDArray<GrGLuint> shadersToDelete; | 668 SkTDArray<GrGLuint> shadersToDelete; |
669 | 669 |
670 if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) { | 670 if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) { |
671 GL_CALL(DeleteProgram(fOutput.fProgramID)); | 671 GL_CALL(DeleteProgram(fOutput.fProgramID)); |
672 return false; | 672 return false; |
673 } | 673 } |
674 | 674 |
675 this->bindProgramLocations(fOutput.fProgramID); | 675 this->bindProgramLocations(fOutput.fProgramID); |
676 if (fUniformManager->isUsingBindUniform()) { | 676 if (fProgramDataManager->isUsingBindUniform()) { |
677 fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms); | 677 fProgramDataManager->getUniformLocations(fOutput.fProgramID, fUniforms); |
678 } | 678 } |
679 | 679 |
680 GL_CALL(LinkProgram(fOutput.fProgramID)); | 680 GL_CALL(LinkProgram(fOutput.fProgramID)); |
681 | 681 |
682 // Calling GetProgramiv is expensive in Chromium. Assume success in release
builds. | 682 // Calling GetProgramiv is expensive in Chromium. Assume success in release
builds. |
683 bool checkLinked = !fGpu->ctxInfo().isChromium(); | 683 bool checkLinked = !fGpu->ctxInfo().isChromium(); |
684 #ifdef SK_DEBUG | 684 #ifdef SK_DEBUG |
685 checkLinked = true; | 685 checkLinked = true; |
686 #endif | 686 #endif |
687 if (checkLinked) { | 687 if (checkLinked) { |
(...skipping 13 matching lines...) Expand all Loading... |
701 (char*)log.get())); | 701 (char*)log.get())); |
702 GrPrintf((char*)log.get()); | 702 GrPrintf((char*)log.get()); |
703 } | 703 } |
704 SkDEBUGFAIL("Error linking program"); | 704 SkDEBUGFAIL("Error linking program"); |
705 GL_CALL(DeleteProgram(fOutput.fProgramID)); | 705 GL_CALL(DeleteProgram(fOutput.fProgramID)); |
706 fOutput.fProgramID = 0; | 706 fOutput.fProgramID = 0; |
707 return false; | 707 return false; |
708 } | 708 } |
709 } | 709 } |
710 | 710 |
711 if (!fUniformManager->isUsingBindUniform()) { | 711 if (!fProgramDataManager->isUsingBindUniform()) { |
712 fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms); | 712 fProgramDataManager->getUniformLocations(fOutput.fProgramID, fUniforms); |
713 } | 713 } |
714 | 714 |
715 for (int i = 0; i < shadersToDelete.count(); ++i) { | 715 for (int i = 0; i < shadersToDelete.count(); ++i) { |
716 GL_CALL(DeleteShader(shadersToDelete[i])); | 716 GL_CALL(DeleteShader(shadersToDelete[i])); |
717 } | 717 } |
718 | 718 |
719 return true; | 719 return true; |
720 } | 720 } |
721 | 721 |
722 // Compiles a GL shader and attaches it to a program. Returns the shader ID if | 722 // Compiles a GL shader and attaches it to a program. Returns the shader ID if |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 } | 817 } |
818 } | 818 } |
819 | 819 |
820 const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const { | 820 const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const { |
821 return fGpu->ctxInfo(); | 821 return fGpu->ctxInfo(); |
822 } | 822 } |
823 | 823 |
824 //////////////////////////////////////////////////////////////////////////////// | 824 //////////////////////////////////////////////////////////////////////////////// |
825 | 825 |
826 GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, | 826 GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, |
827 GrGLUniformManager* uniformManager, | 827 GrGLProgramDataManager* programReso
urceManager, |
828 const GrGLProgramDesc& desc) | 828 const GrGLProgramDesc& desc) |
829 : INHERITED(gpu, uniformManager, desc) | 829 : INHERITED(gpu, programResourceManager, desc) |
830 , fVSAttrs(kVarsPerBlock) | 830 , fVSAttrs(kVarsPerBlock) |
831 , fVSOutputs(kVarsPerBlock) | 831 , fVSOutputs(kVarsPerBlock) |
832 , fGSInputs(kVarsPerBlock) | 832 , fGSInputs(kVarsPerBlock) |
833 , fGSOutputs(kVarsPerBlock) { | 833 , fGSOutputs(kVarsPerBlock) { |
834 } | 834 } |
835 | 835 |
836 void GrGLFullShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr
4* coverage) { | 836 void GrGLFullShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr
4* coverage) { |
837 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); | 837 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); |
838 | 838 |
839 fOutput.fHasVertexShader = true; | 839 fOutput.fHasVertexShader = true; |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1066 | 1066 |
1067 const AttributePair* attribEnd = fEffectAttributes.end(); | 1067 const AttributePair* attribEnd = fEffectAttributes.end(); |
1068 for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attr
ibEnd; ++attrib) { | 1068 for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attr
ibEnd; ++attrib) { |
1069 GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_s
tr())); | 1069 GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_s
tr())); |
1070 } | 1070 } |
1071 } | 1071 } |
1072 | 1072 |
1073 //////////////////////////////////////////////////////////////////////////////// | 1073 //////////////////////////////////////////////////////////////////////////////// |
1074 | 1074 |
1075 GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu, | 1075 GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu, |
1076 GrGLUniformManager*
uniformManager, | 1076 GrGLProgramDataMana
ger* programResourceManager, |
1077 const GrGLProgramDe
sc& desc) | 1077 const GrGLProgramDe
sc& desc) |
1078 : INHERITED(gpu, uniformManager, desc) { | 1078 : INHERITED(gpu, programResourceManager, desc) { |
1079 SkASSERT(!desc.getHeader().fHasVertexCode); | 1079 SkASSERT(!desc.getHeader().fHasVertexCode); |
1080 SkASSERT(gpu->glCaps().pathRenderingSupport()); | 1080 SkASSERT(gpu->glCaps().pathRenderingSupport()); |
1081 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorIn
put); | 1081 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorIn
put); |
1082 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverag
eInput); | 1082 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverag
eInput); |
1083 } | 1083 } |
1084 | 1084 |
1085 int GrGLFragmentOnlyShaderBuilder::addTexCoordSets(int count) { | 1085 int GrGLFragmentOnlyShaderBuilder::addTexCoordSets(int count) { |
1086 int firstFreeCoordSet = fOutput.fTexCoordSetCnt; | 1086 int firstFreeCoordSet = fOutput.fTexCoordSetCnt; |
1087 fOutput.fTexCoordSetCnt += count; | 1087 fOutput.fTexCoordSetCnt += count; |
1088 SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fOutput.fTexCoor
dSetCnt); | 1088 SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fOutput.fTexCoor
dSetCnt); |
1089 return firstFreeCoordSet; | 1089 return firstFreeCoordSet; |
1090 } | 1090 } |
1091 | 1091 |
1092 GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects( | 1092 GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects( |
1093 const GrEffectStage* effectStages[], | 1093 const GrEffectStage* effectStages[], |
1094 int effectCnt, | 1094 int effectCnt, |
1095 const GrGLProgramDesc::EffectKeyProvider& keyProvider, | 1095 const GrGLProgramDesc::EffectKeyProvider& keyProvider, |
1096 GrGLSLExpr4* inOutFSColor) { | 1096 GrGLSLExpr4* inOutFSColor) { |
1097 | 1097 |
1098 GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this, | 1098 GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this, |
1099 effectCnt); | 1099 effectCnt); |
1100 this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder, | 1100 this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder, |
1101 effectStages, | 1101 effectStages, |
1102 effectCnt, | 1102 effectCnt, |
1103 keyProvider, | 1103 keyProvider, |
1104 inOutFSColor); | 1104 inOutFSColor); |
1105 return pathTexGenEffectsBuilder.finish(); | 1105 return pathTexGenEffectsBuilder.finish(); |
1106 } | 1106 } |
OLD | NEW |