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 |