| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "gl/GrGLShaderBuilder.h" | 8 #include "gl/GrGLShaderBuilder.h" |
| 9 #include "gl/GrGLProgram.h" | 9 #include "gl/GrGLProgram.h" |
| 10 #include "gl/GrGLUniformHandle.h" | 10 #include "gl/GrGLUniformHandle.h" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 out->appendf(".%s", swizzle); | 82 out->appendf(".%s", swizzle); |
| 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, | |
| 93 GrGLProgramDataManager* pdman, | |
| 94 const GrGLProgramDesc& desc, | |
| 95 const GrEffectStage* inColorStages[], | |
| 96 const GrEffectStage* inCoverageStages[], | |
| 97 GenProgramOutput* output) { | |
| 98 SkAutoTDelete<GrGLShaderBuilder> builder; | |
| 99 if (desc.getHeader().fHasVertexCode ||!gpu->shouldUseFixedFunctionTexturing(
)) { | |
| 100 builder.reset(SkNEW_ARGS(GrGLFullShaderBuilder, (gpu, pdman, desc))); | |
| 101 } else { | |
| 102 builder.reset(SkNEW_ARGS(GrGLFragmentOnlyShaderBuilder, (gpu, pdman, des
c))); | |
| 103 } | |
| 104 if (builder->genProgram(inColorStages, inCoverageStages)) { | |
| 105 *output = builder->getOutput(); | |
| 106 return true; | |
| 107 } | |
| 108 return false; | |
| 109 } | |
| 110 | |
| 111 bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[], | 92 bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[], |
| 112 const GrEffectStage* coverageStages[]) { | 93 const GrEffectStage* coverageStages[]) { |
| 113 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); | 94 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); |
| 114 | 95 |
| 115 /////////////////////////////////////////////////////////////////////////// | 96 /////////////////////////////////////////////////////////////////////////// |
| 116 // emit code to read the dst copy texture, if necessary | 97 // emit code to read the dst copy texture, if necessary |
| 117 if (kNoDstRead_DstReadKey != header.fDstReadKey && !fGpu->glCaps().fbFetchSu
pport()) { | 98 if (kNoDstRead_DstReadKey != header.fDstReadKey && !fGpu->glCaps().fbFetchSu
pport()) { |
| 118 bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKe
y); | 99 bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKe
y); |
| 119 const char* dstCopyTopLeftName; | 100 const char* dstCopyTopLeftName; |
| 120 const char* dstCopyCoordScaleName; | 101 const char* dstCopyCoordScaleName; |
| 121 const char* dstCopySamplerName; | 102 const char* dstCopySamplerName; |
| 122 uint32_t configMask; | 103 uint32_t configMask; |
| 123 if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) { | 104 if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) { |
| 124 configMask = kA_GrColorComponentFlag; | 105 configMask = kA_GrColorComponentFlag; |
| 125 } else { | 106 } else { |
| 126 configMask = kRGBA_GrColorComponentFlags; | 107 configMask = kRGBA_GrColorComponentFlags; |
| 127 } | 108 } |
| 128 fOutput.fUniformHandles.fDstCopySamplerUni = | 109 fUniformHandles.fDstCopySamplerUni = |
| 129 this->addUniform(kFragment_Visibility, kSampler2D_GrSLType, "DstCopy
Sampler", | 110 this->addUniform(kFragment_Visibility, kSampler2D_GrSLType, "DstCopy
Sampler", |
| 130 &dstCopySamplerName); | 111 &dstCopySamplerName); |
| 131 fOutput.fUniformHandles.fDstCopyTopLeftUni = | 112 fUniformHandles.fDstCopyTopLeftUni = |
| 132 this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyUppe
rLeft", | 113 this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyUppe
rLeft", |
| 133 &dstCopyTopLeftName); | 114 &dstCopyTopLeftName); |
| 134 fOutput.fUniformHandles.fDstCopyScaleUni = | 115 fUniformHandles.fDstCopyScaleUni = |
| 135 this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyCoor
dScale", | 116 this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyCoor
dScale", |
| 136 &dstCopyCoordScaleName); | 117 &dstCopyCoordScaleName); |
| 137 const char* fragPos = this->fragmentPosition(); | 118 const char* fragPos = this->fragmentPosition(); |
| 138 this->fsCodeAppend("\t// Read color from copy of the destination.\n"); | 119 this->fsCodeAppend("\t// Read color from copy of the destination.\n"); |
| 139 this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n", | 120 this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n", |
| 140 fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); | 121 fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); |
| 141 if (!topDown) { | 122 if (!topDown) { |
| 142 this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n"); | 123 this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n"); |
| 143 } | 124 } |
| 144 this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName); | 125 this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName); |
| 145 append_texture_lookup(&fFSCode, | 126 append_texture_lookup(&fFSCode, |
| 146 fGpu, | 127 fGpu, |
| 147 dstCopySamplerName, | 128 dstCopySamplerName, |
| 148 "_dstTexCoord", | 129 "_dstTexCoord", |
| 149 configMask, | 130 configMask, |
| 150 "rgba"); | 131 "rgba"); |
| 151 this->fsCodeAppend(";\n\n"); | 132 this->fsCodeAppend(";\n\n"); |
| 152 } | 133 } |
| 153 | 134 |
| 154 /////////////////////////////////////////////////////////////////////////// | 135 /////////////////////////////////////////////////////////////////////////// |
| 155 // get the initial color and coverage to feed into the first effect in each
effect chain | 136 // get the initial color and coverage to feed into the first effect in each
effect chain |
| 156 | 137 |
| 157 GrGLSLExpr4 inputColor; | 138 GrGLSLExpr4 inputColor; |
| 158 GrGLSLExpr4 inputCoverage; | 139 GrGLSLExpr4 inputCoverage; |
| 159 | 140 |
| 160 if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) { | 141 if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) { |
| 161 const char* name; | 142 const char* name; |
| 162 fOutput.fUniformHandles.fColorUni = | 143 fUniformHandles.fColorUni = |
| 163 this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrS
LType, "Color", | 144 this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrS
LType, "Color", |
| 164 &name); | 145 &name); |
| 165 inputColor = GrGLSLExpr4(name); | 146 inputColor = GrGLSLExpr4(name); |
| 166 } | 147 } |
| 167 | 148 |
| 168 if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) { | 149 if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) { |
| 169 const char* name; | 150 const char* name; |
| 170 fOutput.fUniformHandles.fCoverageUni = | 151 fUniformHandles.fCoverageUni = |
| 171 this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrS
LType, "Coverage", | 152 this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrS
LType, "Coverage", |
| 172 &name); | 153 &name); |
| 173 inputCoverage = GrGLSLExpr4(name); | 154 inputCoverage = GrGLSLExpr4(name); |
| 174 } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput)
{ | 155 } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput)
{ |
| 175 inputCoverage = GrGLSLExpr4(1); | 156 inputCoverage = GrGLSLExpr4(1); |
| 176 } | 157 } |
| 177 | 158 |
| 178 if (k110_GrGLSLGeneration != fGpu->glslGeneration()) { | 159 if (k110_GrGLSLGeneration != fGpu->glslGeneration()) { |
| 179 fFSOutputs.push_back().set(kVec4f_GrSLType, | 160 fFSOutputs.push_back().set(kVec4f_GrSLType, |
| 180 GrGLShaderVar::kOut_TypeModifier, | 161 GrGLShaderVar::kOut_TypeModifier, |
| 181 declared_color_output_name()); | 162 declared_color_output_name()); |
| 182 fHasCustomColorOutput = true; | 163 fHasCustomColorOutput = true; |
| 183 } | 164 } |
| 184 | 165 |
| 185 this->emitCodeBeforeEffects(&inputColor, &inputCoverage); | 166 this->emitCodeBeforeEffects(&inputColor, &inputCoverage); |
| 186 | 167 |
| 187 /////////////////////////////////////////////////////////////////////////// | 168 /////////////////////////////////////////////////////////////////////////// |
| 188 // emit the per-effect code for both color and coverage effects | 169 // emit the per-effect code for both color and coverage effects |
| 189 | 170 |
| 190 GrGLProgramDesc::EffectKeyProvider colorKeyProvider( | 171 GrGLProgramDesc::EffectKeyProvider colorKeyProvider( |
| 191 &this->desc(), GrGLProgramDesc::EffectKeyProvider::kColor_EffectType); | 172 &this->desc(), GrGLProgramDesc::EffectKeyProvider::kColor_EffectType); |
| 192 fOutput.fColorEffects.reset(this->createAndEmitEffects(colorStages, | 173 fColorEffects.reset(this->createAndEmitEffects(colorStages, |
| 193 this->desc().numColor
Effects(), | 174 this->desc().numColorEffects(
), |
| 194 colorKeyProvider, | 175 colorKeyProvider, |
| 195 &inputColor)); | 176 &inputColor)); |
| 196 | 177 |
| 197 GrGLProgramDesc::EffectKeyProvider coverageKeyProvider( | 178 GrGLProgramDesc::EffectKeyProvider coverageKeyProvider( |
| 198 &this->desc(), GrGLProgramDesc::EffectKeyProvider::kCoverage_EffectType)
; | 179 &this->desc(), GrGLProgramDesc::EffectKeyProvider::kCoverage_EffectType)
; |
| 199 fOutput.fCoverageEffects.reset(this->createAndEmitEffects(coverageStages, | 180 fCoverageEffects.reset(this->createAndEmitEffects(coverageStages, |
| 200 this->desc().numCoverageEffects(), | 181 this->desc().numCoverageEf
fects(), |
| 201 coverageKeyProvider, | 182 coverageKeyProvider, |
| 202 &inputCoverage)); | 183 &inputCoverage)); |
| 203 | 184 |
| 204 this->emitCodeAfterEffects(); | 185 this->emitCodeAfterEffects(); |
| 205 | 186 |
| 206 /////////////////////////////////////////////////////////////////////////// | 187 /////////////////////////////////////////////////////////////////////////// |
| 207 // write the secondary color output if necessary | 188 // write the secondary color output if necessary |
| 208 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { | 189 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { |
| 209 const char* secondaryOutputName = this->enableSecondaryOutput(); | 190 const char* secondaryOutputName = this->enableSecondaryOutput(); |
| 210 | 191 |
| 211 // default coeff to ones for kCoverage_DualSrcOutput | 192 // default coeff to ones for kCoverage_DualSrcOutput |
| 212 GrGLSLExpr4 coeff(1); | 193 GrGLSLExpr4 coeff(1); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 240 if (!this->finish()) { | 221 if (!this->finish()) { |
| 241 return false; | 222 return false; |
| 242 } | 223 } |
| 243 | 224 |
| 244 return true; | 225 return true; |
| 245 } | 226 } |
| 246 | 227 |
| 247 ////////////////////////////////////////////////////////////////////////////// | 228 ////////////////////////////////////////////////////////////////////////////// |
| 248 | 229 |
| 249 GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, | 230 GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, |
| 250 GrGLProgramDataManager* programResourceMana
ger, | |
| 251 const GrGLProgramDesc& desc) | 231 const GrGLProgramDesc& desc) |
| 252 : fDesc(desc) | 232 : fHasVertexShader(false) |
| 233 , fTexCoordSetCnt(0) |
| 234 , fProgramID(0) |
| 235 , fDesc(desc) |
| 253 , fGpu(gpu) | 236 , fGpu(gpu) |
| 254 , fProgramDataManager(SkRef(programResourceManager)) | |
| 255 , fFSFeaturesAddedMask(0) | 237 , fFSFeaturesAddedMask(0) |
| 256 , fFSInputs(kVarsPerBlock) | 238 , fFSInputs(kVarsPerBlock) |
| 257 , fFSOutputs(kMaxFSOutputs) | 239 , fFSOutputs(kMaxFSOutputs) |
| 258 , fUniforms(kVarsPerBlock) | 240 , fUniforms(kVarsPerBlock) |
| 259 , fSetupFragPosition(false) | 241 , fSetupFragPosition(false) |
| 260 , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFr
agPosKey) | 242 , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFr
agPosKey) |
| 261 , fHasCustomColorOutput(false) | 243 , fHasCustomColorOutput(false) |
| 262 , fHasSecondaryOutput(false) { | 244 , fHasSecondaryOutput(false) { |
| 263 } | 245 } |
| 264 | 246 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 SkDEBUGFAIL("GrGLEffect asked for dst color but its generating GrEff
ect " | 290 SkDEBUGFAIL("GrGLEffect asked for dst color but its generating GrEff
ect " |
| 309 "did not request access."); | 291 "did not request access."); |
| 310 return ""; | 292 return ""; |
| 311 } | 293 } |
| 312 } | 294 } |
| 313 | 295 |
| 314 if (fGpu->glCaps().fbFetchSupport()) { | 296 if (fGpu->glCaps().fbFetchSupport()) { |
| 315 this->addFSFeature(1 << (kLastGLSLPrivateFeature + 1), | 297 this->addFSFeature(1 << (kLastGLSLPrivateFeature + 1), |
| 316 fGpu->glCaps().fbFetchExtensionString()); | 298 fGpu->glCaps().fbFetchExtensionString()); |
| 317 return fGpu->glCaps().fbFetchColorName(); | 299 return fGpu->glCaps().fbFetchColorName(); |
| 318 } else if (fOutput.fUniformHandles.fDstCopySamplerUni.isValid()) { | 300 } else if (fUniformHandles.fDstCopySamplerUni.isValid()) { |
| 319 return kDstCopyColorName; | 301 return kDstCopyColorName; |
| 320 } else { | 302 } else { |
| 321 return ""; | 303 return ""; |
| 322 } | 304 } |
| 323 } | 305 } |
| 324 | 306 |
| 325 void GrGLShaderBuilder::appendTextureLookup(SkString* out, | 307 void GrGLShaderBuilder::appendTextureLookup(SkString* out, |
| 326 const GrGLShaderBuilder::TextureSamp
ler& sampler, | 308 const GrGLShaderBuilder::TextureSamp
ler& sampler, |
| 327 const char* coordName, | 309 const char* coordName, |
| 328 GrSLType varyingType) const { | 310 GrSLType varyingType) const { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 GrGLProgramDataManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_
t visibility, | 380 GrGLProgramDataManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_
t visibility, |
| 399 GrSLTyp
e type, | 381 GrSLTyp
e type, |
| 400 const c
har* name, | 382 const c
har* name, |
| 401 int cou
nt, | 383 int cou
nt, |
| 402 const c
har** outName) { | 384 const c
har** outName) { |
| 403 SkASSERT(name && strlen(name)); | 385 SkASSERT(name && strlen(name)); |
| 404 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); | 386 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); |
| 405 SkASSERT(0 == (~kVisibilityMask & visibility)); | 387 SkASSERT(0 == (~kVisibilityMask & visibility)); |
| 406 SkASSERT(0 != visibility); | 388 SkASSERT(0 != visibility); |
| 407 | 389 |
| 408 BuilderUniform& uni = fUniforms.push_back(); | 390 UniformInfo& uni = fUniforms.push_back(); |
| 409 UniformHandle h = GrGLProgramDataManager::UniformHandle::CreateFromUniformIn
dex(fUniforms.count() - 1); | |
| 410 SkDEBUGCODE(UniformHandle h2 =) | |
| 411 fProgramDataManager->appendUniform(type, count); | |
| 412 // We expect the uniform manager to initially have no uniforms and that all
uniforms are added | |
| 413 // by this function. Therefore, the handles should match. | |
| 414 SkASSERT(h2 == h); | |
| 415 uni.fVariable.setType(type); | 391 uni.fVariable.setType(type); |
| 416 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); | 392 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); |
| 417 this->nameVariable(uni.fVariable.accessName(), 'u', name); | 393 this->nameVariable(uni.fVariable.accessName(), 'u', name); |
| 418 uni.fVariable.setArrayCount(count); | 394 uni.fVariable.setArrayCount(count); |
| 419 uni.fVisibility = visibility; | 395 uni.fVisibility = visibility; |
| 420 | 396 |
| 421 // If it is visible in both the VS and FS, the precision must match. | 397 // If it is visible in both the VS and FS, the precision must match. |
| 422 // We declare a default FS precision, but not a default VS. So set the var | 398 // We declare a default FS precision, but not a default VS. So set the var |
| 423 // to use the default FS precision. | 399 // to use the default FS precision. |
| 424 if ((kVertex_Visibility | kFragment_Visibility) == visibility) { | 400 if ((kVertex_Visibility | kFragment_Visibility) == visibility) { |
| 425 // the fragment and vertex precisions must match | 401 // the fragment and vertex precisions must match |
| 426 uni.fVariable.setPrecision(kDefaultFragmentPrecision); | 402 uni.fVariable.setPrecision(kDefaultFragmentPrecision); |
| 427 } | 403 } |
| 428 | 404 |
| 429 if (NULL != outName) { | 405 if (NULL != outName) { |
| 430 *outName = uni.fVariable.c_str(); | 406 *outName = uni.fVariable.c_str(); |
| 431 } | 407 } |
| 432 | 408 return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fUnifor
ms.count() - 1); |
| 433 return h; | |
| 434 } | 409 } |
| 435 | 410 |
| 436 SkString GrGLShaderBuilder::ensureFSCoords2D(const TransformedCoordsArray& coord
s, int index) { | 411 SkString GrGLShaderBuilder::ensureFSCoords2D(const TransformedCoordsArray& coord
s, int index) { |
| 437 if (kVec3f_GrSLType != coords[index].type()) { | 412 if (kVec3f_GrSLType != coords[index].type()) { |
| 438 SkASSERT(kVec2f_GrSLType == coords[index].type()); | 413 SkASSERT(kVec2f_GrSLType == coords[index].type()); |
| 439 return coords[index].getName(); | 414 return coords[index].getName(); |
| 440 } | 415 } |
| 441 | 416 |
| 442 SkString coords2D("coords2D"); | 417 SkString coords2D("coords2D"); |
| 443 if (0 != index) { | 418 if (0 != index) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 GrGLShaderVar::kUpperLeft_Origin); | 451 GrGLShaderVar::kUpperLeft_Origin); |
| 477 fSetupFragPosition = true; | 452 fSetupFragPosition = true; |
| 478 } | 453 } |
| 479 return "gl_FragCoord"; | 454 return "gl_FragCoord"; |
| 480 } else { | 455 } else { |
| 481 static const char* kCoordName = "fragCoordYDown"; | 456 static const char* kCoordName = "fragCoordYDown"; |
| 482 if (!fSetupFragPosition) { | 457 if (!fSetupFragPosition) { |
| 483 // temporarily change the stage index because we're inserting non-st
age code. | 458 // temporarily change the stage index because we're inserting non-st
age code. |
| 484 CodeStage::AutoStageRestore csar(&fCodeStage, NULL); | 459 CodeStage::AutoStageRestore csar(&fCodeStage, NULL); |
| 485 | 460 |
| 486 SkASSERT(!fOutput.fUniformHandles.fRTHeightUni.isValid()); | 461 SkASSERT(!fUniformHandles.fRTHeightUni.isValid()); |
| 487 const char* rtHeightName; | 462 const char* rtHeightName; |
| 488 | 463 |
| 489 fOutput.fUniformHandles.fRTHeightUni = | 464 fUniformHandles.fRTHeightUni = |
| 490 this->addUniform(kFragment_Visibility, kFloat_GrSLType, "RTHeigh
t", &rtHeightName); | 465 this->addUniform(kFragment_Visibility, kFloat_GrSLType, "RTHeigh
t", &rtHeightName); |
| 491 | 466 |
| 492 // Using glFragCoord.zw for the last two components tickles an Adren
o driver bug that | 467 // Using glFragCoord.zw for the last two components tickles an Adren
o driver bug that |
| 493 // causes programs to fail to link. Making this function return a ve
c2() didn't fix the | 468 // causes programs to fail to link. Making this function return a ve
c2() didn't fix the |
| 494 // problem but using 1.0 for the last two components does. | 469 // problem but using 1.0 for the last two components does. |
| 495 this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_Fra
gCoord.y, 1.0, " | 470 this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_Fra
gCoord.y, 1.0, " |
| 496 "1.0);\n", kCoordName, rtHeightName); | 471 "1.0);\n", kCoordName, rtHeightName); |
| 497 fSetupFragPosition = true; | 472 fSetupFragPosition = true; |
| 498 } | 473 } |
| 499 SkASSERT(fOutput.fUniformHandles.fRTHeightUni.isValid()); | 474 SkASSERT(fUniformHandles.fRTHeightUni.isValid()); |
| 500 return kCoordName; | 475 return kCoordName; |
| 501 } | 476 } |
| 502 } | 477 } |
| 503 | 478 |
| 504 void GrGLShaderBuilder::fsEmitFunction(GrSLType returnType, | 479 void GrGLShaderBuilder::fsEmitFunction(GrSLType returnType, |
| 505 const char* name, | 480 const char* name, |
| 506 int argCnt, | 481 int argCnt, |
| 507 const GrGLShaderVar* args, | 482 const GrGLShaderVar* args, |
| 508 const char* body, | 483 const char* body, |
| 509 SkString* outName) { | 484 SkString* outName) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 if (!fHasSecondaryOutput) { | 595 if (!fHasSecondaryOutput) { |
| 621 fFSOutputs.push_back().set(kVec4f_GrSLType, | 596 fFSOutputs.push_back().set(kVec4f_GrSLType, |
| 622 GrGLShaderVar::kOut_TypeModifier, | 597 GrGLShaderVar::kOut_TypeModifier, |
| 623 dual_source_output_name()); | 598 dual_source_output_name()); |
| 624 fHasSecondaryOutput = true; | 599 fHasSecondaryOutput = true; |
| 625 } | 600 } |
| 626 return dual_source_output_name(); | 601 return dual_source_output_name(); |
| 627 } | 602 } |
| 628 | 603 |
| 629 bool GrGLShaderBuilder::finish() { | 604 bool GrGLShaderBuilder::finish() { |
| 630 SkASSERT(0 == fOutput.fProgramID); | 605 SkASSERT(0 == fProgramID); |
| 631 GL_CALL_RET(fOutput.fProgramID, CreateProgram()); | 606 GL_CALL_RET(fProgramID, CreateProgram()); |
| 632 if (!fOutput.fProgramID) { | 607 if (!fProgramID) { |
| 633 return false; | 608 return false; |
| 634 } | 609 } |
| 635 | 610 |
| 636 SkTDArray<GrGLuint> shadersToDelete; | 611 SkTDArray<GrGLuint> shadersToDelete; |
| 637 | 612 |
| 638 if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) { | 613 if (!this->compileAndAttachShaders(fProgramID, &shadersToDelete)) { |
| 639 GL_CALL(DeleteProgram(fOutput.fProgramID)); | 614 GL_CALL(DeleteProgram(fProgramID)); |
| 640 return false; | 615 return false; |
| 641 } | 616 } |
| 642 | 617 |
| 643 this->bindProgramLocations(fOutput.fProgramID); | 618 this->bindProgramLocations(fProgramID); |
| 644 if (fProgramDataManager->isUsingBindUniform()) { | |
| 645 fProgramDataManager->getUniformLocations(fOutput.fProgramID, fUniforms); | |
| 646 } | |
| 647 | 619 |
| 648 GL_CALL(LinkProgram(fOutput.fProgramID)); | 620 GL_CALL(LinkProgram(fProgramID)); |
| 649 | 621 |
| 650 // Calling GetProgramiv is expensive in Chromium. Assume success in release
builds. | 622 // Calling GetProgramiv is expensive in Chromium. Assume success in release
builds. |
| 651 bool checkLinked = !fGpu->ctxInfo().isChromium(); | 623 bool checkLinked = !fGpu->ctxInfo().isChromium(); |
| 652 #ifdef SK_DEBUG | 624 #ifdef SK_DEBUG |
| 653 checkLinked = true; | 625 checkLinked = true; |
| 654 #endif | 626 #endif |
| 655 if (checkLinked) { | 627 if (checkLinked) { |
| 656 GrGLint linked = GR_GL_INIT_ZERO; | 628 GrGLint linked = GR_GL_INIT_ZERO; |
| 657 GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_LINK_STATUS, &linked)); | 629 GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked)); |
| 658 if (!linked) { | 630 if (!linked) { |
| 659 GrGLint infoLen = GR_GL_INIT_ZERO; | 631 GrGLint infoLen = GR_GL_INIT_ZERO; |
| 660 GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_INFO_LOG_LENGTH, &inf
oLen)); | 632 GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen)); |
| 661 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debug
ger | 633 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debug
ger |
| 662 if (infoLen > 0) { | 634 if (infoLen > 0) { |
| 663 // retrieve length even though we don't need it to workaround | 635 // retrieve length even though we don't need it to workaround |
| 664 // bug in chrome cmd buffer param validation. | 636 // bug in chrome cmd buffer param validation. |
| 665 GrGLsizei length = GR_GL_INIT_ZERO; | 637 GrGLsizei length = GR_GL_INIT_ZERO; |
| 666 GL_CALL(GetProgramInfoLog(fOutput.fProgramID, | 638 GL_CALL(GetProgramInfoLog(fProgramID, |
| 667 infoLen+1, | 639 infoLen+1, |
| 668 &length, | 640 &length, |
| 669 (char*)log.get())); | 641 (char*)log.get())); |
| 670 GrPrintf((char*)log.get()); | 642 GrPrintf((char*)log.get()); |
| 671 } | 643 } |
| 672 SkDEBUGFAIL("Error linking program"); | 644 SkDEBUGFAIL("Error linking program"); |
| 673 GL_CALL(DeleteProgram(fOutput.fProgramID)); | 645 GL_CALL(DeleteProgram(fProgramID)); |
| 674 fOutput.fProgramID = 0; | 646 fProgramID = 0; |
| 675 return false; | 647 return false; |
| 676 } | 648 } |
| 677 } | 649 } |
| 678 | 650 |
| 679 if (!fProgramDataManager->isUsingBindUniform()) { | 651 this->resolveProgramLocations(fProgramID); |
| 680 fProgramDataManager->getUniformLocations(fOutput.fProgramID, fUniforms); | |
| 681 } | |
| 682 | 652 |
| 683 for (int i = 0; i < shadersToDelete.count(); ++i) { | 653 for (int i = 0; i < shadersToDelete.count(); ++i) { |
| 684 GL_CALL(DeleteShader(shadersToDelete[i])); | 654 GL_CALL(DeleteShader(shadersToDelete[i])); |
| 685 } | 655 } |
| 686 | 656 |
| 687 return true; | 657 return true; |
| 688 } | 658 } |
| 689 | 659 |
| 690 // Compiles a GL shader and attaches it to a program. Returns the shader ID if | 660 // Compiles a GL shader and attaches it to a program. Returns the shader ID if |
| 691 // successful, or 0 if not. | 661 // successful, or 0 if not. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 GrGLuint fragShaderId = attach_shader(fGpu->glContext(), programId, GR_GL_FR
AGMENT_SHADER, fragShaderSrc); | 739 GrGLuint fragShaderId = attach_shader(fGpu->glContext(), programId, GR_GL_FR
AGMENT_SHADER, fragShaderSrc); |
| 770 if (!fragShaderId) { | 740 if (!fragShaderId) { |
| 771 return false; | 741 return false; |
| 772 } | 742 } |
| 773 | 743 |
| 774 *shaderIds->append() = fragShaderId; | 744 *shaderIds->append() = fragShaderId; |
| 775 | 745 |
| 776 return true; | 746 return true; |
| 777 } | 747 } |
| 778 | 748 |
| 779 void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) const { | 749 void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) { |
| 780 if (fHasCustomColorOutput) { | 750 if (fHasCustomColorOutput) { |
| 781 GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name())
); | 751 GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name())
); |
| 782 } | 752 } |
| 783 if (fHasSecondaryOutput) { | 753 if (fHasSecondaryOutput) { |
| 784 GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_
name())); | 754 GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_
name())); |
| 785 } | 755 } |
| 756 // skbug.com/2056 |
| 757 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= NULL; |
| 758 if (usingBindUniform) { |
| 759 int count = fUniforms.count(); |
| 760 for (int i = 0; i < count; ++i) { |
| 761 GL_CALL(BindUniformLocation(programId, i, fUniforms[i].fVariable.c_s
tr())); |
| 762 fUniforms[i].fLocation = i; |
| 763 } |
| 764 } |
| 765 } |
| 766 |
| 767 void GrGLShaderBuilder::resolveProgramLocations(GrGLuint programId) { |
| 768 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= NULL; |
| 769 if (!usingBindUniform) { |
| 770 int count = fUniforms.count(); |
| 771 for (int i = 0; i < count; ++i) { |
| 772 GrGLint location; |
| 773 GL_CALL_RET(location, |
| 774 GetUniformLocation(programId, fUniforms[i].fVariable.c_s
tr())); |
| 775 fUniforms[i].fLocation = location; |
| 776 } |
| 777 } |
| 786 } | 778 } |
| 787 | 779 |
| 788 const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const { | 780 const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const { |
| 789 return fGpu->ctxInfo(); | 781 return fGpu->ctxInfo(); |
| 790 } | 782 } |
| 791 | 783 |
| 792 //////////////////////////////////////////////////////////////////////////////// | 784 //////////////////////////////////////////////////////////////////////////////// |
| 793 | 785 |
| 794 GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, | 786 GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, |
| 795 GrGLProgramDataManager* programReso
urceManager, | |
| 796 const GrGLProgramDesc& desc) | 787 const GrGLProgramDesc& desc) |
| 797 : INHERITED(gpu, programResourceManager, desc) | 788 : INHERITED(gpu, desc) |
| 798 , fVSAttrs(kVarsPerBlock) | 789 , fVSAttrs(kVarsPerBlock) |
| 799 , fVSOutputs(kVarsPerBlock) | 790 , fVSOutputs(kVarsPerBlock) |
| 800 , fGSInputs(kVarsPerBlock) | 791 , fGSInputs(kVarsPerBlock) |
| 801 , fGSOutputs(kVarsPerBlock) { | 792 , fGSOutputs(kVarsPerBlock) { |
| 802 } | 793 } |
| 803 | 794 |
| 804 void GrGLFullShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr
4* coverage) { | 795 void GrGLFullShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr
4* coverage) { |
| 805 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); | 796 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); |
| 806 | 797 |
| 807 fOutput.fHasVertexShader = true; | 798 fHasVertexShader = true; |
| 808 | 799 |
| 809 fPositionVar = &fVSAttrs.push_back(); | 800 fPositionVar = &fVSAttrs.push_back(); |
| 810 fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "
aPosition"); | 801 fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "
aPosition"); |
| 811 if (-1 != header.fLocalCoordAttributeIndex) { | 802 if (-1 != header.fLocalCoordAttributeIndex) { |
| 812 fLocalCoordsVar = &fVSAttrs.push_back(); | 803 fLocalCoordsVar = &fVSAttrs.push_back(); |
| 813 fLocalCoordsVar->set(kVec2f_GrSLType, | 804 fLocalCoordsVar->set(kVec2f_GrSLType, |
| 814 GrGLShaderVar::kAttribute_TypeModifier, | 805 GrGLShaderVar::kAttribute_TypeModifier, |
| 815 "aLocalCoords"); | 806 "aLocalCoords"); |
| 816 } else { | 807 } else { |
| 817 fLocalCoordsVar = fPositionVar; | 808 fLocalCoordsVar = fPositionVar; |
| 818 } | 809 } |
| 819 | 810 |
| 820 const char* viewMName; | 811 const char* viewMName; |
| 821 fOutput.fUniformHandles.fViewMatrixUni = | 812 fUniformHandles.fViewMatrixUni = |
| 822 this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kMat33f_GrSLType
, "ViewM", | 813 this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kMat33f_GrSLType
, "ViewM", |
| 823 &viewMName); | 814 &viewMName); |
| 824 | 815 |
| 825 // Transform the position into Skia's device coords. | 816 // Transform the position into Skia's device coords. |
| 826 this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n", | 817 this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n", |
| 827 viewMName, fPositionVar->c_str()); | 818 viewMName, fPositionVar->c_str()); |
| 828 | 819 |
| 829 // we output point size in the GS if present | 820 // we output point size in the GS if present |
| 830 if (header.fEmitsPointSize | 821 if (header.fEmitsPointSize |
| 831 #if GR_GL_EXPERIMENTAL_GS | 822 #if GR_GL_EXPERIMENTAL_GS |
| (...skipping 15 matching lines...) Expand all Loading... |
| 847 this->addAttribute(kVec4f_GrSLType, coverage_attribute_name()); | 838 this->addAttribute(kVec4f_GrSLType, coverage_attribute_name()); |
| 848 const char *vsName, *fsName; | 839 const char *vsName, *fsName; |
| 849 this->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); | 840 this->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); |
| 850 this->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name()); | 841 this->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name()); |
| 851 *coverage = fsName; | 842 *coverage = fsName; |
| 852 } | 843 } |
| 853 } | 844 } |
| 854 | 845 |
| 855 void GrGLFullShaderBuilder::emitCodeAfterEffects() { | 846 void GrGLFullShaderBuilder::emitCodeAfterEffects() { |
| 856 const char* rtAdjustName; | 847 const char* rtAdjustName; |
| 857 fOutput.fUniformHandles.fRTAdjustmentUni = | 848 fUniformHandles.fRTAdjustmentUni = |
| 858 this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kVec4f_GrSLType,
"rtAdjustment", | 849 this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kVec4f_GrSLType,
"rtAdjustment", |
| 859 &rtAdjustName); | 850 &rtAdjustName); |
| 860 | 851 |
| 861 // Transform from Skia's device coords to GL's normalized device coords. | 852 // Transform from Skia's device coords to GL's normalized device coords. |
| 862 this->vsCodeAppendf( | 853 this->vsCodeAppendf( |
| 863 "\tgl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.
z);\n", | 854 "\tgl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.
z);\n", |
| 864 rtAdjustName, rtAdjustName); | 855 rtAdjustName, rtAdjustName); |
| 865 } | 856 } |
| 866 | 857 |
| 867 bool GrGLFullShaderBuilder::addAttribute(GrSLType type, const char* name) { | 858 bool GrGLFullShaderBuilder::addAttribute(GrSLType type, const char* name) { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 if (!geomShaderId) { | 990 if (!geomShaderId) { |
| 1000 return false; | 991 return false; |
| 1001 } | 992 } |
| 1002 *shaderIds->append() = geomShaderId; | 993 *shaderIds->append() = geomShaderId; |
| 1003 } | 994 } |
| 1004 #endif | 995 #endif |
| 1005 | 996 |
| 1006 return this->INHERITED::compileAndAttachShaders(programId, shaderIds); | 997 return this->INHERITED::compileAndAttachShaders(programId, shaderIds); |
| 1007 } | 998 } |
| 1008 | 999 |
| 1009 void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const { | 1000 void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) { |
| 1010 this->INHERITED::bindProgramLocations(programId); | 1001 this->INHERITED::bindProgramLocations(programId); |
| 1011 | 1002 |
| 1012 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); | 1003 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); |
| 1013 | 1004 |
| 1014 // Bind the attrib locations to same values for all shaders | 1005 // Bind the attrib locations to same values for all shaders |
| 1015 SkASSERT(-1 != header.fPositionAttributeIndex); | 1006 SkASSERT(-1 != header.fPositionAttributeIndex); |
| 1016 GL_CALL(BindAttribLocation(programId, | 1007 GL_CALL(BindAttribLocation(programId, |
| 1017 header.fPositionAttributeIndex, | 1008 header.fPositionAttributeIndex, |
| 1018 fPositionVar->c_str())); | 1009 fPositionVar->c_str())); |
| 1019 if (-1 != header.fLocalCoordAttributeIndex) { | 1010 if (-1 != header.fLocalCoordAttributeIndex) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1034 | 1025 |
| 1035 const AttributePair* attribEnd = fEffectAttributes.end(); | 1026 const AttributePair* attribEnd = fEffectAttributes.end(); |
| 1036 for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attr
ibEnd; ++attrib) { | 1027 for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attr
ibEnd; ++attrib) { |
| 1037 GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_s
tr())); | 1028 GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_s
tr())); |
| 1038 } | 1029 } |
| 1039 } | 1030 } |
| 1040 | 1031 |
| 1041 //////////////////////////////////////////////////////////////////////////////// | 1032 //////////////////////////////////////////////////////////////////////////////// |
| 1042 | 1033 |
| 1043 GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu, | 1034 GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu, |
| 1044 GrGLProgramDataMana
ger* programResourceManager, | |
| 1045 const GrGLProgramDe
sc& desc) | 1035 const GrGLProgramDe
sc& desc) |
| 1046 : INHERITED(gpu, programResourceManager, desc) { | 1036 : INHERITED(gpu, desc) { |
| 1047 SkASSERT(!desc.getHeader().fHasVertexCode); | 1037 SkASSERT(!desc.getHeader().fHasVertexCode); |
| 1048 SkASSERT(gpu->glCaps().pathRenderingSupport()); | 1038 SkASSERT(gpu->glCaps().pathRenderingSupport()); |
| 1049 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorIn
put); | 1039 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorIn
put); |
| 1050 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverag
eInput); | 1040 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverag
eInput); |
| 1051 } | 1041 } |
| 1052 | 1042 |
| 1053 int GrGLFragmentOnlyShaderBuilder::addTexCoordSets(int count) { | 1043 int GrGLFragmentOnlyShaderBuilder::addTexCoordSets(int count) { |
| 1054 int firstFreeCoordSet = fOutput.fTexCoordSetCnt; | 1044 int firstFreeCoordSet = fTexCoordSetCnt; |
| 1055 fOutput.fTexCoordSetCnt += count; | 1045 fTexCoordSetCnt += count; |
| 1056 SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fOutput.fTexCoor
dSetCnt); | 1046 SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fTexCoordSetCnt)
; |
| 1057 return firstFreeCoordSet; | 1047 return firstFreeCoordSet; |
| 1058 } | 1048 } |
| 1059 | 1049 |
| 1060 GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects( | 1050 GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects( |
| 1061 const GrEffectStage* effectStages[], | 1051 const GrEffectStage* effectStages[], |
| 1062 int effectCnt, | 1052 int effectCnt, |
| 1063 const GrGLProgramDesc::EffectKeyProvider& keyProvider, | 1053 const GrGLProgramDesc::EffectKeyProvider& keyProvider, |
| 1064 GrGLSLExpr4* inOutFSColor) { | 1054 GrGLSLExpr4* inOutFSColor) { |
| 1065 | 1055 |
| 1066 GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this, | 1056 GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this, |
| 1067 effectCnt); | 1057 effectCnt); |
| 1068 this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder, | 1058 this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder, |
| 1069 effectStages, | 1059 effectStages, |
| 1070 effectCnt, | 1060 effectCnt, |
| 1071 keyProvider, | 1061 keyProvider, |
| 1072 inOutFSColor); | 1062 inOutFSColor); |
| 1073 return pathTexGenEffectsBuilder.finish(); | 1063 return pathTexGenEffectsBuilder.finish(); |
| 1074 } | 1064 } |
| OLD | NEW |