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 |