| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "GrGLProgramBuilder.h" | 8 #include "GrGLProgramBuilder.h" |
| 9 #include "gl/GrGLProgram.h" | 9 #include "gl/GrGLProgram.h" |
| 10 #include "gl/GrGLSLPrettyPrint.h" | 10 #include "gl/GrGLSLPrettyPrint.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 // get the initial color and coverage to feed into the first effect in each
effect chain | 50 // get the initial color and coverage to feed into the first effect in each
effect chain |
| 51 GrGLSLExpr4 inputColor; | 51 GrGLSLExpr4 inputColor; |
| 52 GrGLSLExpr1 inputCoverage; | 52 GrGLSLExpr1 inputCoverage; |
| 53 pb->setupUniformColorAndCoverageIfNeeded(&inputColor, &inputCoverage); | 53 pb->setupUniformColorAndCoverageIfNeeded(&inputColor, &inputCoverage); |
| 54 | 54 |
| 55 // if we have a vertex shader(we don't only if we are using NVPR or NVPR ES)
, then we may have | 55 // if we have a vertex shader(we don't only if we are using NVPR or NVPR ES)
, then we may have |
| 56 // to setup a few more things like builtin vertex attributes | 56 // to setup a few more things like builtin vertex attributes |
| 57 bool hasVertexShader = !(header.fUseNvpr && | 57 bool hasVertexShader = !(header.fUseNvpr && |
| 58 gpu->glPathRendering()->texturingMode() == | 58 gpu->glPathRendering()->texturingMode() == |
| 59 GrGLPathRendering::FixedFunction_TexturingMode); | 59 GrGLPathRendering::FixedFunction_TexturingMode); |
| 60 |
| 60 if (hasVertexShader) { | 61 if (hasVertexShader) { |
| 61 pb->fVS.setupLocalCoords(); | 62 pb->fVS.setupUniformViewMatrix(); |
| 62 pb->fVS.transformGLToSkiaCoords(); | 63 pb->fVS.setupPositionAndLocalCoords(); |
| 64 |
| 63 if (header.fEmitsPointSize) { | 65 if (header.fEmitsPointSize) { |
| 64 pb->fVS.codeAppend("gl_PointSize = 1.0;"); | 66 pb->fVS.codeAppend("gl_PointSize = 1.0;"); |
| 65 } | 67 } |
| 66 if (GrProgramDesc::kAttribute_ColorInput == header.fColorInput) { | 68 if (GrProgramDesc::kAttribute_ColorInput == header.fColorInput) { |
| 67 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor); | 69 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor); |
| 68 } | 70 } |
| 69 if (GrProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { | 71 if (GrProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { |
| 70 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage); | 72 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage); |
| 71 } | 73 } |
| 72 } | 74 } |
| 73 | 75 |
| 74 // TODO: Once all stages can handle taking a float or vec4 and correctly han
dling them we can | 76 // TODO: Once all stages can handle taking a float or vec4 and correctly han
dling them we can |
| 75 // remove this cast to a vec4. | 77 // remove this cast to a vec4. |
| 76 GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage); | 78 GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage); |
| 77 | 79 |
| 78 pb->emitAndInstallProcs(optState, &inputColor, &inputCoverageVec4); | 80 pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4); |
| 79 | 81 |
| 80 if (hasVertexShader) { | 82 if (hasVertexShader) { |
| 81 pb->fVS.transformSkiaToGLCoords(); | 83 pb->fVS.transformToNormalizedDeviceSpace(); |
| 82 } | 84 } |
| 83 | 85 |
| 84 // write the secondary color output if necessary | 86 // write the secondary color output if necessary |
| 85 if (GrProgramDesc::kNone_SecondaryOutputType != header.fSecondaryOutputType)
{ | 87 if (GrProgramDesc::kNone_SecondaryOutputType != header.fSecondaryOutputType)
{ |
| 86 pb->fFS.enableSecondaryOutput(inputColor, inputCoverageVec4); | 88 pb->fFS.enableSecondaryOutput(inputColor, inputCoverageVec4); |
| 87 } | 89 } |
| 88 | 90 |
| 89 pb->fFS.combineColorAndCoverage(inputColor, inputCoverageVec4); | 91 pb->fFS.combineColorAndCoverage(inputColor, inputCoverageVec4); |
| 90 | 92 |
| 91 return pb->finalize(); | 93 return pb->finalize(); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 int co
unt, | 166 int co
unt, |
| 165 const
char** outName) { | 167 const
char** outName) { |
| 166 SkASSERT(name && strlen(name)); | 168 SkASSERT(name && strlen(name)); |
| 167 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); | 169 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); |
| 168 SkASSERT(0 == (~kVisibilityMask & visibility)); | 170 SkASSERT(0 == (~kVisibilityMask & visibility)); |
| 169 SkASSERT(0 != visibility); | 171 SkASSERT(0 != visibility); |
| 170 | 172 |
| 171 UniformInfo& uni = fUniforms.push_back(); | 173 UniformInfo& uni = fUniforms.push_back(); |
| 172 uni.fVariable.setType(type); | 174 uni.fVariable.setType(type); |
| 173 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); | 175 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); |
| 174 this->nameVariable(uni.fVariable.accessName(), 'u', name); | 176 // TODO this is a bit hacky, lets think of a better way. Basically we need
to be able to use |
| 177 // the uniform view matrix name in the GP, and the GP is immutable so it has
to tell the PB |
| 178 // exactly what name it wants to use for the uniform view matrix. If we pre
fix anythings, then |
| 179 // the names will mismatch. I think the correct solution is to have all GPs
which need the |
| 180 // uniform view matrix, they should upload the view matrix in their setData
along with regular |
| 181 // uniforms. |
| 182 char prefix = 'u'; |
| 183 if ('u' == name[0]) { |
| 184 prefix = '\0'; |
| 185 } |
| 186 this->nameVariable(uni.fVariable.accessName(), prefix, name); |
| 175 uni.fVariable.setArrayCount(count); | 187 uni.fVariable.setArrayCount(count); |
| 176 uni.fVisibility = visibility; | 188 uni.fVisibility = visibility; |
| 177 | 189 |
| 178 // If it is visible in both the VS and FS, the precision must match. | 190 // If it is visible in both the VS and FS, the precision must match. |
| 179 // We declare a default FS precision, but not a default VS. So set the var | 191 // We declare a default FS precision, but not a default VS. So set the var |
| 180 // to use the default FS precision. | 192 // to use the default FS precision. |
| 181 if ((kVertex_Visibility | kFragment_Visibility) == visibility) { | 193 if ((kVertex_Visibility | kFragment_Visibility) == visibility) { |
| 182 // the fragment and vertex precisions must match | 194 // the fragment and vertex precisions must match |
| 183 uni.fVariable.setPrecision(kDefaultFragmentPrecision); | 195 uni.fVariable.setPrecision(kDefaultFragmentPrecision); |
| 184 } | 196 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 235 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| 224 kFloat_GrSLType, | 236 kFloat_GrSLType, |
| 225 "Coverage", | 237 "Coverage", |
| 226 &name); | 238 &name); |
| 227 *inputCoverage = GrGLSLExpr1(name); | 239 *inputCoverage = GrGLSLExpr1(name); |
| 228 } else if (GrProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { | 240 } else if (GrProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { |
| 229 *inputCoverage = GrGLSLExpr1(1); | 241 *inputCoverage = GrGLSLExpr1(1); |
| 230 } | 242 } |
| 231 } | 243 } |
| 232 | 244 |
| 233 void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState, | 245 void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, |
| 234 GrGLSLExpr4* inputColor, | |
| 235 GrGLSLExpr4* inputCoverage) { | 246 GrGLSLExpr4* inputCoverage) { |
| 236 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs)); | 247 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs)); |
| 237 int numProcs = optState.numFragmentStages(); | 248 int numProcs = fOptState.numFragmentStages(); |
| 238 this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor); | 249 this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor); |
| 239 if (optState.hasGeometryProcessor()) { | 250 if (fOptState.hasGeometryProcessor()) { |
| 240 const GrGeometryProcessor& gp = *optState.getGeometryProcessor(); | 251 const GrGeometryProcessor& gp = *fOptState.getGeometryProcessor(); |
| 241 fVS.emitAttributes(gp); | 252 fVS.emitAttributes(gp); |
| 242 ProcKeyProvider keyProvider(&fDesc, | 253 ProcKeyProvider keyProvider(&fDesc, |
| 243 ProcKeyProvider::kGeometry_ProcessorType, | 254 ProcKeyProvider::kGeometry_ProcessorType, |
| 244 GrGLProgramDescBuilder::kProcessorKeyOffsets
AndLengthOffset); | 255 GrGLProgramDescBuilder::kProcessorKeyOffsets
AndLengthOffset); |
| 245 GrGLSLExpr4 output; | 256 GrGLSLExpr4 output; |
| 246 this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *input
Coverage, &output); | 257 this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *input
Coverage, &output); |
| 247 *inputCoverage = output; | 258 *inputCoverage = output; |
| 248 } | 259 } |
| 249 this->emitAndInstallFragProcs(optState.numColorStages(), numProcs, inputCov
erage); | 260 this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs, inputCo
verage); |
| 250 } | 261 } |
| 251 | 262 |
| 252 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, G
rGLSLExpr4* inOut) { | 263 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, G
rGLSLExpr4* inOut) { |
| 253 ProcKeyProvider keyProvider(&fDesc, | 264 ProcKeyProvider keyProvider(&fDesc, |
| 254 ProcKeyProvider::kFragment_ProcessorType, | 265 ProcKeyProvider::kFragment_ProcessorType, |
| 255 GrGLProgramDescBuilder::kProcessorKeyOffsetsAndL
engthOffset); | 266 GrGLProgramDescBuilder::kProcessorKeyOffsetsAndL
engthOffset); |
| 256 for (int e = procOffset; e < numProcs; ++e) { | 267 for (int e = procOffset; e < numProcs; ++e) { |
| 257 GrGLSLExpr4 output; | 268 GrGLSLExpr4 output; |
| 258 const GrFragmentStage& stage = fOptState.getFragmentStage(e); | 269 const GrFragmentStage& stage = fOptState.getFragmentStage(e); |
| 259 this->emitAndInstallProc<GrFragmentStage>(stage, e, keyProvider, *inOut,
&output); | 270 this->emitAndInstallProc<GrFragmentStage>(stage, e, keyProvider, *inOut,
&output); |
| 260 *inOut = output; | 271 *inOut = output; |
| 261 } | 272 } |
| 262 } | 273 } |
| 263 | 274 |
| 264 // TODO Processors cannot output zeros because an empty string is all 1s | 275 // TODO Processors cannot output zeros because an empty string is all 1s |
| 265 // the fix is to allow effects to take the GrGLSLExpr4 directly | 276 // the fix is to allow effects to take the GrGLSLExpr4 directly |
| 266 template <class Proc> | 277 template <class Proc> |
| 267 void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc, | 278 void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc, |
| 268 int index, | 279 int index, |
| 269 const ProcKeyProvider& keyProvider, | 280 const ProcKeyProvider& keyProvider, |
| 270 const GrGLSLExpr4& input, | 281 const GrGLSLExpr4& input, |
| 271 GrGLSLExpr4* output) { | 282 GrGLSLExpr4* output) { |
| 272 // Program builders have a bit of state we need to clear with each effect | 283 // Program builders have a bit of state we need to clear with each effect |
| 273 AutoStageAdvance adv(this); | 284 AutoStageAdvance adv(this); |
| 274 | 285 |
| 275 // create var to hold stage result | 286 // create var to hold stage result. If we already have a valid output name,
just use that |
| 287 // otherwise create a new mangled one. |
| 276 SkString outColorName; | 288 SkString outColorName; |
| 277 this->nameVariable(&outColorName, '\0', "output"); | 289 if (output->isValid()) { |
| 290 outColorName = output->c_str(); |
| 291 } else { |
| 292 this->nameVariable(&outColorName, '\0', "output"); |
| 293 } |
| 278 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); | 294 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); |
| 279 *output = outColorName; | 295 *output = outColorName; |
| 280 | 296 |
| 281 // Enclose custom code in a block to avoid namespace conflicts | 297 // Enclose custom code in a block to avoid namespace conflicts |
| 282 SkString openBrace; | 298 SkString openBrace; |
| 283 openBrace.printf("{ // Stage %d\n", fStageIndex); | 299 openBrace.printf("{ // Stage %d\n", fStageIndex); |
| 284 fFS.codeAppend(openBrace.c_str()); | 300 fFS.codeAppend(openBrace.c_str()); |
| 285 | 301 |
| 286 this->emitAndInstallProc(proc, keyProvider.get(index), output->c_str(), | 302 this->emitAndInstallProc(proc, keyProvider.get(index), output->c_str(), |
| 287 input.isOnes() ? NULL : input.c_str()); | 303 input.isOnes() ? NULL : input.c_str()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 308 ifp->fGLProc->emitCode(this, fp, key, outColor, inColor, coords, samplers); | 324 ifp->fGLProc->emitCode(this, fp, key, outColor, inColor, coords, samplers); |
| 309 | 325 |
| 310 // We have to check that effects and the code they emit are consistent, ie i
f an effect | 326 // We have to check that effects and the code they emit are consistent, ie i
f an effect |
| 311 // asks for dst color, then the emit code needs to follow suit | 327 // asks for dst color, then the emit code needs to follow suit |
| 312 verify(fp); | 328 verify(fp); |
| 313 fFragmentProcessors->fProcs.push_back(ifp); | 329 fFragmentProcessors->fProcs.push_back(ifp); |
| 314 } | 330 } |
| 315 | 331 |
| 316 void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp, | 332 void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp, |
| 317 const GrProcessorKey& key, | 333 const GrProcessorKey& key, |
| 318 const char* outColor, | 334 const char* outCoverage, |
| 319 const char* inColor) { | 335 const char* inCoverage) { |
| 320 SkASSERT(!fGeometryProcessor); | 336 SkASSERT(!fGeometryProcessor); |
| 321 fGeometryProcessor = SkNEW(GrGLInstalledGeoProc); | 337 fGeometryProcessor = SkNEW(GrGLInstalledGeoProc); |
| 322 | 338 |
| 323 fGeometryProcessor->fGLProc.reset(gp.getFactory().createGLInstance(gp)); | 339 fGeometryProcessor->fGLProc.reset(gp.getFactory().createGLInstance(gp)); |
| 324 | 340 |
| 325 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures()); | 341 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures()); |
| 326 this->emitSamplers(gp, &samplers, fGeometryProcessor); | 342 this->emitSamplers(gp, &samplers, fGeometryProcessor); |
| 327 | 343 |
| 328 GrGLGeometryProcessor::EmitArgs args(this, gp, key, outColor, inColor, sampl
ers); | 344 GrGLGeometryProcessor::EmitArgs args(this, gp, key, outCoverage, inCoverage,
samplers); |
| 329 fGeometryProcessor->fGLProc->emitCode(args); | 345 fGeometryProcessor->fGLProc->emitCode(args); |
| 330 | 346 |
| 331 // We have to check that effects and the code they emit are consistent, ie i
f an effect | 347 // We have to check that effects and the code they emit are consistent, ie i
f an effect |
| 332 // asks for dst color, then the emit code needs to follow suit | 348 // asks for dst color, then the emit code needs to follow suit |
| 333 verify(gp); | 349 verify(gp); |
| 334 } | 350 } |
| 335 | 351 |
| 336 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) { | 352 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) { |
| 337 SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition()); | 353 SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition()); |
| 338 } | 354 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 367 uniName, | 383 uniName, |
| 368 &uniName).toShaderBuilder
Index(); | 384 &uniName).toShaderBuilder
Index(); |
| 369 | 385 |
| 370 const char* varyingName = "MatrixCoord"; | 386 const char* varyingName = "MatrixCoord"; |
| 371 SkString suffixedVaryingName; | 387 SkString suffixedVaryingName; |
| 372 if (0 != t) { | 388 if (0 != t) { |
| 373 suffixedVaryingName.append(varyingName); | 389 suffixedVaryingName.append(varyingName); |
| 374 suffixedVaryingName.appendf("_%i", t); | 390 suffixedVaryingName.appendf("_%i", t); |
| 375 varyingName = suffixedVaryingName.c_str(); | 391 varyingName = suffixedVaryingName.c_str(); |
| 376 } | 392 } |
| 393 const char* coords = kPosition_GrCoordSet == effect->coordTransform(t).s
ourceCoords() ? |
| 394 fVS.positionAttribute().c_s
tr() : |
| 395 fVS.localCoordsAttribute().
c_str(); |
| 377 GrGLVertToFrag v(varyingType); | 396 GrGLVertToFrag v(varyingType); |
| 378 this->addVarying(varyingName, &v); | 397 this->addCoordVarying(varyingName, &v, uniName, coords); |
| 379 | 398 |
| 380 const GrGLShaderVar& coords = | |
| 381 kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords()
? | |
| 382 fVS.positionAttribute() : | |
| 383 fVS.localCoordsAttribute(); | |
| 384 | |
| 385 // varying = matrix * coords (logically) | |
| 386 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingTyp
e); | 399 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingTyp
e); |
| 387 if (kVec2f_GrSLType == varyingType) { | |
| 388 fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;", | |
| 389 v.vsOut(), uniName, coords.c_str()); | |
| 390 } else { | |
| 391 fVS.codeAppendf("%s = %s * vec3(%s, 1);", | |
| 392 v.vsOut(), uniName, coords.c_str()); | |
| 393 } | |
| 394 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, | 400 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, |
| 395 (SkString(v.fsIn()), varyingType)); | 401 (SkString(v.fsIn()), varyingType)); |
| 396 } | 402 } |
| 397 } | 403 } |
| 398 | 404 |
| 399 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor, | 405 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor, |
| 400 GrGLProcessor::TextureSamplerArray* outSam
plers, | 406 GrGLProcessor::TextureSamplerArray* outSam
plers, |
| 401 GrGLInstalledProc* ip) { | 407 GrGLInstalledProc* ip) { |
| 402 int numTextures = processor.numTextures(); | 408 int numTextures = processor.numTextures(); |
| 403 ip->fSamplers.push_back_n(numTextures); | 409 ip->fSamplers.push_back_n(numTextures); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 } | 522 } |
| 517 | 523 |
| 518 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 524 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 519 | 525 |
| 520 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { | 526 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
| 521 int numProcs = fProcs.count(); | 527 int numProcs = fProcs.count(); |
| 522 for (int e = 0; e < numProcs; ++e) { | 528 for (int e = 0; e < numProcs; ++e) { |
| 523 SkDELETE(fProcs[e]); | 529 SkDELETE(fProcs[e]); |
| 524 } | 530 } |
| 525 } | 531 } |
| OLD | NEW |