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