| 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 && | 98 if (kNoDstRead_DstReadKey != header.fDstReadKey && |
| 118 GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) { | 99 GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) { |
| 119 bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKe
y); | 100 bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKe
y); |
| 120 const char* dstCopyTopLeftName; | 101 const char* dstCopyTopLeftName; |
| 121 const char* dstCopyCoordScaleName; | 102 const char* dstCopyCoordScaleName; |
| 122 const char* dstCopySamplerName; | 103 const char* dstCopySamplerName; |
| 123 uint32_t configMask; | 104 uint32_t configMask; |
| 124 if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) { | 105 if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) { |
| 125 configMask = kA_GrColorComponentFlag; | 106 configMask = kA_GrColorComponentFlag; |
| 126 } else { | 107 } else { |
| 127 configMask = kRGBA_GrColorComponentFlags; | 108 configMask = kRGBA_GrColorComponentFlags; |
| 128 } | 109 } |
| 129 fOutput.fUniformHandles.fDstCopySamplerUni = | 110 fUniformHandles.fDstCopySamplerUni = |
| 130 this->addUniform(kFragment_Visibility, kSampler2D_GrSLType, "DstCopy
Sampler", | 111 this->addUniform(kFragment_Visibility, kSampler2D_GrSLType, "DstCopy
Sampler", |
| 131 &dstCopySamplerName); | 112 &dstCopySamplerName); |
| 132 fOutput.fUniformHandles.fDstCopyTopLeftUni = | 113 fUniformHandles.fDstCopyTopLeftUni = |
| 133 this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyUppe
rLeft", | 114 this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyUppe
rLeft", |
| 134 &dstCopyTopLeftName); | 115 &dstCopyTopLeftName); |
| 135 fOutput.fUniformHandles.fDstCopyScaleUni = | 116 fUniformHandles.fDstCopyScaleUni = |
| 136 this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyCoor
dScale", | 117 this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyCoor
dScale", |
| 137 &dstCopyCoordScaleName); | 118 &dstCopyCoordScaleName); |
| 138 const char* fragPos = this->fragmentPosition(); | 119 const char* fragPos = this->fragmentPosition(); |
| 139 this->fsCodeAppend("\t// Read color from copy of the destination.\n"); | 120 this->fsCodeAppend("\t// Read color from copy of the destination.\n"); |
| 140 this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n", | 121 this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n", |
| 141 fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); | 122 fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); |
| 142 if (!topDown) { | 123 if (!topDown) { |
| 143 this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n"); | 124 this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n"); |
| 144 } | 125 } |
| 145 this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName); | 126 this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName); |
| 146 append_texture_lookup(&fFSCode, | 127 append_texture_lookup(&fFSCode, |
| 147 fGpu, | 128 fGpu, |
| 148 dstCopySamplerName, | 129 dstCopySamplerName, |
| 149 "_dstTexCoord", | 130 "_dstTexCoord", |
| 150 configMask, | 131 configMask, |
| 151 "rgba"); | 132 "rgba"); |
| 152 this->fsCodeAppend(";\n\n"); | 133 this->fsCodeAppend(";\n\n"); |
| 153 } | 134 } |
| 154 | 135 |
| 155 /////////////////////////////////////////////////////////////////////////// | 136 /////////////////////////////////////////////////////////////////////////// |
| 156 // get the initial color and coverage to feed into the first effect in each
effect chain | 137 // get the initial color and coverage to feed into the first effect in each
effect chain |
| 157 | 138 |
| 158 GrGLSLExpr4 inputColor; | 139 GrGLSLExpr4 inputColor; |
| 159 GrGLSLExpr4 inputCoverage; | 140 GrGLSLExpr4 inputCoverage; |
| 160 | 141 |
| 161 if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) { | 142 if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) { |
| 162 const char* name; | 143 const char* name; |
| 163 fOutput.fUniformHandles.fColorUni = | 144 fUniformHandles.fColorUni = |
| 164 this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrS
LType, "Color", | 145 this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrS
LType, "Color", |
| 165 &name); | 146 &name); |
| 166 inputColor = GrGLSLExpr4(name); | 147 inputColor = GrGLSLExpr4(name); |
| 167 } | 148 } |
| 168 | 149 |
| 169 if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) { | 150 if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) { |
| 170 const char* name; | 151 const char* name; |
| 171 fOutput.fUniformHandles.fCoverageUni = | 152 fUniformHandles.fCoverageUni = |
| 172 this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrS
LType, "Coverage", | 153 this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrS
LType, "Coverage", |
| 173 &name); | 154 &name); |
| 174 inputCoverage = GrGLSLExpr4(name); | 155 inputCoverage = GrGLSLExpr4(name); |
| 175 } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput)
{ | 156 } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput)
{ |
| 176 inputCoverage = GrGLSLExpr4(1); | 157 inputCoverage = GrGLSLExpr4(1); |
| 177 } | 158 } |
| 178 | 159 |
| 179 if (k110_GrGLSLGeneration != fGpu->glslGeneration()) { | 160 if (k110_GrGLSLGeneration != fGpu->glslGeneration()) { |
| 180 fFSOutputs.push_back().set(kVec4f_GrSLType, | 161 fFSOutputs.push_back().set(kVec4f_GrSLType, |
| 181 GrGLShaderVar::kOut_TypeModifier, | 162 GrGLShaderVar::kOut_TypeModifier, |
| 182 declared_color_output_name()); | 163 declared_color_output_name()); |
| 183 fHasCustomColorOutput = true; | 164 fHasCustomColorOutput = true; |
| 184 } | 165 } |
| 185 | 166 |
| 186 this->emitCodeBeforeEffects(&inputColor, &inputCoverage); | 167 this->emitCodeBeforeEffects(&inputColor, &inputCoverage); |
| 187 | 168 |
| 188 /////////////////////////////////////////////////////////////////////////// | 169 /////////////////////////////////////////////////////////////////////////// |
| 189 // emit the per-effect code for both color and coverage effects | 170 // emit the per-effect code for both color and coverage effects |
| 190 | 171 |
| 191 GrGLProgramDesc::EffectKeyProvider colorKeyProvider( | 172 GrGLProgramDesc::EffectKeyProvider colorKeyProvider( |
| 192 &this->desc(), GrGLProgramDesc::EffectKeyProvider::kColor_EffectType); | 173 &this->desc(), GrGLProgramDesc::EffectKeyProvider::kColor_EffectType); |
| 193 fOutput.fColorEffects.reset(this->createAndEmitEffects(colorStages, | 174 fColorEffects.reset(this->createAndEmitEffects(colorStages, |
| 194 this->desc().numColor
Effects(), | 175 this->desc().numColorEffects(
), |
| 195 colorKeyProvider, | 176 colorKeyProvider, |
| 196 &inputColor)); | 177 &inputColor)); |
| 197 | 178 |
| 198 GrGLProgramDesc::EffectKeyProvider coverageKeyProvider( | 179 GrGLProgramDesc::EffectKeyProvider coverageKeyProvider( |
| 199 &this->desc(), GrGLProgramDesc::EffectKeyProvider::kCoverage_EffectType)
; | 180 &this->desc(), GrGLProgramDesc::EffectKeyProvider::kCoverage_EffectType)
; |
| 200 fOutput.fCoverageEffects.reset(this->createAndEmitEffects(coverageStages, | 181 fCoverageEffects.reset(this->createAndEmitEffects(coverageStages, |
| 201 this->desc().numCoverageEffects(), | 182 this->desc().numCoverageEf
fects(), |
| 202 coverageKeyProvider, | 183 coverageKeyProvider, |
| 203 &inputCoverage)); | 184 &inputCoverage)); |
| 204 | 185 |
| 205 this->emitCodeAfterEffects(); | 186 this->emitCodeAfterEffects(); |
| 206 | 187 |
| 207 /////////////////////////////////////////////////////////////////////////// | 188 /////////////////////////////////////////////////////////////////////////// |
| 208 // write the secondary color output if necessary | 189 // write the secondary color output if necessary |
| 209 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { | 190 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { |
| 210 const char* secondaryOutputName = this->enableSecondaryOutput(); | 191 const char* secondaryOutputName = this->enableSecondaryOutput(); |
| 211 | 192 |
| 212 // default coeff to ones for kCoverage_DualSrcOutput | 193 // default coeff to ones for kCoverage_DualSrcOutput |
| 213 GrGLSLExpr4 coeff(1); | 194 GrGLSLExpr4 coeff(1); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 241 if (!this->finish()) { | 222 if (!this->finish()) { |
| 242 return false; | 223 return false; |
| 243 } | 224 } |
| 244 | 225 |
| 245 return true; | 226 return true; |
| 246 } | 227 } |
| 247 | 228 |
| 248 ////////////////////////////////////////////////////////////////////////////// | 229 ////////////////////////////////////////////////////////////////////////////// |
| 249 | 230 |
| 250 GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, | 231 GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, |
| 251 GrGLProgramDataManager* programResourceMana
ger, | |
| 252 const GrGLProgramDesc& desc) | 232 const GrGLProgramDesc& desc) |
| 253 : fDesc(desc) | 233 : fHasVertexShader(false) |
| 234 , fTexCoordSetCnt(0) |
| 235 , fProgramID(0) |
| 236 , fDesc(desc) |
| 254 , fGpu(gpu) | 237 , fGpu(gpu) |
| 255 , fProgramDataManager(SkRef(programResourceManager)) | |
| 256 , fFSFeaturesAddedMask(0) | 238 , fFSFeaturesAddedMask(0) |
| 257 , fFSInputs(kVarsPerBlock) | 239 , fFSInputs(kVarsPerBlock) |
| 258 , fFSOutputs(kMaxFSOutputs) | 240 , fFSOutputs(kMaxFSOutputs) |
| 259 , fUniforms(kVarsPerBlock) | 241 , fUniforms(kVarsPerBlock) |
| 260 , fSetupFragPosition(false) | 242 , fSetupFragPosition(false) |
| 261 , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFr
agPosKey) | 243 , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFr
agPosKey) |
| 262 , fHasCustomColorOutput(false) | 244 , fHasCustomColorOutput(false) |
| 263 , fHasSecondaryOutput(false) { | 245 , fHasSecondaryOutput(false) { |
| 264 } | 246 } |
| 265 | 247 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 } | 325 } |
| 344 } | 326 } |
| 345 static const char kFBFetchColorName[] = "gl_LastFragData[0]"; | 327 static const char kFBFetchColorName[] = "gl_LastFragData[0]"; |
| 346 GrGLCaps::FBFetchType fetchType = fGpu->glCaps().fbFetchType(); | 328 GrGLCaps::FBFetchType fetchType = fGpu->glCaps().fbFetchType(); |
| 347 if (GrGLCaps::kEXT_FBFetchType == fetchType) { | 329 if (GrGLCaps::kEXT_FBFetchType == fetchType) { |
| 348 SkAssertResult(this->enablePrivateFeature(kEXTShaderFramebufferFetch_GLS
LPrivateFeature)); | 330 SkAssertResult(this->enablePrivateFeature(kEXTShaderFramebufferFetch_GLS
LPrivateFeature)); |
| 349 return kFBFetchColorName; | 331 return kFBFetchColorName; |
| 350 } else if (GrGLCaps::kNV_FBFetchType == fetchType) { | 332 } else if (GrGLCaps::kNV_FBFetchType == fetchType) { |
| 351 SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSL
PrivateFeature)); | 333 SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSL
PrivateFeature)); |
| 352 return kFBFetchColorName; | 334 return kFBFetchColorName; |
| 353 } else if (fOutput.fUniformHandles.fDstCopySamplerUni.isValid()) { | 335 } else if (fUniformHandles.fDstCopySamplerUni.isValid()) { |
| 354 return kDstCopyColorName; | 336 return kDstCopyColorName; |
| 355 } else { | 337 } else { |
| 356 return ""; | 338 return ""; |
| 357 } | 339 } |
| 358 } | 340 } |
| 359 | 341 |
| 360 void GrGLShaderBuilder::appendTextureLookup(SkString* out, | 342 void GrGLShaderBuilder::appendTextureLookup(SkString* out, |
| 361 const GrGLShaderBuilder::TextureSamp
ler& sampler, | 343 const GrGLShaderBuilder::TextureSamp
ler& sampler, |
| 362 const char* coordName, | 344 const char* coordName, |
| 363 GrSLType varyingType) const { | 345 GrSLType varyingType) const { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 GrGLProgramDataManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_
t visibility, | 415 GrGLProgramDataManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_
t visibility, |
| 434 GrSLTyp
e type, | 416 GrSLTyp
e type, |
| 435 const c
har* name, | 417 const c
har* name, |
| 436 int cou
nt, | 418 int cou
nt, |
| 437 const c
har** outName) { | 419 const c
har** outName) { |
| 438 SkASSERT(name && strlen(name)); | 420 SkASSERT(name && strlen(name)); |
| 439 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); | 421 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); |
| 440 SkASSERT(0 == (~kVisibilityMask & visibility)); | 422 SkASSERT(0 == (~kVisibilityMask & visibility)); |
| 441 SkASSERT(0 != visibility); | 423 SkASSERT(0 != visibility); |
| 442 | 424 |
| 443 BuilderUniform& uni = fUniforms.push_back(); | 425 UniformInfo& uni = fUniforms.push_back(); |
| 444 UniformHandle h = GrGLProgramDataManager::UniformHandle::CreateFromUniformIn
dex(fUniforms.count() - 1); | |
| 445 SkDEBUGCODE(UniformHandle h2 =) | |
| 446 fProgramDataManager->appendUniform(type, count); | |
| 447 // We expect the uniform manager to initially have no uniforms and that all
uniforms are added | |
| 448 // by this function. Therefore, the handles should match. | |
| 449 SkASSERT(h2 == h); | |
| 450 uni.fVariable.setType(type); | 426 uni.fVariable.setType(type); |
| 451 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); | 427 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); |
| 452 this->nameVariable(uni.fVariable.accessName(), 'u', name); | 428 this->nameVariable(uni.fVariable.accessName(), 'u', name); |
| 453 uni.fVariable.setArrayCount(count); | 429 uni.fVariable.setArrayCount(count); |
| 454 uni.fVisibility = visibility; | 430 uni.fVisibility = visibility; |
| 455 | 431 |
| 456 // If it is visible in both the VS and FS, the precision must match. | 432 // If it is visible in both the VS and FS, the precision must match. |
| 457 // We declare a default FS precision, but not a default VS. So set the var | 433 // We declare a default FS precision, but not a default VS. So set the var |
| 458 // to use the default FS precision. | 434 // to use the default FS precision. |
| 459 if ((kVertex_Visibility | kFragment_Visibility) == visibility) { | 435 if ((kVertex_Visibility | kFragment_Visibility) == visibility) { |
| 460 // the fragment and vertex precisions must match | 436 // the fragment and vertex precisions must match |
| 461 uni.fVariable.setPrecision(kDefaultFragmentPrecision); | 437 uni.fVariable.setPrecision(kDefaultFragmentPrecision); |
| 462 } | 438 } |
| 463 | 439 |
| 464 if (NULL != outName) { | 440 if (NULL != outName) { |
| 465 *outName = uni.fVariable.c_str(); | 441 *outName = uni.fVariable.c_str(); |
| 466 } | 442 } |
| 467 | 443 return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fUnifor
ms.count() - 1); |
| 468 return h; | |
| 469 } | 444 } |
| 470 | 445 |
| 471 SkString GrGLShaderBuilder::ensureFSCoords2D(const TransformedCoordsArray& coord
s, int index) { | 446 SkString GrGLShaderBuilder::ensureFSCoords2D(const TransformedCoordsArray& coord
s, int index) { |
| 472 if (kVec3f_GrSLType != coords[index].type()) { | 447 if (kVec3f_GrSLType != coords[index].type()) { |
| 473 SkASSERT(kVec2f_GrSLType == coords[index].type()); | 448 SkASSERT(kVec2f_GrSLType == coords[index].type()); |
| 474 return coords[index].getName(); | 449 return coords[index].getName(); |
| 475 } | 450 } |
| 476 | 451 |
| 477 SkString coords2D("coords2D"); | 452 SkString coords2D("coords2D"); |
| 478 if (0 != index) { | 453 if (0 != index) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 508 GrGLShaderVar::kUpperLeft_Origin); | 483 GrGLShaderVar::kUpperLeft_Origin); |
| 509 fSetupFragPosition = true; | 484 fSetupFragPosition = true; |
| 510 } | 485 } |
| 511 return "gl_FragCoord"; | 486 return "gl_FragCoord"; |
| 512 } else { | 487 } else { |
| 513 static const char* kCoordName = "fragCoordYDown"; | 488 static const char* kCoordName = "fragCoordYDown"; |
| 514 if (!fSetupFragPosition) { | 489 if (!fSetupFragPosition) { |
| 515 // temporarily change the stage index because we're inserting non-st
age code. | 490 // temporarily change the stage index because we're inserting non-st
age code. |
| 516 CodeStage::AutoStageRestore csar(&fCodeStage, NULL); | 491 CodeStage::AutoStageRestore csar(&fCodeStage, NULL); |
| 517 | 492 |
| 518 SkASSERT(!fOutput.fUniformHandles.fRTHeightUni.isValid()); | 493 SkASSERT(!fUniformHandles.fRTHeightUni.isValid()); |
| 519 const char* rtHeightName; | 494 const char* rtHeightName; |
| 520 | 495 |
| 521 fOutput.fUniformHandles.fRTHeightUni = | 496 fUniformHandles.fRTHeightUni = |
| 522 this->addUniform(kFragment_Visibility, kFloat_GrSLType, "RTHeigh
t", &rtHeightName); | 497 this->addUniform(kFragment_Visibility, kFloat_GrSLType, "RTHeigh
t", &rtHeightName); |
| 523 | 498 |
| 524 // Using glFragCoord.zw for the last two components tickles an Adren
o driver bug that | 499 // Using glFragCoord.zw for the last two components tickles an Adren
o driver bug that |
| 525 // causes programs to fail to link. Making this function return a ve
c2() didn't fix the | 500 // causes programs to fail to link. Making this function return a ve
c2() didn't fix the |
| 526 // problem but using 1.0 for the last two components does. | 501 // problem but using 1.0 for the last two components does. |
| 527 this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_Fra
gCoord.y, 1.0, " | 502 this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_Fra
gCoord.y, 1.0, " |
| 528 "1.0);\n", kCoordName, rtHeightName); | 503 "1.0);\n", kCoordName, rtHeightName); |
| 529 fSetupFragPosition = true; | 504 fSetupFragPosition = true; |
| 530 } | 505 } |
| 531 SkASSERT(fOutput.fUniformHandles.fRTHeightUni.isValid()); | 506 SkASSERT(fUniformHandles.fRTHeightUni.isValid()); |
| 532 return kCoordName; | 507 return kCoordName; |
| 533 } | 508 } |
| 534 } | 509 } |
| 535 | 510 |
| 536 void GrGLShaderBuilder::fsEmitFunction(GrSLType returnType, | 511 void GrGLShaderBuilder::fsEmitFunction(GrSLType returnType, |
| 537 const char* name, | 512 const char* name, |
| 538 int argCnt, | 513 int argCnt, |
| 539 const GrGLShaderVar* args, | 514 const GrGLShaderVar* args, |
| 540 const char* body, | 515 const char* body, |
| 541 SkString* outName) { | 516 SkString* outName) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 if (!fHasSecondaryOutput) { | 627 if (!fHasSecondaryOutput) { |
| 653 fFSOutputs.push_back().set(kVec4f_GrSLType, | 628 fFSOutputs.push_back().set(kVec4f_GrSLType, |
| 654 GrGLShaderVar::kOut_TypeModifier, | 629 GrGLShaderVar::kOut_TypeModifier, |
| 655 dual_source_output_name()); | 630 dual_source_output_name()); |
| 656 fHasSecondaryOutput = true; | 631 fHasSecondaryOutput = true; |
| 657 } | 632 } |
| 658 return dual_source_output_name(); | 633 return dual_source_output_name(); |
| 659 } | 634 } |
| 660 | 635 |
| 661 bool GrGLShaderBuilder::finish() { | 636 bool GrGLShaderBuilder::finish() { |
| 662 SkASSERT(0 == fOutput.fProgramID); | 637 SkASSERT(0 == fProgramID); |
| 663 GL_CALL_RET(fOutput.fProgramID, CreateProgram()); | 638 GL_CALL_RET(fProgramID, CreateProgram()); |
| 664 if (!fOutput.fProgramID) { | 639 if (!fProgramID) { |
| 665 return false; | 640 return false; |
| 666 } | 641 } |
| 667 | 642 |
| 668 SkTDArray<GrGLuint> shadersToDelete; | 643 SkTDArray<GrGLuint> shadersToDelete; |
| 669 | 644 |
| 670 if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) { | 645 if (!this->compileAndAttachShaders(fProgramID, &shadersToDelete)) { |
| 671 GL_CALL(DeleteProgram(fOutput.fProgramID)); | 646 GL_CALL(DeleteProgram(fProgramID)); |
| 672 return false; | 647 return false; |
| 673 } | 648 } |
| 674 | 649 |
| 675 this->bindProgramLocations(fOutput.fProgramID); | 650 this->bindProgramLocations(fProgramID); |
| 676 if (fProgramDataManager->isUsingBindUniform()) { | |
| 677 fProgramDataManager->getUniformLocations(fOutput.fProgramID, fUniforms); | |
| 678 } | |
| 679 | 651 |
| 680 GL_CALL(LinkProgram(fOutput.fProgramID)); | 652 GL_CALL(LinkProgram(fProgramID)); |
| 681 | 653 |
| 682 // Calling GetProgramiv is expensive in Chromium. Assume success in release
builds. | 654 // Calling GetProgramiv is expensive in Chromium. Assume success in release
builds. |
| 683 bool checkLinked = !fGpu->ctxInfo().isChromium(); | 655 bool checkLinked = !fGpu->ctxInfo().isChromium(); |
| 684 #ifdef SK_DEBUG | 656 #ifdef SK_DEBUG |
| 685 checkLinked = true; | 657 checkLinked = true; |
| 686 #endif | 658 #endif |
| 687 if (checkLinked) { | 659 if (checkLinked) { |
| 688 GrGLint linked = GR_GL_INIT_ZERO; | 660 GrGLint linked = GR_GL_INIT_ZERO; |
| 689 GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_LINK_STATUS, &linked)); | 661 GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked)); |
| 690 if (!linked) { | 662 if (!linked) { |
| 691 GrGLint infoLen = GR_GL_INIT_ZERO; | 663 GrGLint infoLen = GR_GL_INIT_ZERO; |
| 692 GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_INFO_LOG_LENGTH, &inf
oLen)); | 664 GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen)); |
| 693 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debug
ger | 665 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debug
ger |
| 694 if (infoLen > 0) { | 666 if (infoLen > 0) { |
| 695 // retrieve length even though we don't need it to workaround | 667 // retrieve length even though we don't need it to workaround |
| 696 // bug in chrome cmd buffer param validation. | 668 // bug in chrome cmd buffer param validation. |
| 697 GrGLsizei length = GR_GL_INIT_ZERO; | 669 GrGLsizei length = GR_GL_INIT_ZERO; |
| 698 GL_CALL(GetProgramInfoLog(fOutput.fProgramID, | 670 GL_CALL(GetProgramInfoLog(fProgramID, |
| 699 infoLen+1, | 671 infoLen+1, |
| 700 &length, | 672 &length, |
| 701 (char*)log.get())); | 673 (char*)log.get())); |
| 702 GrPrintf((char*)log.get()); | 674 GrPrintf((char*)log.get()); |
| 703 } | 675 } |
| 704 SkDEBUGFAIL("Error linking program"); | 676 SkDEBUGFAIL("Error linking program"); |
| 705 GL_CALL(DeleteProgram(fOutput.fProgramID)); | 677 GL_CALL(DeleteProgram(fProgramID)); |
| 706 fOutput.fProgramID = 0; | 678 fProgramID = 0; |
| 707 return false; | 679 return false; |
| 708 } | 680 } |
| 709 } | 681 } |
| 710 | 682 |
| 711 if (!fProgramDataManager->isUsingBindUniform()) { | 683 this->resolveProgramLocations(fProgramID); |
| 712 fProgramDataManager->getUniformLocations(fOutput.fProgramID, fUniforms); | |
| 713 } | |
| 714 | 684 |
| 715 for (int i = 0; i < shadersToDelete.count(); ++i) { | 685 for (int i = 0; i < shadersToDelete.count(); ++i) { |
| 716 GL_CALL(DeleteShader(shadersToDelete[i])); | 686 GL_CALL(DeleteShader(shadersToDelete[i])); |
| 717 } | 687 } |
| 718 | 688 |
| 719 return true; | 689 return true; |
| 720 } | 690 } |
| 721 | 691 |
| 722 // Compiles a GL shader and attaches it to a program. Returns the shader ID if | 692 // Compiles a GL shader and attaches it to a program. Returns the shader ID if |
| 723 // successful, or 0 if not. | 693 // successful, or 0 if not. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 GrGLuint fragShaderId = attach_shader(fGpu->glContext(), programId, GR_GL_FR
AGMENT_SHADER, fragShaderSrc); | 771 GrGLuint fragShaderId = attach_shader(fGpu->glContext(), programId, GR_GL_FR
AGMENT_SHADER, fragShaderSrc); |
| 802 if (!fragShaderId) { | 772 if (!fragShaderId) { |
| 803 return false; | 773 return false; |
| 804 } | 774 } |
| 805 | 775 |
| 806 *shaderIds->append() = fragShaderId; | 776 *shaderIds->append() = fragShaderId; |
| 807 | 777 |
| 808 return true; | 778 return true; |
| 809 } | 779 } |
| 810 | 780 |
| 811 void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) const { | 781 void GrGLShaderBuilder::bindProgramLocations(GrGLuint programId) { |
| 812 if (fHasCustomColorOutput) { | 782 if (fHasCustomColorOutput) { |
| 813 GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name())
); | 783 GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name())
); |
| 814 } | 784 } |
| 815 if (fHasSecondaryOutput) { | 785 if (fHasSecondaryOutput) { |
| 816 GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_
name())); | 786 GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_
name())); |
| 817 } | 787 } |
| 788 // skbug.com/2056 |
| 789 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= NULL; |
| 790 if (usingBindUniform) { |
| 791 int count = fUniforms.count(); |
| 792 for (int i = 0; i < count; ++i) { |
| 793 GL_CALL(BindUniformLocation(programId, i, fUniforms[i].fVariable.c_s
tr())); |
| 794 fUniforms[i].fLocation = i; |
| 795 } |
| 796 } |
| 797 } |
| 798 |
| 799 void GrGLShaderBuilder::resolveProgramLocations(GrGLuint programId) { |
| 800 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= NULL; |
| 801 if (!usingBindUniform) { |
| 802 int count = fUniforms.count(); |
| 803 for (int i = 0; i < count; ++i) { |
| 804 GrGLint location; |
| 805 GL_CALL_RET(location, |
| 806 GetUniformLocation(programId, fUniforms[i].fVariable.c_s
tr())); |
| 807 fUniforms[i].fLocation = location; |
| 808 } |
| 809 } |
| 818 } | 810 } |
| 819 | 811 |
| 820 const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const { | 812 const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const { |
| 821 return fGpu->ctxInfo(); | 813 return fGpu->ctxInfo(); |
| 822 } | 814 } |
| 823 | 815 |
| 824 //////////////////////////////////////////////////////////////////////////////// | 816 //////////////////////////////////////////////////////////////////////////////// |
| 825 | 817 |
| 826 GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, | 818 GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, |
| 827 GrGLProgramDataManager* programReso
urceManager, | |
| 828 const GrGLProgramDesc& desc) | 819 const GrGLProgramDesc& desc) |
| 829 : INHERITED(gpu, programResourceManager, desc) | 820 : INHERITED(gpu, desc) |
| 830 , fVSAttrs(kVarsPerBlock) | 821 , fVSAttrs(kVarsPerBlock) |
| 831 , fVSOutputs(kVarsPerBlock) | 822 , fVSOutputs(kVarsPerBlock) |
| 832 , fGSInputs(kVarsPerBlock) | 823 , fGSInputs(kVarsPerBlock) |
| 833 , fGSOutputs(kVarsPerBlock) { | 824 , fGSOutputs(kVarsPerBlock) { |
| 834 } | 825 } |
| 835 | 826 |
| 836 void GrGLFullShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr
4* coverage) { | 827 void GrGLFullShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr
4* coverage) { |
| 837 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); | 828 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); |
| 838 | 829 |
| 839 fOutput.fHasVertexShader = true; | 830 fHasVertexShader = true; |
| 840 | 831 |
| 841 fPositionVar = &fVSAttrs.push_back(); | 832 fPositionVar = &fVSAttrs.push_back(); |
| 842 fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "
aPosition"); | 833 fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "
aPosition"); |
| 843 if (-1 != header.fLocalCoordAttributeIndex) { | 834 if (-1 != header.fLocalCoordAttributeIndex) { |
| 844 fLocalCoordsVar = &fVSAttrs.push_back(); | 835 fLocalCoordsVar = &fVSAttrs.push_back(); |
| 845 fLocalCoordsVar->set(kVec2f_GrSLType, | 836 fLocalCoordsVar->set(kVec2f_GrSLType, |
| 846 GrGLShaderVar::kAttribute_TypeModifier, | 837 GrGLShaderVar::kAttribute_TypeModifier, |
| 847 "aLocalCoords"); | 838 "aLocalCoords"); |
| 848 } else { | 839 } else { |
| 849 fLocalCoordsVar = fPositionVar; | 840 fLocalCoordsVar = fPositionVar; |
| 850 } | 841 } |
| 851 | 842 |
| 852 const char* viewMName; | 843 const char* viewMName; |
| 853 fOutput.fUniformHandles.fViewMatrixUni = | 844 fUniformHandles.fViewMatrixUni = |
| 854 this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kMat33f_GrSLType
, "ViewM", | 845 this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kMat33f_GrSLType
, "ViewM", |
| 855 &viewMName); | 846 &viewMName); |
| 856 | 847 |
| 857 // Transform the position into Skia's device coords. | 848 // Transform the position into Skia's device coords. |
| 858 this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n", | 849 this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n", |
| 859 viewMName, fPositionVar->c_str()); | 850 viewMName, fPositionVar->c_str()); |
| 860 | 851 |
| 861 // we output point size in the GS if present | 852 // we output point size in the GS if present |
| 862 if (header.fEmitsPointSize | 853 if (header.fEmitsPointSize |
| 863 #if GR_GL_EXPERIMENTAL_GS | 854 #if GR_GL_EXPERIMENTAL_GS |
| (...skipping 15 matching lines...) Expand all Loading... |
| 879 this->addAttribute(kVec4f_GrSLType, coverage_attribute_name()); | 870 this->addAttribute(kVec4f_GrSLType, coverage_attribute_name()); |
| 880 const char *vsName, *fsName; | 871 const char *vsName, *fsName; |
| 881 this->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); | 872 this->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); |
| 882 this->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name()); | 873 this->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name()); |
| 883 *coverage = fsName; | 874 *coverage = fsName; |
| 884 } | 875 } |
| 885 } | 876 } |
| 886 | 877 |
| 887 void GrGLFullShaderBuilder::emitCodeAfterEffects() { | 878 void GrGLFullShaderBuilder::emitCodeAfterEffects() { |
| 888 const char* rtAdjustName; | 879 const char* rtAdjustName; |
| 889 fOutput.fUniformHandles.fRTAdjustmentUni = | 880 fUniformHandles.fRTAdjustmentUni = |
| 890 this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kVec4f_GrSLType,
"rtAdjustment", | 881 this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kVec4f_GrSLType,
"rtAdjustment", |
| 891 &rtAdjustName); | 882 &rtAdjustName); |
| 892 | 883 |
| 893 // Transform from Skia's device coords to GL's normalized device coords. | 884 // Transform from Skia's device coords to GL's normalized device coords. |
| 894 this->vsCodeAppendf( | 885 this->vsCodeAppendf( |
| 895 "\tgl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.
z);\n", | 886 "\tgl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.
z);\n", |
| 896 rtAdjustName, rtAdjustName); | 887 rtAdjustName, rtAdjustName); |
| 897 } | 888 } |
| 898 | 889 |
| 899 bool GrGLFullShaderBuilder::addAttribute(GrSLType type, const char* name) { | 890 bool GrGLFullShaderBuilder::addAttribute(GrSLType type, const char* name) { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 if (!geomShaderId) { | 1022 if (!geomShaderId) { |
| 1032 return false; | 1023 return false; |
| 1033 } | 1024 } |
| 1034 *shaderIds->append() = geomShaderId; | 1025 *shaderIds->append() = geomShaderId; |
| 1035 } | 1026 } |
| 1036 #endif | 1027 #endif |
| 1037 | 1028 |
| 1038 return this->INHERITED::compileAndAttachShaders(programId, shaderIds); | 1029 return this->INHERITED::compileAndAttachShaders(programId, shaderIds); |
| 1039 } | 1030 } |
| 1040 | 1031 |
| 1041 void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const { | 1032 void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) { |
| 1042 this->INHERITED::bindProgramLocations(programId); | 1033 this->INHERITED::bindProgramLocations(programId); |
| 1043 | 1034 |
| 1044 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); | 1035 const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); |
| 1045 | 1036 |
| 1046 // Bind the attrib locations to same values for all shaders | 1037 // Bind the attrib locations to same values for all shaders |
| 1047 SkASSERT(-1 != header.fPositionAttributeIndex); | 1038 SkASSERT(-1 != header.fPositionAttributeIndex); |
| 1048 GL_CALL(BindAttribLocation(programId, | 1039 GL_CALL(BindAttribLocation(programId, |
| 1049 header.fPositionAttributeIndex, | 1040 header.fPositionAttributeIndex, |
| 1050 fPositionVar->c_str())); | 1041 fPositionVar->c_str())); |
| 1051 if (-1 != header.fLocalCoordAttributeIndex) { | 1042 if (-1 != header.fLocalCoordAttributeIndex) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1066 | 1057 |
| 1067 const AttributePair* attribEnd = fEffectAttributes.end(); | 1058 const AttributePair* attribEnd = fEffectAttributes.end(); |
| 1068 for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attr
ibEnd; ++attrib) { | 1059 for (const AttributePair* attrib = fEffectAttributes.begin(); attrib != attr
ibEnd; ++attrib) { |
| 1069 GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_s
tr())); | 1060 GL_CALL(BindAttribLocation(programId, attrib->fIndex, attrib->fName.c_s
tr())); |
| 1070 } | 1061 } |
| 1071 } | 1062 } |
| 1072 | 1063 |
| 1073 //////////////////////////////////////////////////////////////////////////////// | 1064 //////////////////////////////////////////////////////////////////////////////// |
| 1074 | 1065 |
| 1075 GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu, | 1066 GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu, |
| 1076 GrGLProgramDataMana
ger* programResourceManager, | |
| 1077 const GrGLProgramDe
sc& desc) | 1067 const GrGLProgramDe
sc& desc) |
| 1078 : INHERITED(gpu, programResourceManager, desc) { | 1068 : INHERITED(gpu, desc) { |
| 1079 SkASSERT(!desc.getHeader().fHasVertexCode); | 1069 SkASSERT(!desc.getHeader().fHasVertexCode); |
| 1080 SkASSERT(gpu->glCaps().pathRenderingSupport()); | 1070 SkASSERT(gpu->glCaps().pathRenderingSupport()); |
| 1081 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorIn
put); | 1071 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorIn
put); |
| 1082 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverag
eInput); | 1072 SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverag
eInput); |
| 1083 } | 1073 } |
| 1084 | 1074 |
| 1085 int GrGLFragmentOnlyShaderBuilder::addTexCoordSets(int count) { | 1075 int GrGLFragmentOnlyShaderBuilder::addTexCoordSets(int count) { |
| 1086 int firstFreeCoordSet = fOutput.fTexCoordSetCnt; | 1076 int firstFreeCoordSet = fTexCoordSetCnt; |
| 1087 fOutput.fTexCoordSetCnt += count; | 1077 fTexCoordSetCnt += count; |
| 1088 SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fOutput.fTexCoor
dSetCnt); | 1078 SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fTexCoordSetCnt)
; |
| 1089 return firstFreeCoordSet; | 1079 return firstFreeCoordSet; |
| 1090 } | 1080 } |
| 1091 | 1081 |
| 1092 GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects( | 1082 GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects( |
| 1093 const GrEffectStage* effectStages[], | 1083 const GrEffectStage* effectStages[], |
| 1094 int effectCnt, | 1084 int effectCnt, |
| 1095 const GrGLProgramDesc::EffectKeyProvider& keyProvider, | 1085 const GrGLProgramDesc::EffectKeyProvider& keyProvider, |
| 1096 GrGLSLExpr4* inOutFSColor) { | 1086 GrGLSLExpr4* inOutFSColor) { |
| 1097 | 1087 |
| 1098 GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this, | 1088 GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this, |
| 1099 effectCnt); | 1089 effectCnt); |
| 1100 this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder, | 1090 this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder, |
| 1101 effectStages, | 1091 effectStages, |
| 1102 effectCnt, | 1092 effectCnt, |
| 1103 keyProvider, | 1093 keyProvider, |
| 1104 inOutFSColor); | 1094 inOutFSColor); |
| 1105 return pathTexGenEffectsBuilder.finish(); | 1095 return pathTexGenEffectsBuilder.finish(); |
| 1106 } | 1096 } |
| OLD | NEW |