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 "GrDrawEffect.h" | 11 #include "GrDrawEffect.h" |
| 12 #include "GrGpuGL.h" |
12 #include "GrTexture.h" | 13 #include "GrTexture.h" |
| 14 #include "SkRTConf.h" |
| 15 #include "SkTrace.h" |
| 16 |
| 17 #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X) |
| 18 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fGpu->glInterface(), R, X) |
13 | 19 |
14 // number of each input/output type in a single allocation block | 20 // number of each input/output type in a single allocation block |
15 static const int kVarsPerBlock = 8; | 21 static const int kVarsPerBlock = 8; |
16 | 22 |
17 // except FS outputs where we expect 2 at most. | 23 // except FS outputs where we expect 2 at most. |
18 static const int kMaxFSOutputs = 2; | 24 static const int kMaxFSOutputs = 2; |
19 | 25 |
20 // ES2 FS only guarantees mediump and lowp support | 26 // ES2 FS only guarantees mediump and lowp support |
21 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar:
:kMedium_Precision; | 27 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar:
:kMedium_Precision; |
22 | 28 |
23 typedef GrGLUniformManager::UniformHandle UniformHandle; | 29 typedef GrGLUniformManager::UniformHandle UniformHandle; |
| 30 |
| 31 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, |
| 32 "Print the source code for all shaders generated."); |
| 33 |
24 /////////////////////////////////////////////////////////////////////////////// | 34 /////////////////////////////////////////////////////////////////////////////// |
25 | 35 |
26 namespace { | 36 namespace { |
27 | 37 |
| 38 inline const char* color_attribute_name() { return "aColor"; } |
| 39 inline const char* coverage_attribute_name() { return "aCoverage"; } |
| 40 inline const char* declared_color_output_name() { return "fsColorOut"; } |
| 41 inline const char* dual_source_output_name() { return "dualSourceOut"; } |
28 inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen)
{ | 42 inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen)
{ |
29 if (kVec2f_GrSLType == type) { | 43 if (kVec2f_GrSLType == type) { |
30 return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D"; | 44 return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D"; |
31 } else { | 45 } else { |
32 SkASSERT(kVec3f_GrSLType == type); | 46 SkASSERT(kVec3f_GrSLType == type); |
33 return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj
"; | 47 return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj
"; |
34 } | 48 } |
35 } | 49 } |
36 | 50 |
37 /** | 51 /** |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 outAppend->appendf(".%s", swizzle); | 98 outAppend->appendf(".%s", swizzle); |
85 } | 99 } |
86 } | 100 } |
87 | 101 |
88 } | 102 } |
89 | 103 |
90 static const char kDstCopyColorName[] = "_dstColor"; | 104 static const char kDstCopyColorName[] = "_dstColor"; |
91 | 105 |
92 /////////////////////////////////////////////////////////////////////////////// | 106 /////////////////////////////////////////////////////////////////////////////// |
93 | 107 |
94 GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, | 108 GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, |
95 GrGLUniformManager& uniformManager, | 109 GrGLUniformManager& uniformManager, |
96 const GrGLProgramDesc& desc, | 110 const GrGLProgramDesc& desc, |
97 bool needsVertexShader) | 111 bool needsVertexShader) |
98 : fUniforms(kVarsPerBlock) | 112 : fUniforms(kVarsPerBlock) |
99 , fCtxInfo(ctxInfo) | 113 , fGpu(gpu) |
100 , fUniformManager(uniformManager) | 114 , fUniformManager(uniformManager) |
101 , fFSFeaturesAddedMask(0) | 115 , fFSFeaturesAddedMask(0) |
102 , fFSInputs(kVarsPerBlock) | 116 , fFSInputs(kVarsPerBlock) |
103 , fFSOutputs(kMaxFSOutputs) | 117 , fFSOutputs(kMaxFSOutputs) |
104 , fSetupFragPosition(false) | 118 , fSetupFragPosition(false) |
| 119 , fKnownColorValue(kNone_GrSLConstantVec) |
| 120 , fKnownCoverageValue(kNone_GrSLConstantVec) |
| 121 , fHasCustomColorOutput(false) |
| 122 , fHasSecondaryOutput(false) |
105 , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFr
agPosKey) { | 123 , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFr
agPosKey) { |
106 | 124 |
107 const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); | 125 const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); |
108 | 126 |
109 if (needsVertexShader) { | 127 if (needsVertexShader) { |
110 fVertexBuilder.reset(SkNEW_ARGS(VertexBuilder, (this, desc))); | 128 fVertexBuilder.reset(SkNEW_ARGS(VertexBuilder, (this, fGpu, desc))); |
111 } | 129 } |
112 | 130 |
113 // Emit code to read the dst copy textue if necessary. | 131 // Emit code to read the dst copy textue if necessary. |
114 if (kNoDstRead_DstReadKey != header.fDstReadKey && | 132 if (kNoDstRead_DstReadKey != header.fDstReadKey && |
115 GrGLCaps::kNone_FBFetchType == ctxInfo.caps()->fbFetchType()) { | 133 GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) { |
116 bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKe
y); | 134 bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKe
y); |
117 const char* dstCopyTopLeftName; | 135 const char* dstCopyTopLeftName; |
118 const char* dstCopyCoordScaleName; | 136 const char* dstCopyCoordScaleName; |
119 uint32_t configMask; | 137 uint32_t configMask; |
120 if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) { | 138 if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) { |
121 configMask = kA_GrColorComponentFlag; | 139 configMask = kA_GrColorComponentFlag; |
122 } else { | 140 } else { |
123 configMask = kRGBA_GrColorComponentFlags; | 141 configMask = kRGBA_GrColorComponentFlags; |
124 } | 142 } |
125 fDstCopySampler.init(this, configMask, "rgba", 0); | 143 fDstCopySampler.init(this, configMask, "rgba", 0); |
(...skipping 10 matching lines...) Expand all Loading... |
136 this->fsCodeAppend("\t// Read color from copy of the destination.\n"); | 154 this->fsCodeAppend("\t// Read color from copy of the destination.\n"); |
137 this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n", | 155 this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n", |
138 fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); | 156 fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); |
139 if (!topDown) { | 157 if (!topDown) { |
140 this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n"); | 158 this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n"); |
141 } | 159 } |
142 this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName); | 160 this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName); |
143 this->fsAppendTextureLookup(fDstCopySampler, "_dstTexCoord"); | 161 this->fsAppendTextureLookup(fDstCopySampler, "_dstTexCoord"); |
144 this->fsCodeAppend(";\n\n"); | 162 this->fsCodeAppend(";\n\n"); |
145 } | 163 } |
| 164 |
| 165 switch (header.fColorInput) { |
| 166 case GrGLProgramDesc::kAttribute_ColorInput: { |
| 167 SkASSERT(NULL != fVertexBuilder.get()); |
| 168 fVertexBuilder->addAttribute(kVec4f_GrSLType, color_attribute_name()
); |
| 169 const char *vsName, *fsName; |
| 170 fVertexBuilder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsNam
e); |
| 171 fVertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, color_attribut
e_name()); |
| 172 fInputColor = fsName; |
| 173 break; |
| 174 } |
| 175 case GrGLProgramDesc::kUniform_ColorInput: { |
| 176 const char* name; |
| 177 fColorUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibi
lity, |
| 178 kVec4f_GrSLType, "Color", &name); |
| 179 fInputColor = name; |
| 180 break; |
| 181 } |
| 182 case GrGLProgramDesc::kTransBlack_ColorInput: |
| 183 fKnownColorValue = kZeros_GrSLConstantVec; |
| 184 break; |
| 185 case GrGLProgramDesc::kSolidWhite_ColorInput: |
| 186 fKnownColorValue = kOnes_GrSLConstantVec; |
| 187 break; |
| 188 default: |
| 189 GrCrash("Unknown color type."); |
| 190 } |
| 191 |
| 192 switch (header.fCoverageInput) { |
| 193 case GrGLProgramDesc::kAttribute_ColorInput: { |
| 194 SkASSERT(NULL != fVertexBuilder.get()); |
| 195 fVertexBuilder->addAttribute(kVec4f_GrSLType, coverage_attribute_nam
e()); |
| 196 const char *vsName, *fsName; |
| 197 fVertexBuilder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fs
Name); |
| 198 fVertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attri
bute_name()); |
| 199 fInputCoverage = fsName; |
| 200 break; |
| 201 } |
| 202 case GrGLProgramDesc::kUniform_ColorInput: { |
| 203 const char* name; |
| 204 fCoverageUniform = this->addUniform(GrGLShaderBuilder::kFragment_Vis
ibility, |
| 205 kVec4f_GrSLType, "Coverage", &na
me); |
| 206 fInputCoverage = name; |
| 207 break; |
| 208 } |
| 209 case GrGLProgramDesc::kTransBlack_ColorInput: |
| 210 fKnownCoverageValue = kZeros_GrSLConstantVec; |
| 211 break; |
| 212 case GrGLProgramDesc::kSolidWhite_ColorInput: |
| 213 fKnownCoverageValue = kOnes_GrSLConstantVec; |
| 214 break; |
| 215 default: |
| 216 GrCrash("Unknown coverage type."); |
| 217 } |
| 218 |
| 219 if (k110_GrGLSLGeneration != fGpu->glslGeneration()) { |
| 220 fFSOutputs.push_back().set(kVec4f_GrSLType, |
| 221 GrGLShaderVar::kOut_TypeModifier, |
| 222 declared_color_output_name()); |
| 223 fHasCustomColorOutput = true; |
| 224 } |
146 } | 225 } |
147 | 226 |
148 bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) { | 227 bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) { |
149 switch (feature) { | 228 switch (feature) { |
150 case kStandardDerivatives_GLSLFeature: | 229 case kStandardDerivatives_GLSLFeature: |
151 if (!fCtxInfo.caps()->shaderDerivativeSupport()) { | 230 if (!fGpu->glCaps().shaderDerivativeSupport()) { |
152 return false; | 231 return false; |
153 } | 232 } |
154 if (kES_GrGLBinding == fCtxInfo.binding()) { | 233 if (kES_GrGLBinding == fGpu->glBinding()) { |
155 this->addFSFeature(1 << kStandardDerivatives_GLSLFeature, | 234 this->addFSFeature(1 << kStandardDerivatives_GLSLFeature, |
156 "GL_OES_standard_derivatives"); | 235 "GL_OES_standard_derivatives"); |
157 } | 236 } |
158 return true; | 237 return true; |
159 default: | 238 default: |
160 GrCrash("Unexpected GLSLFeature requested."); | 239 GrCrash("Unexpected GLSLFeature requested."); |
161 return false; | 240 return false; |
162 } | 241 } |
163 } | 242 } |
164 | 243 |
165 bool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) { | 244 bool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) { |
166 switch (feature) { | 245 switch (feature) { |
167 case kFragCoordConventions_GLSLPrivateFeature: | 246 case kFragCoordConventions_GLSLPrivateFeature: |
168 if (!fCtxInfo.caps()->fragCoordConventionsSupport()) { | 247 if (!fGpu->glCaps().fragCoordConventionsSupport()) { |
169 return false; | 248 return false; |
170 } | 249 } |
171 if (fCtxInfo.glslGeneration() < k150_GrGLSLGeneration) { | 250 if (fGpu->glslGeneration() < k150_GrGLSLGeneration) { |
172 this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature
, | 251 this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature
, |
173 "GL_ARB_fragment_coord_conventions"); | 252 "GL_ARB_fragment_coord_conventions"); |
174 } | 253 } |
175 return true; | 254 return true; |
176 case kEXTShaderFramebufferFetch_GLSLPrivateFeature: | 255 case kEXTShaderFramebufferFetch_GLSLPrivateFeature: |
177 if (GrGLCaps::kEXT_FBFetchType != fCtxInfo.caps()->fbFetchType()) { | 256 if (GrGLCaps::kEXT_FBFetchType != fGpu->glCaps().fbFetchType()) { |
178 return false; | 257 return false; |
179 } | 258 } |
180 this->addFSFeature(1 << kEXTShaderFramebufferFetch_GLSLPrivateFeatur
e, | 259 this->addFSFeature(1 << kEXTShaderFramebufferFetch_GLSLPrivateFeatur
e, |
181 "GL_EXT_shader_framebuffer_fetch"); | 260 "GL_EXT_shader_framebuffer_fetch"); |
182 return true; | 261 return true; |
183 case kNVShaderFramebufferFetch_GLSLPrivateFeature: | 262 case kNVShaderFramebufferFetch_GLSLPrivateFeature: |
184 if (GrGLCaps::kNV_FBFetchType != fCtxInfo.caps()->fbFetchType()) { | 263 if (GrGLCaps::kNV_FBFetchType != fGpu->glCaps().fbFetchType()) { |
185 return false; | 264 return false; |
186 } | 265 } |
187 this->addFSFeature(1 << kNVShaderFramebufferFetch_GLSLPrivateFeature
, | 266 this->addFSFeature(1 << kNVShaderFramebufferFetch_GLSLPrivateFeature
, |
188 "GL_NV_shader_framebuffer_fetch"); | 267 "GL_NV_shader_framebuffer_fetch"); |
189 return true; | 268 return true; |
190 default: | 269 default: |
191 GrCrash("Unexpected GLSLPrivateFeature requested."); | 270 GrCrash("Unexpected GLSLPrivateFeature requested."); |
192 return false; | 271 return false; |
193 } | 272 } |
194 } | 273 } |
(...skipping 23 matching lines...) Expand all Loading... |
218 const char* GrGLShaderBuilder::dstColor() { | 297 const char* GrGLShaderBuilder::dstColor() { |
219 if (fCodeStage.inStageCode()) { | 298 if (fCodeStage.inStageCode()) { |
220 const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect(); | 299 const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect(); |
221 if (!effect->willReadDstColor()) { | 300 if (!effect->willReadDstColor()) { |
222 GrDebugCrash("GrGLEffect asked for dst color but its generating GrEf
fect " | 301 GrDebugCrash("GrGLEffect asked for dst color but its generating GrEf
fect " |
223 "did not request access."); | 302 "did not request access."); |
224 return ""; | 303 return ""; |
225 } | 304 } |
226 } | 305 } |
227 static const char kFBFetchColorName[] = "gl_LastFragData[0]"; | 306 static const char kFBFetchColorName[] = "gl_LastFragData[0]"; |
228 GrGLCaps::FBFetchType fetchType = fCtxInfo.caps()->fbFetchType(); | 307 GrGLCaps::FBFetchType fetchType = fGpu->glCaps().fbFetchType(); |
229 if (GrGLCaps::kEXT_FBFetchType == fetchType) { | 308 if (GrGLCaps::kEXT_FBFetchType == fetchType) { |
230 SkAssertResult(this->enablePrivateFeature(kEXTShaderFramebufferFetch_GLS
LPrivateFeature)); | 309 SkAssertResult(this->enablePrivateFeature(kEXTShaderFramebufferFetch_GLS
LPrivateFeature)); |
231 return kFBFetchColorName; | 310 return kFBFetchColorName; |
232 } else if (GrGLCaps::kNV_FBFetchType == fetchType) { | 311 } else if (GrGLCaps::kNV_FBFetchType == fetchType) { |
233 SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSL
PrivateFeature)); | 312 SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSL
PrivateFeature)); |
234 return kFBFetchColorName; | 313 return kFBFetchColorName; |
235 } else if (fDstCopySampler.isInitialized()) { | 314 } else if (fDstCopySampler.isInitialized()) { |
236 return kDstCopyColorName; | 315 return kDstCopyColorName; |
237 } else { | 316 } else { |
238 return ""; | 317 return ""; |
239 } | 318 } |
240 } | 319 } |
241 | 320 |
242 void GrGLShaderBuilder::appendTextureLookup(SkString* out, | 321 void GrGLShaderBuilder::appendTextureLookup(SkString* out, |
243 const GrGLShaderBuilder::TextureSamp
ler& sampler, | 322 const GrGLShaderBuilder::TextureSamp
ler& sampler, |
244 const char* coordName, | 323 const char* coordName, |
245 GrSLType varyingType) const { | 324 GrSLType varyingType) const { |
246 SkASSERT(NULL != coordName); | 325 SkASSERT(NULL != coordName); |
247 | 326 |
248 out->appendf("%s(%s, %s)", | 327 out->appendf("%s(%s, %s)", |
249 sample_function_name(varyingType, fCtxInfo.glslGeneration()), | 328 sample_function_name(varyingType, fGpu->glslGeneration()), |
250 this->getUniformCStr(sampler.fSamplerUniform), | 329 this->getUniformCStr(sampler.fSamplerUniform), |
251 coordName); | 330 coordName); |
252 append_swizzle(out, sampler, *fCtxInfo.caps()); | 331 append_swizzle(out, sampler, fGpu->glCaps()); |
253 } | 332 } |
254 | 333 |
255 void GrGLShaderBuilder::fsAppendTextureLookup(const GrGLShaderBuilder::TextureSa
mpler& sampler, | 334 void GrGLShaderBuilder::fsAppendTextureLookup(const GrGLShaderBuilder::TextureSa
mpler& sampler, |
256 const char* coordName, | 335 const char* coordName, |
257 GrSLType varyingType) { | 336 GrSLType varyingType) { |
258 this->appendTextureLookup(&fFSCode, sampler, coordName, varyingType); | 337 this->appendTextureLookup(&fFSCode, sampler, coordName, varyingType); |
259 } | 338 } |
260 | 339 |
261 void GrGLShaderBuilder::fsAppendTextureLookupAndModulate( | 340 void GrGLShaderBuilder::fsAppendTextureLookupAndModulate( |
262 const char* modulation, | 341 const char* modulation, |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 } | 451 } |
373 if (fTopLeftFragPosRead) { | 452 if (fTopLeftFragPosRead) { |
374 if (!fSetupFragPosition) { | 453 if (!fSetupFragPosition) { |
375 fFSInputs.push_back().set(kVec4f_GrSLType, | 454 fFSInputs.push_back().set(kVec4f_GrSLType, |
376 GrGLShaderVar::kIn_TypeModifier, | 455 GrGLShaderVar::kIn_TypeModifier, |
377 "gl_FragCoord", | 456 "gl_FragCoord", |
378 GrGLShaderVar::kDefault_Precision); | 457 GrGLShaderVar::kDefault_Precision); |
379 fSetupFragPosition = true; | 458 fSetupFragPosition = true; |
380 } | 459 } |
381 return "gl_FragCoord"; | 460 return "gl_FragCoord"; |
382 } else if (fCtxInfo.caps()->fragCoordConventionsSupport()) { | 461 } else if (fGpu->glCaps().fragCoordConventionsSupport()) { |
383 if (!fSetupFragPosition) { | 462 if (!fSetupFragPosition) { |
384 SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSL
PrivateFeature)); | 463 SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSL
PrivateFeature)); |
385 fFSInputs.push_back().set(kVec4f_GrSLType, | 464 fFSInputs.push_back().set(kVec4f_GrSLType, |
386 GrGLShaderVar::kIn_TypeModifier, | 465 GrGLShaderVar::kIn_TypeModifier, |
387 "gl_FragCoord", | 466 "gl_FragCoord", |
388 GrGLShaderVar::kDefault_Precision, | 467 GrGLShaderVar::kDefault_Precision, |
389 GrGLShaderVar::kUpperLeft_Origin); | 468 GrGLShaderVar::kUpperLeft_Origin); |
390 fSetupFragPosition = true; | 469 fSetupFragPosition = true; |
391 } | 470 } |
392 return "gl_FragCoord"; | 471 return "gl_FragCoord"; |
(...skipping 25 matching lines...) Expand all Loading... |
418 const char* name, | 497 const char* name, |
419 int argCnt, | 498 int argCnt, |
420 const GrGLShaderVar* args, | 499 const GrGLShaderVar* args, |
421 const char* body, | 500 const char* body, |
422 SkString* outName) { | 501 SkString* outName) { |
423 fFSFunctions.append(GrGLSLTypeString(returnType)); | 502 fFSFunctions.append(GrGLSLTypeString(returnType)); |
424 this->nameVariable(outName, '\0', name); | 503 this->nameVariable(outName, '\0', name); |
425 fFSFunctions.appendf(" %s", outName->c_str()); | 504 fFSFunctions.appendf(" %s", outName->c_str()); |
426 fFSFunctions.append("("); | 505 fFSFunctions.append("("); |
427 for (int i = 0; i < argCnt; ++i) { | 506 for (int i = 0; i < argCnt; ++i) { |
428 args[i].appendDecl(fCtxInfo, &fFSFunctions); | 507 args[i].appendDecl(this->ctxInfo(), &fFSFunctions); |
429 if (i < argCnt - 1) { | 508 if (i < argCnt - 1) { |
430 fFSFunctions.append(", "); | 509 fFSFunctions.append(", "); |
431 } | 510 } |
432 } | 511 } |
433 fFSFunctions.append(") {\n"); | 512 fFSFunctions.append(") {\n"); |
434 fFSFunctions.append(body); | 513 fFSFunctions.append(body); |
435 fFSFunctions.append("}\n\n"); | 514 fFSFunctions.append("}\n\n"); |
436 } | 515 } |
437 | 516 |
438 namespace { | 517 namespace { |
(...skipping 17 matching lines...) Expand all Loading... |
456 GrCrash("Default precision now allowed."); | 535 GrCrash("Default precision now allowed."); |
457 default: | 536 default: |
458 GrCrash("Unknown precision value."); | 537 GrCrash("Unknown precision value."); |
459 } | 538 } |
460 } | 539 } |
461 } | 540 } |
462 } | 541 } |
463 | 542 |
464 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { | 543 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { |
465 for (int i = 0; i < vars.count(); ++i) { | 544 for (int i = 0; i < vars.count(); ++i) { |
466 vars[i].appendDecl(fCtxInfo, out); | 545 vars[i].appendDecl(this->ctxInfo(), out); |
467 out->append(";\n"); | 546 out->append(";\n"); |
468 } | 547 } |
469 } | 548 } |
470 | 549 |
471 void GrGLShaderBuilder::appendUniformDecls(ShaderVisibility visibility, | 550 void GrGLShaderBuilder::appendUniformDecls(ShaderVisibility visibility, |
472 SkString* out) const { | 551 SkString* out) const { |
473 for (int i = 0; i < fUniforms.count(); ++i) { | 552 for (int i = 0; i < fUniforms.count(); ++i) { |
474 if (fUniforms[i].fVisibility & visibility) { | 553 if (fUniforms[i].fVisibility & visibility) { |
475 fUniforms[i].fVariable.appendDecl(fCtxInfo, out); | 554 fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out); |
476 out->append(";\n"); | 555 out->append(";\n"); |
477 } | 556 } |
478 } | 557 } |
479 } | 558 } |
480 | 559 |
481 void GrGLShaderBuilder::fsGetShader(SkString* shaderStr) const { | |
482 *shaderStr = GrGetGLSLVersionDecl(fCtxInfo); | |
483 shaderStr->append(fFSExtensions); | |
484 append_default_precision_qualifier(kDefaultFragmentPrecision, | |
485 fCtxInfo.binding(), | |
486 shaderStr); | |
487 this->appendUniformDecls(kFragment_Visibility, shaderStr); | |
488 this->appendDecls(fFSInputs, shaderStr); | |
489 // We shouldn't have declared outputs on 1.10 | |
490 SkASSERT(k110_GrGLSLGeneration != fCtxInfo.glslGeneration() || fFSOutputs.em
pty()); | |
491 this->appendDecls(fFSOutputs, shaderStr); | |
492 shaderStr->append(fFSFunctions); | |
493 shaderStr->append("void main() {\n"); | |
494 shaderStr->append(fFSCode); | |
495 shaderStr->append("}\n"); | |
496 } | |
497 | |
498 void GrGLShaderBuilder::finished(GrGLuint programID) { | |
499 fUniformManager.getUniformLocations(programID, fUniforms); | |
500 } | |
501 | |
502 void GrGLShaderBuilder::emitEffects( | 560 void GrGLShaderBuilder::emitEffects( |
503 const GrEffectStage* effectStages[], | 561 const GrEffectStage* effectStages[], |
504 const GrBackendEffectFactory::EffectKey effectKeys[], | 562 const GrBackendEffectFactory::EffectKey effectKeys[], |
505 int effectCnt, | 563 int effectCnt, |
506 SkString* fsInOutColor, | 564 SkString* fsInOutColor, |
507 GrSLConstantVec* fsInOutColorKnownValue, | 565 GrSLConstantVec* fsInOutColorKnownValue, |
508 SkTArray<GrGLUniformManager::UniformHandle, true>* effec
tSamplerHandles[], | 566 SkTArray<GrGLUniformManager::UniformHandle, true>* effec
tSamplerHandles[], |
509 GrGLEffect* glEffects[]) { | 567 GrGLEffect* glEffects[]) { |
510 bool effectEmitted = false; | 568 bool effectEmitted = false; |
511 | 569 |
512 SkString inColor = *fsInOutColor; | 570 SkString inColor = *fsInOutColor; |
513 SkString outColor; | 571 SkString outColor; |
514 | 572 |
515 for (int e = 0; e < effectCnt; ++e) { | 573 for (int e = 0; e < effectCnt; ++e) { |
516 SkASSERT(NULL != effectStages[e] && NULL != effectStages[e]->getEffect()
); | 574 SkASSERT(NULL != effectStages[e] && NULL != effectStages[e]->getEffect()
); |
517 const GrEffectStage& stage = *effectStages[e]; | 575 const GrEffectStage& stage = *effectStages[e]; |
518 const GrEffectRef& effect = *stage.getEffect(); | 576 const GrEffectRef& effect = *stage.getEffect(); |
519 | 577 |
520 CodeStage::AutoStageRestore csar(&fCodeStage, &stage); | 578 CodeStage::AutoStageRestore csar(&fCodeStage, &stage); |
521 | 579 |
522 int numTextures = effect->numTextures(); | 580 int numTextures = effect->numTextures(); |
523 SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers; | 581 SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers; |
524 textureSamplers.push_back_n(numTextures); | 582 textureSamplers.push_back_n(numTextures); |
525 for (int t = 0; t < numTextures; ++t) { | 583 for (int t = 0; t < numTextures; ++t) { |
526 textureSamplers[t].init(this, &effect->textureAccess(t), t); | 584 textureSamplers[t].init(this, &effect->textureAccess(t), t); |
527 effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUnifor
m); | 585 effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUnifor
m); |
528 } | 586 } |
529 GrDrawEffect drawEffect(stage, fVertexBuilder.get() | 587 GrDrawEffect drawEffect(stage, NULL != fVertexBuilder.get() |
530 && fVertexBuilder->hasExplicitLocalCoords
()); | 588 && fVertexBuilder->hasExplicitLocalCoords
()); |
531 | 589 |
532 int numAttributes = stage.getVertexAttribIndexCount(); | 590 int numAttributes = stage.getVertexAttribIndexCount(); |
533 const int* attributeIndices = stage.getVertexAttribIndices(); | 591 const int* attributeIndices = stage.getVertexAttribIndices(); |
534 SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames; | 592 SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames; |
535 for (int a = 0; a < numAttributes; ++a) { | 593 for (int a = 0; a < numAttributes; ++a) { |
536 // TODO: Make addAttribute mangle the name. | 594 // TODO: Make addAttribute mangle the name. |
537 SkASSERT(fVertexBuilder.get()); | 595 SkASSERT(NULL != fVertexBuilder.get()); |
538 SkString attributeName("aAttr"); | 596 SkString attributeName("aAttr"); |
539 attributeName.appendS32(attributeIndices[a]); | 597 attributeName.appendS32(attributeIndices[a]); |
540 fVertexBuilder->addEffectAttribute(attributeIndices[a], | 598 fVertexBuilder->addEffectAttribute(attributeIndices[a], |
541 effect->vertexAttribType(a), | 599 effect->vertexAttribType(a), |
542 attributeName); | 600 attributeName); |
543 } | 601 } |
544 | 602 |
545 glEffects[e] = effect->getFactory().createGLInstance(drawEffect); | 603 glEffects[e] = effect->getFactory().createGLInstance(drawEffect); |
546 | 604 |
547 if (kZeros_GrSLConstantVec == *fsInOutColorKnownValue) { | 605 if (kZeros_GrSLConstantVec == *fsInOutColorKnownValue) { |
548 // Effects have no way to communicate zeros, they treat an empty str
ing as ones. | 606 // Effects have no way to communicate zeros, they treat an empty str
ing as ones. |
549 this->nameVariable(&inColor, '\0', "input"); | 607 this->nameVariable(&inColor, '\0', "input"); |
550 this->fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZero
sVecf(4)); | 608 this->fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZero
sVecf(4)); |
551 } | 609 } |
552 | 610 |
553 // create var to hold stage result | 611 // create var to hold stage result |
554 this->nameVariable(&outColor, '\0', "output"); | 612 this->nameVariable(&outColor, '\0', "output"); |
555 this->fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); | 613 this->fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); |
556 | 614 |
557 // Enclose custom code in a block to avoid namespace conflicts | 615 // Enclose custom code in a block to avoid namespace conflicts |
558 SkString openBrace; | 616 SkString openBrace; |
559 openBrace.printf("\t{ // Stage %d: %s\n", fCodeStage.stageIndex(), glEff
ects[e]->name()); | 617 openBrace.printf("\t{ // Stage %d: %s\n", fCodeStage.stageIndex(), glEff
ects[e]->name()); |
560 if (fVertexBuilder.get()) { | 618 if (NULL != fVertexBuilder.get()) { |
561 fVertexBuilder->vsCodeAppend(openBrace.c_str()); | 619 fVertexBuilder->vsCodeAppend(openBrace.c_str()); |
562 } | 620 } |
563 this->fsCodeAppend(openBrace.c_str()); | 621 this->fsCodeAppend(openBrace.c_str()); |
564 | 622 |
565 glEffects[e]->emitCode(this, | 623 glEffects[e]->emitCode(this, |
566 drawEffect, | 624 drawEffect, |
567 effectKeys[e], | 625 effectKeys[e], |
568 outColor.c_str(), | 626 outColor.c_str(), |
569 inColor.isEmpty() ? NULL : inColor.c_str(), | 627 inColor.isEmpty() ? NULL : inColor.c_str(), |
570 textureSamplers); | 628 textureSamplers); |
571 | 629 |
572 if (fVertexBuilder.get()) { | 630 if (NULL != fVertexBuilder.get()) { |
573 fVertexBuilder->vsCodeAppend("\t}\n"); | 631 fVertexBuilder->vsCodeAppend("\t}\n"); |
574 } | 632 } |
575 this->fsCodeAppend("\t}\n"); | 633 this->fsCodeAppend("\t}\n"); |
576 | 634 |
577 inColor = outColor; | 635 inColor = outColor; |
578 *fsInOutColorKnownValue = kNone_GrSLConstantVec; | 636 *fsInOutColorKnownValue = kNone_GrSLConstantVec; |
579 effectEmitted = true; | 637 effectEmitted = true; |
580 } | 638 } |
581 | 639 |
582 if (effectEmitted) { | 640 if (effectEmitted) { |
583 *fsInOutColor = outColor; | 641 *fsInOutColor = outColor; |
584 } | 642 } |
585 } | 643 } |
586 | 644 |
| 645 const char* GrGLShaderBuilder::getColorOutputName() const { |
| 646 return fHasCustomColorOutput ? declared_color_output_name() : "gl_FragColor"
; |
| 647 } |
| 648 |
| 649 const char* GrGLShaderBuilder::enableSecondaryOutput() { |
| 650 if (!fHasSecondaryOutput) { |
| 651 fFSOutputs.push_back().set(kVec4f_GrSLType, |
| 652 GrGLShaderVar::kOut_TypeModifier, |
| 653 dual_source_output_name()); |
| 654 fHasSecondaryOutput = true; |
| 655 } |
| 656 return dual_source_output_name(); |
| 657 } |
| 658 |
| 659 |
| 660 bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) { |
| 661 SK_TRACE_EVENT0("GrGLShaderBuilder::finish"); |
| 662 |
| 663 GrGLuint programId = 0; |
| 664 GL_CALL_RET(programId, CreateProgram()); |
| 665 if (!programId) { |
| 666 return false; |
| 667 } |
| 668 |
| 669 if (!this->compileAndAttachShaders(programId)) { |
| 670 GL_CALL(DeleteProgram(programId)); |
| 671 return false; |
| 672 } |
| 673 |
| 674 this->bindProgramLocations(programId); |
| 675 |
| 676 GL_CALL(LinkProgram(programId)); |
| 677 GrGLint linked = GR_GL_INIT_ZERO; |
| 678 GL_CALL(GetProgramiv(programId, GR_GL_LINK_STATUS, &linked)); |
| 679 if (!linked) { |
| 680 GrGLint infoLen = GR_GL_INIT_ZERO; |
| 681 GL_CALL(GetProgramiv(programId, GR_GL_INFO_LOG_LENGTH, &infoLen)); |
| 682 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger |
| 683 if (infoLen > 0) { |
| 684 // retrieve length even though we don't need it to workaround |
| 685 // bug in chrome cmd buffer param validation. |
| 686 GrGLsizei length = GR_GL_INIT_ZERO; |
| 687 GL_CALL(GetProgramInfoLog(programId, |
| 688 infoLen+1, |
| 689 &length, |
| 690 (char*)log.get())); |
| 691 GrPrintf((char*)log.get()); |
| 692 } |
| 693 SkDEBUGFAIL("Error linking program"); |
| 694 GL_CALL(DeleteProgram(programId)); |
| 695 return false; |
| 696 } |
| 697 |
| 698 fUniformManager.getUniformLocations(programId, fUniforms); |
| 699 *outProgramId = programId; |
| 700 return true; |
| 701 } |
| 702 |
| 703 namespace { |
| 704 // Compiles a GL shader, attaches it to a program, and releases the shader's ref
erence. |
| 705 // (That way there's no need to hang on to the GL shader id and delete it later.
) |
| 706 bool attach_shader(const GrGLInterface* gli, |
| 707 GrGLuint programId, |
| 708 GrGLenum type, |
| 709 const SkString& shaderSrc) { |
| 710 GrGLuint shaderId; |
| 711 GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); |
| 712 if (0 == shaderId) { |
| 713 return false; |
| 714 } |
| 715 |
| 716 const GrGLchar* sourceStr = shaderSrc.c_str(); |
| 717 int sourceLength = shaderSrc.size(); |
| 718 GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); |
| 719 |
| 720 GrGLint compiled = GR_GL_INIT_ZERO; |
| 721 GR_GL_CALL(gli, CompileShader(shaderId)); |
| 722 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled)); |
| 723 |
| 724 if (!compiled) { |
| 725 GrGLint infoLen = GR_GL_INIT_ZERO; |
| 726 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen)); |
| 727 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger |
| 728 if (infoLen > 0) { |
| 729 // retrieve length even though we don't need it to workaround bug in
chrome cmd buffer |
| 730 // param validation. |
| 731 GrGLsizei length = GR_GL_INIT_ZERO; |
| 732 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, |
| 733 &length, (char*)log.get())); |
| 734 GrPrintf(shaderSrc.c_str()); |
| 735 GrPrintf("\n%s", log.get()); |
| 736 } |
| 737 SkDEBUGFAIL("Shader compilation failed!"); |
| 738 GR_GL_CALL(gli, DeleteShader(shaderId)); |
| 739 return false; |
| 740 } else if (c_PrintShaders) { |
| 741 GrPrintf(shaderSrc.c_str()); |
| 742 GrPrintf("\n"); |
| 743 } |
| 744 |
| 745 GR_GL_CALL(gli, AttachShader(programId, shaderId)); |
| 746 GR_GL_CALL(gli, DeleteShader(shaderId)); |
| 747 return true; |
| 748 } |
| 749 |
| 750 } |
| 751 |
| 752 bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { |
| 753 if (NULL != fVertexBuilder.get() && !fVertexBuilder->compileAndAttachShaders
(programId)) { |
| 754 return false; |
| 755 } |
| 756 |
| 757 SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); |
| 758 fragShaderSrc.append(fFSExtensions); |
| 759 append_default_precision_qualifier(kDefaultFragmentPrecision, |
| 760 fGpu->glBinding(), |
| 761 &fragShaderSrc); |
| 762 this->appendUniformDecls(kFragment_Visibility, &fragShaderSrc); |
| 763 this->appendDecls(fFSInputs, &fragShaderSrc); |
| 764 // We shouldn't have declared outputs on 1.10 |
| 765 SkASSERT(k110_GrGLSLGeneration != fGpu->glslGeneration() || fFSOutputs.empty
()); |
| 766 this->appendDecls(fFSOutputs, &fragShaderSrc); |
| 767 fragShaderSrc.append(fFSFunctions); |
| 768 fragShaderSrc.append("void main() {\n"); |
| 769 fragShaderSrc.append(fFSCode); |
| 770 fragShaderSrc.append("}\n"); |
| 771 if (!attach_shader(fGpu->glInterface(), programId, GR_GL_FRAGMENT_SHADER, fr
agShaderSrc)) { |
| 772 return false; |
| 773 } |
| 774 |
| 775 return true; |
| 776 } |
| 777 |
| 778 void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) const { |
| 779 if (NULL != fVertexBuilder.get()) { |
| 780 fVertexBuilder->bindProgramLocations(programId); |
| 781 } |
| 782 |
| 783 if (fHasCustomColorOutput) { |
| 784 GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name())
); |
| 785 } |
| 786 if (fHasSecondaryOutput) { |
| 787 GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_
name())); |
| 788 } |
| 789 } |
| 790 |
| 791 const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const { |
| 792 return fGpu->ctxInfo(); |
| 793 } |
| 794 |
587 //////////////////////////////////////////////////////////////////////////// | 795 //////////////////////////////////////////////////////////////////////////// |
588 | 796 |
589 GrGLShaderBuilder::VertexBuilder::VertexBuilder(GrGLShaderBuilder* parent, | 797 GrGLShaderBuilder::VertexBuilder::VertexBuilder(GrGLShaderBuilder* parent, |
| 798 GrGpuGL* gpu, |
590 const GrGLProgramDesc& desc) | 799 const GrGLProgramDesc& desc) |
591 : fVSAttrs(kVarsPerBlock) | 800 : fParent(parent) |
| 801 , fGpu(gpu) |
| 802 , fDesc(desc) |
| 803 , fVSAttrs(kVarsPerBlock) |
592 , fVSOutputs(kVarsPerBlock) | 804 , fVSOutputs(kVarsPerBlock) |
593 , fGSInputs(kVarsPerBlock) | 805 , fGSInputs(kVarsPerBlock) |
594 , fGSOutputs(kVarsPerBlock) | 806 , fGSOutputs(kVarsPerBlock) { |
595 , fParent(parent) | 807 |
596 #if GR_GL_EXPERIMENTAL_GS | 808 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
597 , fUsesGS(SkToBool(desc.getHeader().fExperimentalGS)) | |
598 #else | |
599 , fUsesGS(false) | |
600 #endif | |
601 { | |
602 const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); | |
603 | 809 |
604 fPositionVar = &fVSAttrs.push_back(); | 810 fPositionVar = &fVSAttrs.push_back(); |
605 fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "
aPosition"); | 811 fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "
aPosition"); |
606 if (-1 != header.fLocalCoordAttributeIndex) { | 812 if (-1 != header.fLocalCoordAttributeIndex) { |
607 fLocalCoordsVar = &fVSAttrs.push_back(); | 813 fLocalCoordsVar = &fVSAttrs.push_back(); |
608 fLocalCoordsVar->set(kVec2f_GrSLType, | 814 fLocalCoordsVar->set(kVec2f_GrSLType, |
609 GrGLShaderVar::kAttribute_TypeModifier, | 815 GrGLShaderVar::kAttribute_TypeModifier, |
610 "aLocalCoords"); | 816 "aLocalCoords"); |
611 } else { | 817 } else { |
612 fLocalCoordsVar = fPositionVar; | 818 fLocalCoordsVar = fPositionVar; |
613 } | 819 } |
| 820 |
| 821 const char* viewMName; |
| 822 fViewMatrixUniform = fParent->addUniform(GrGLShaderBuilder::kVertex_Visibili
ty, |
| 823 kMat33f_GrSLType, "ViewM", &viewMNa
me); |
| 824 |
| 825 this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" |
| 826 "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", |
| 827 viewMName, fPositionVar->c_str()); |
| 828 |
| 829 // we output point size in the GS if present |
| 830 if (header.fEmitsPointSize |
| 831 #if GR_GL_EXPERIMENTAL_GS |
| 832 && !header.fExperimentalGS |
| 833 #endif |
| 834 ) { |
| 835 this->vsCodeAppend("\tgl_PointSize = 1.0;\n"); |
| 836 } |
614 } | 837 } |
615 | 838 |
616 bool GrGLShaderBuilder::VertexBuilder::addAttribute(GrSLType type, | 839 bool GrGLShaderBuilder::VertexBuilder::addAttribute(GrSLType type, |
617 const char* name) { | 840 const char* name) { |
618 for (int i = 0; i < fVSAttrs.count(); ++i) { | 841 for (int i = 0; i < fVSAttrs.count(); ++i) { |
619 const GrGLShaderVar& attr = fVSAttrs[i]; | 842 const GrGLShaderVar& attr = fVSAttrs[i]; |
620 // if attribute already added, don't add it again | 843 // if attribute already added, don't add it again |
621 if (attr.getName().equals(name)) { | 844 if (attr.getName().equals(name)) { |
622 SkASSERT(attr.getType() == type); | 845 SkASSERT(attr.getType() == type); |
623 return false; | 846 return false; |
(...skipping 23 matching lines...) Expand all Loading... |
647 fVSOutputs.push_back(); | 870 fVSOutputs.push_back(); |
648 fVSOutputs.back().setType(type); | 871 fVSOutputs.back().setType(type); |
649 fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); | 872 fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); |
650 fParent->nameVariable(fVSOutputs.back().accessName(), 'v', name); | 873 fParent->nameVariable(fVSOutputs.back().accessName(), 'v', name); |
651 | 874 |
652 if (vsOutName) { | 875 if (vsOutName) { |
653 *vsOutName = fVSOutputs.back().getName().c_str(); | 876 *vsOutName = fVSOutputs.back().getName().c_str(); |
654 } | 877 } |
655 // input to FS comes either from VS or GS | 878 // input to FS comes either from VS or GS |
656 const SkString* fsName; | 879 const SkString* fsName; |
657 if (fUsesGS) { | 880 #if GR_GL_EXPERIMENTAL_GS |
| 881 if (fDesc.getHeader().fExperimentalGS) { |
658 // if we have a GS take each varying in as an array | 882 // if we have a GS take each varying in as an array |
659 // and output as non-array. | 883 // and output as non-array. |
660 fGSInputs.push_back(); | 884 fGSInputs.push_back(); |
661 fGSInputs.back().setType(type); | 885 fGSInputs.back().setType(type); |
662 fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier)
; | 886 fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier)
; |
663 fGSInputs.back().setUnsizedArray(); | 887 fGSInputs.back().setUnsizedArray(); |
664 *fGSInputs.back().accessName() = fVSOutputs.back().getName(); | 888 *fGSInputs.back().accessName() = fVSOutputs.back().getName(); |
665 fGSOutputs.push_back(); | 889 fGSOutputs.push_back(); |
666 fGSOutputs.back().setType(type); | 890 fGSOutputs.back().setType(type); |
667 fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifie
r); | 891 fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifie
r); |
668 fParent->nameVariable(fGSOutputs.back().accessName(), 'g', name); | 892 fParent->nameVariable(fGSOutputs.back().accessName(), 'g', name); |
669 fsName = fGSOutputs.back().accessName(); | 893 fsName = fGSOutputs.back().accessName(); |
670 } else { | 894 } else |
| 895 #endif |
| 896 { |
671 fsName = fVSOutputs.back().accessName(); | 897 fsName = fVSOutputs.back().accessName(); |
672 } | 898 } |
673 fParent->fsInputAppend().set(type, | 899 fParent->fsInputAppend().set(type, |
674 GrGLShaderVar::kVaryingIn_TypeModifier, | 900 GrGLShaderVar::kVaryingIn_TypeModifier, |
675 *fsName); | 901 *fsName); |
676 if (fsInName) { | 902 if (fsInName) { |
677 *fsInName = fsName->c_str(); | 903 *fsInName = fsName->c_str(); |
678 } | 904 } |
679 } | 905 } |
680 | 906 |
681 void GrGLShaderBuilder::VertexBuilder::vsGetShader(SkString* shaderStr) const { | |
682 *shaderStr = GrGetGLSLVersionDecl(fParent->ctxInfo()); | |
683 fParent->appendUniformDecls(kVertex_Visibility, shaderStr); | |
684 fParent->appendDecls(fVSAttrs, shaderStr); | |
685 fParent->appendDecls(fVSOutputs, shaderStr); | |
686 shaderStr->append("void main() {\n"); | |
687 shaderStr->append(fVSCode); | |
688 shaderStr->append("}\n"); | |
689 } | |
690 | |
691 void GrGLShaderBuilder::VertexBuilder::gsGetShader(SkString* shaderStr) const { | |
692 if (!fUsesGS) { | |
693 shaderStr->reset(); | |
694 return; | |
695 } | |
696 | |
697 *shaderStr = GrGetGLSLVersionDecl(fParent->ctxInfo()); | |
698 shaderStr->append(fGSHeader); | |
699 fParent->appendDecls(fGSInputs, shaderStr); | |
700 fParent->appendDecls(fGSOutputs, shaderStr); | |
701 shaderStr->append("void main() {\n"); | |
702 shaderStr->append(fGSCode); | |
703 shaderStr->append("}\n"); | |
704 } | |
705 | |
706 | |
707 const SkString* GrGLShaderBuilder::VertexBuilder::getEffectAttributeName(int att
ributeIndex) const { | 907 const SkString* GrGLShaderBuilder::VertexBuilder::getEffectAttributeName(int att
ributeIndex) const { |
708 const AttributePair* attribEnd = this->getEffectAttributes().end(); | 908 const AttributePair* attribEnd = fEffectAttributes.end(); |
709 for (const AttributePair* attrib = this->getEffectAttributes().begin(); | 909 for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attr
ibEnd; ++attrib) { |
710 attrib != attribEnd; | |
711 ++attrib) { | |
712 if (attrib->fIndex == attributeIndex) { | 910 if (attrib->fIndex == attributeIndex) { |
713 return &attrib->fName; | 911 return &attrib->fName; |
714 } | 912 } |
715 } | 913 } |
716 | 914 |
717 return NULL; | 915 return NULL; |
718 } | 916 } |
| 917 |
| 918 bool GrGLShaderBuilder::VertexBuilder::compileAndAttachShaders(GrGLuint programI
d) const { |
| 919 SkString vertShaderSrc(GrGetGLSLVersionDecl(fParent->ctxInfo())); |
| 920 fParent->appendUniformDecls(kVertex_Visibility, &vertShaderSrc); |
| 921 fParent->appendDecls(fVSAttrs, &vertShaderSrc); |
| 922 fParent->appendDecls(fVSOutputs, &vertShaderSrc); |
| 923 vertShaderSrc.append("void main() {\n"); |
| 924 vertShaderSrc.append(fVSCode); |
| 925 vertShaderSrc.append("}\n"); |
| 926 if (!attach_shader(fGpu->glInterface(), programId, GR_GL_VERTEX_SHADER, vert
ShaderSrc)) { |
| 927 return false; |
| 928 } |
| 929 |
| 930 #if GR_GL_EXPERIMENTAL_GS |
| 931 if (fDesc.getHeader().fExperimentalGS) { |
| 932 SkASSERT(fGpu->glslGeneration() >= k150_GrGLSLGeneration); |
| 933 SkString geomShaderSrc(GrGetGLSLVersionDecl(fParent->ctxInfo())); |
| 934 geomShaderSrc.append("layout(triangles) in;\n" |
| 935 "layout(triangle_strip, max_vertices = 6) out;\n"); |
| 936 fParent->appendDecls(fGSInputs, &geomShaderSrc); |
| 937 fParent->appendDecls(fGSOutputs, &geomShaderSrc); |
| 938 geomShaderSrc.append("void main() {\n"); |
| 939 geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n" |
| 940 "\t\tgl_Position = gl_in[i].gl_Position;\n"); |
| 941 if (fDesc.getHeader().fEmitsPointSize) { |
| 942 geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n"); |
| 943 } |
| 944 SkASSERT(fGSInputs.count() == fGSOutputs.count()); |
| 945 for (int i = 0; i < fGSInputs.count(); ++i) { |
| 946 geomShaderSrc.appendf("\t\t%s = %s[i];\n", |
| 947 fGSOutputs[i].getName().c_str(), |
| 948 fGSInputs[i].getName().c_str()); |
| 949 } |
| 950 geomShaderSrc.append("\t\tEmitVertex();\n" |
| 951 "\t}\n" |
| 952 "\tEndPrimitive();\n"); |
| 953 geomShaderSrc.append("}\n"); |
| 954 if (!attach_shader(fGpu->glInterface(), programId, GR_GL_GEOMETRY_SHADER
, geomShaderSrc)) { |
| 955 return false; |
| 956 } |
| 957 } |
| 958 #endif |
| 959 |
| 960 return true; |
| 961 } |
| 962 |
| 963 void GrGLShaderBuilder::VertexBuilder::bindProgramLocations(GrGLuint programId)
const { |
| 964 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
| 965 |
| 966 // Bind the attrib locations to same values for all shaders |
| 967 SkASSERT(-1 != header.fPositionAttributeIndex); |
| 968 GL_CALL(BindAttribLocation(programId, |
| 969 header.fPositionAttributeIndex, |
| 970 fPositionVar->c_str())); |
| 971 if (-1 != header.fLocalCoordAttributeIndex) { |
| 972 GL_CALL(BindAttribLocation(programId, |
| 973 header.fLocalCoordAttributeIndex, |
| 974 fLocalCoordsVar->c_str())); |
| 975 } |
| 976 if (-1 != header.fColorAttributeIndex) { |
| 977 GL_CALL(BindAttribLocation(programId, |
| 978 header.fColorAttributeIndex, |
| 979 color_attribute_name())); |
| 980 } |
| 981 if (-1 != header.fCoverageAttributeIndex) { |
| 982 GL_CALL(BindAttribLocation(programId, |
| 983 header.fCoverageAttributeIndex, |
| 984 coverage_attribute_name())); |
| 985 } |
| 986 |
| 987 const AttributePair* attribEnd = fEffectAttributes.end(); |
| 988 for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attr
ibEnd; ++attrib) { |
| 989 GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_s
tr())); |
| 990 } |
| 991 } |
OLD | NEW |