Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "GrGLProgram.h" | 8 #include "GrGLProgram.h" |
| 9 | 9 |
| 10 #include "GrAllocator.h" | 10 #include "GrAllocator.h" |
| 11 #include "GrEffect.h" | 11 #include "GrEffect.h" |
| 12 #include "GrDrawEffect.h" | 12 #include "GrDrawEffect.h" |
| 13 #include "GrGLEffect.h" | 13 #include "GrGLEffect.h" |
| 14 #include "GrGpuGL.h" | 14 #include "GrGpuGL.h" |
| 15 #include "GrGLShaderVar.h" | 15 #include "GrGLShaderVar.h" |
| 16 #include "GrGLSL.h" | |
| 16 #include "SkTrace.h" | 17 #include "SkTrace.h" |
| 17 #include "SkXfermode.h" | 18 #include "SkXfermode.h" |
| 18 | 19 |
| 19 #include "SkRTConf.h" | 20 #include "SkRTConf.h" |
| 20 | 21 |
| 21 SK_DEFINE_INST_COUNT(GrGLProgram) | 22 SK_DEFINE_INST_COUNT(GrGLProgram) |
| 22 | 23 |
| 23 #define GL_CALL(X) GR_GL_CALL(fContext.interface(), X) | 24 #define GL_CALL(X) GR_GL_CALL(fContext.interface(), X) |
| 24 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContext.interface(), R, X) | 25 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContext.interface(), R, X) |
| 25 | 26 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 case GrGLProgramDesc::kCoverageISC_DualSrcOutput: | 106 case GrGLProgramDesc::kCoverageISC_DualSrcOutput: |
| 106 *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; | 107 *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; |
| 107 break; | 108 break; |
| 108 default: | 109 default: |
| 109 GrCrash("Unexpected dual source blend output"); | 110 GrCrash("Unexpected dual source blend output"); |
| 110 break; | 111 break; |
| 111 } | 112 } |
| 112 } | 113 } |
| 113 | 114 |
| 114 namespace { | 115 namespace { |
| 115 | |
| 116 // given two blend coeffecients determine whether the src | 116 // given two blend coeffecients determine whether the src |
| 117 // and/or dst computation can be omitted. | 117 // and/or dst computation can be omitted. |
| 118 inline void need_blend_inputs(SkXfermode::Coeff srcCoeff, | 118 inline void need_blend_inputs(SkXfermode::Coeff srcCoeff, |
| 119 SkXfermode::Coeff dstCoeff, | 119 SkXfermode::Coeff dstCoeff, |
| 120 bool* needSrcValue, | 120 bool* needSrcValue, |
| 121 bool* needDstValue) { | 121 bool* needDstValue) { |
| 122 if (SkXfermode::kZero_Coeff == srcCoeff) { | 122 if (SkXfermode::kZero_Coeff == srcCoeff) { |
| 123 switch (dstCoeff) { | 123 switch (dstCoeff) { |
| 124 // these all read the src | 124 // these all read the src |
| 125 case SkXfermode::kSC_Coeff: | 125 case SkXfermode::kSC_Coeff: |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 204 const char * outputVar, | 204 const char * outputVar, |
| 205 SkXfermode::Coeff uniformCoeff, | 205 SkXfermode::Coeff uniformCoeff, |
| 206 SkXfermode::Coeff colorCoeff, | 206 SkXfermode::Coeff colorCoeff, |
| 207 const char* filterColor, | 207 const char* filterColor, |
| 208 const char* inColor) { | 208 const char* inColor) { |
| 209 SkString colorStr, constStr; | 209 SkString colorStr, constStr; |
| 210 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); | 210 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); |
| 211 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor ); | 211 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor ); |
| 212 | 212 |
| 213 SkString sum; | 213 SkString sum; |
| 214 GrGLSLAdd4f(&sum, colorStr.c_str(), constStr.c_str()); | 214 GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str()); |
| 215 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); | 215 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); |
| 216 } | 216 } |
| 217 } | 217 } |
| 218 | 218 |
| 219 void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { | 219 GrSLConstantVec GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { |
| 220 switch (fDesc.fColorInput) { | 220 switch (fDesc.fColorInput) { |
| 221 case GrGLProgramDesc::kAttribute_ColorInput: { | 221 case GrGLProgramDesc::kAttribute_ColorInput: { |
| 222 builder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME); | 222 builder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME); |
| 223 const char *vsName, *fsName; | 223 const char *vsName, *fsName; |
| 224 builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); | 224 builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); |
| 225 builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName); | 225 builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName); |
| 226 *inColor = fsName; | 226 *inColor = fsName; |
| 227 } break; | 227 return kNone_GrSLConstantVec; |
| 228 } | |
| 228 case GrGLProgramDesc::kUniform_ColorInput: { | 229 case GrGLProgramDesc::kUniform_ColorInput: { |
| 229 const char* name; | 230 const char* name; |
| 230 fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::k Fragment_ShaderType, | 231 fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::k Fragment_ShaderType, |
| 231 kVec4f_GrSLType, "Co lor", &name); | 232 kVec4f_GrSLType, "Co lor", &name); |
| 232 *inColor = name; | 233 *inColor = name; |
| 233 break; | 234 return kNone_GrSLConstantVec; |
| 234 } | 235 } |
| 235 case GrGLProgramDesc::kTransBlack_ColorInput: | 236 case GrGLProgramDesc::kTransBlack_ColorInput: |
| 236 GrAssert(!"needComputedColor should be false."); | 237 inColor->reset(); |
| 237 break; | 238 return kZeros_GrSLConstantVec; |
| 238 case GrGLProgramDesc::kSolidWhite_ColorInput: | 239 case GrGLProgramDesc::kSolidWhite_ColorInput: |
| 239 break; | 240 inColor->reset(); |
| 241 return kOnes_GrSLConstantVec; | |
| 240 default: | 242 default: |
| 241 GrCrash("Unknown color type."); | 243 GrCrash("Unknown color type."); |
| 242 break; | 244 return kNone_GrSLConstantVec; |
| 243 } | 245 } |
| 244 } | 246 } |
| 245 | 247 |
| 246 void GrGLProgram::genUniformCoverage(GrGLShaderBuilder* builder, SkString* inOut Coverage) { | 248 GrSLConstantVec GrGLProgram::genInputCoverage(GrGLShaderBuilder* builder, SkStri ng* inCoverage) { |
| 247 const char* covUniName; | 249 switch (fDesc.fCoverageInput) { |
| 248 fUniformHandles.fCoverageUni = builder->addUniform(GrGLShaderBuilder::kFragm ent_ShaderType, | 250 case GrGLProgramDesc::kAttribute_ColorInput: { |
| 249 kVec4f_GrSLType, "Coverag e", &covUniName); | 251 builder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME); |
| 250 if (inOutCoverage->size()) { | 252 const char *vsName, *fsName; |
| 251 builder->fsCodeAppendf("\tvec4 uniCoverage = %s * %s;\n", | 253 builder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); |
| 252 covUniName, inOutCoverage->c_str()); | 254 builder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName); |
| 253 *inOutCoverage = "uniCoverage"; | 255 *inCoverage = fsName; |
| 254 } else { | 256 return kNone_GrSLConstantVec; |
| 255 *inOutCoverage = covUniName; | 257 } |
| 258 case GrGLProgramDesc::kUniform_ColorInput: { | |
| 259 const char* name; | |
| 260 fUniformHandles.fCoverageUni = | |
| 261 builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, | |
| 262 kVec4f_GrSLType, "Coverage", &name); | |
| 263 *inCoverage = name; | |
| 264 return kNone_GrSLConstantVec; | |
| 265 } | |
| 266 case GrGLProgramDesc::kTransBlack_ColorInput: | |
| 267 inCoverage->reset(); | |
| 268 return kZeros_GrSLConstantVec; | |
| 269 case GrGLProgramDesc::kSolidWhite_ColorInput: | |
| 270 inCoverage->reset(); | |
| 271 return kOnes_GrSLConstantVec; | |
| 272 default: | |
| 273 GrCrash("Unknown color type."); | |
| 274 return kNone_GrSLConstantVec; | |
| 256 } | 275 } |
| 257 } | 276 } |
| 258 | 277 |
| 259 namespace { | |
| 260 void gen_attribute_coverage(GrGLShaderBuilder* builder, | |
| 261 SkString* inOutCoverage) { | |
| 262 builder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME); | |
| 263 const char *vsName, *fsName; | |
| 264 builder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); | |
| 265 builder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName); | |
| 266 if (inOutCoverage->size()) { | |
| 267 builder->fsCodeAppendf("\tvec4 attrCoverage = %s * %s;\n", fsName, inOut Coverage->c_str()); | |
| 268 *inOutCoverage = "attrCoverage"; | |
| 269 } else { | |
| 270 *inOutCoverage = fsName; | |
| 271 } | |
| 272 } | |
| 273 } | |
| 274 | |
| 275 void GrGLProgram::genGeometryShader(GrGLShaderBuilder* builder) const { | 278 void GrGLProgram::genGeometryShader(GrGLShaderBuilder* builder) const { |
| 276 #if GR_GL_EXPERIMENTAL_GS | 279 #if GR_GL_EXPERIMENTAL_GS |
| 277 // TODO: The builder should add all this glue code. | 280 // TODO: The builder should add all this glue code. |
| 278 if (fDesc.fExperimentalGS) { | 281 if (fDesc.fExperimentalGS) { |
| 279 GrAssert(fContext.info().glslGeneration() >= k150_GrGLSLGeneration); | 282 GrAssert(fContext.info().glslGeneration() >= k150_GrGLSLGeneration); |
| 280 builder->fGSHeader.append("layout(triangles) in;\n" | 283 builder->fGSHeader.append("layout(triangles) in;\n" |
| 281 "layout(triangle_strip, max_vertices = 6) out ;\n"); | 284 "layout(triangle_strip, max_vertices = 6) out ;\n"); |
| 282 builder->gsCodeAppend("\tfor (int i = 0; i < 3; ++i) {\n" | 285 builder->gsCodeAppend("\tfor (int i = 0; i < 3; ++i) {\n" |
| 283 "\t\tgl_Position = gl_in[i].gl_Position;\n"); | 286 "\t\tgl_Position = gl_in[i].gl_Position;\n"); |
| 284 if (fDesc.fEmitsPointSize) { | 287 if (fDesc.fEmitsPointSize) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 } | 416 } |
| 414 | 417 |
| 415 return true; | 418 return true; |
| 416 } | 419 } |
| 417 | 420 |
| 418 bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { | 421 bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { |
| 419 GrAssert(0 == fProgramID); | 422 GrAssert(0 == fProgramID); |
| 420 | 423 |
| 421 GrGLShaderBuilder builder(fContext.info(), fUniformManager, fDesc); | 424 GrGLShaderBuilder builder(fContext.info(), fUniformManager, fDesc); |
| 422 | 425 |
| 423 SkXfermode::Coeff colorCoeff, uniformCoeff; | |
| 424 // The rest of transfer mode color filters have not been implemented | |
| 425 if (fDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) { | |
| 426 GR_DEBUGCODE(bool success =) | |
| 427 SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode> | |
| 428 (fDesc.fColorFilterXfermode), | |
| 429 &uniformCoeff, &colorCoeff); | |
| 430 GR_DEBUGASSERT(success); | |
| 431 } else { | |
| 432 colorCoeff = SkXfermode::kOne_Coeff; | |
| 433 uniformCoeff = SkXfermode::kZero_Coeff; | |
| 434 } | |
| 435 | |
| 436 // no need to do the color filter if coverage is 0. The output color is scal ed by the coverage. | |
| 437 // All the dual source outputs are scaled by the coverage as well. | |
| 438 if (GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fCoverageInput) { | |
| 439 colorCoeff = SkXfermode::kZero_Coeff; | |
| 440 uniformCoeff = SkXfermode::kZero_Coeff; | |
| 441 } | |
| 442 | |
| 443 // If we know the final color is going to be all zeros then we can | |
| 444 // simplify the color filter coefficients. needComputedColor will then | |
| 445 // come out false below. | |
| 446 if (GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fColorInput) { | |
| 447 colorCoeff = SkXfermode::kZero_Coeff; | |
| 448 if (SkXfermode::kDC_Coeff == uniformCoeff || | |
| 449 SkXfermode::kDA_Coeff == uniformCoeff) { | |
| 450 uniformCoeff = SkXfermode::kZero_Coeff; | |
| 451 } else if (SkXfermode::kIDC_Coeff == uniformCoeff || | |
| 452 SkXfermode::kIDA_Coeff == uniformCoeff) { | |
| 453 uniformCoeff = SkXfermode::kOne_Coeff; | |
| 454 } | |
| 455 } | |
| 456 | |
| 457 bool needColorFilterUniform; | |
| 458 bool needComputedColor; | |
| 459 need_blend_inputs(uniformCoeff, colorCoeff, | |
| 460 &needColorFilterUniform, &needComputedColor); | |
| 461 | |
| 462 // the dual source output has no canonical var name, have to | 426 // the dual source output has no canonical var name, have to |
| 463 // declare an output, which is incompatible with gl_FragColor/gl_FragData. | 427 // declare an output, which is incompatible with gl_FragColor/gl_FragData. |
| 464 bool dualSourceOutputWritten = false; | 428 bool dualSourceOutputWritten = false; |
| 465 | 429 |
| 466 GrGLShaderVar colorOutput; | 430 GrGLShaderVar colorOutput; |
| 467 bool isColorDeclared = GrGLSLSetupFSColorOuput(fContext.info().glslGeneratio n(), | 431 bool isColorDeclared = GrGLSLSetupFSColorOuput(fContext.info().glslGeneratio n(), |
| 468 declared_color_output_name(), | 432 declared_color_output_name(), |
| 469 &colorOutput); | 433 &colorOutput); |
| 470 if (isColorDeclared) { | 434 if (isColorDeclared) { |
| 471 builder.fFSOutputs.push_back(colorOutput); | 435 builder.fFSOutputs.push_back(colorOutput); |
| 472 } | 436 } |
| 473 | 437 |
| 474 const char* viewMName; | 438 const char* viewMName; |
| 475 fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVert ex_ShaderType, | 439 fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVert ex_ShaderType, |
| 476 kMat33f_GrSLType, "ViewM ", &viewMName); | 440 kMat33f_GrSLType, "ViewM ", &viewMName); |
| 477 | 441 |
| 478 | 442 |
| 479 builder.vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" | 443 builder.vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" |
| 480 "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", | 444 "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", |
| 481 viewMName, builder.positionAttribute().getName().c_str ()); | 445 viewMName, builder.positionAttribute().getName().c_str ()); |
| 482 | 446 |
| 483 // incoming color to current stage being processed. | 447 // incoming color to current stage being processed. |
| 484 SkString inColor; | 448 SkString inColor; |
| 485 | 449 GrSLConstantVec knownColorValue = this->genInputColor(&builder, &inColor); |
| 486 if (needComputedColor) { | |
| 487 this->genInputColor(&builder, &inColor); | |
| 488 } | |
| 489 | 450 |
| 490 // we output point size in the GS if present | 451 // we output point size in the GS if present |
| 491 if (fDesc.fEmitsPointSize | 452 if (fDesc.fEmitsPointSize |
| 492 #if GR_GL_EXPERIMENTAL_GS | 453 #if GR_GL_EXPERIMENTAL_GS |
| 493 && !fDesc.fExperimentalGS | 454 && !fDesc.fExperimentalGS |
| 494 #endif | 455 #endif |
| 495 ) { | 456 ) { |
| 496 builder.vsCodeAppend("\tgl_PointSize = 1.0;\n"); | 457 builder.vsCodeAppend("\tgl_PointSize = 1.0;\n"); |
| 497 } | 458 } |
| 498 | 459 |
| 499 /////////////////////////////////////////////////////////////////////////// | 460 // Get the coeffs for the Mode-based color filter, determine if color is nee ded. |
| 500 // compute the final color | 461 SkXfermode::Coeff colorCoeff; |
| 462 SkXfermode::Coeff filterColorCoeff; | |
| 463 SkAssertResult( | |
| 464 SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>(fDesc.fColorFilter Xfermode), | |
| 465 &filterColorCoeff, | |
| 466 &colorCoeff)); | |
| 467 bool needColor, needFilterColor; | |
| 468 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor ); | |
| 501 | 469 |
| 502 // if we have color stages string them together, feeding the output color | 470 if (needColor) { |
| 503 // of each to the next and generating code for each stage. | 471 //////////////////////////////////////////////////////////////////////// /// |
| 504 if (needComputedColor) { | 472 // compute the color |
| 473 // if we have color stages string them together, feeding the output colo r | |
| 474 // of each to the next and generating code for each stage. | |
| 505 SkString outColor; | 475 SkString outColor; |
| 506 for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) { | 476 for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) { |
| 507 if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) { | 477 if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) { |
| 478 if (kZeros_GrSLConstantVec == knownColorValue) { | |
| 479 // Effects have no way to communicate zeros, they treat an e mpty string as ones. | |
| 480 inColor = "initialColor"; | |
| 481 builder.fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZerosVecf(4)); | |
| 482 } | |
| 508 // create var to hold stage result | 483 // create var to hold stage result |
| 509 outColor = "color"; | 484 outColor = "color"; |
| 510 outColor.appendS32(s); | 485 outColor.appendS32(s); |
| 511 builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); | 486 builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); |
| 512 | 487 |
| 513 builder.setCurrentStage(s); | 488 builder.setCurrentStage(s); |
| 514 fEffects[s] = builder.createAndEmitGLEffect(*stages[s], | 489 fEffects[s] = builder.createAndEmitGLEffect(*stages[s], |
| 515 fDesc.fEffectKeys[s] , | 490 fDesc.fEffectKeys[s] , |
| 516 inColor.size() ? inC olor.c_str() : NULL, | 491 inColor.size() ? inC olor.c_str() : NULL, |
| 517 outColor.c_str(), | 492 outColor.c_str(), |
| 518 &fUniformHandles.fEf fectSamplerUnis[s]); | 493 &fUniformHandles.fEf fectSamplerUnis[s]); |
| 519 builder.setNonStage(); | 494 builder.setNonStage(); |
| 520 inColor = outColor; | 495 inColor = outColor; |
| 496 knownColorValue = kNone_GrSLConstantVec; | |
| 521 } | 497 } |
| 522 } | 498 } |
| 523 } | 499 } |
| 524 | 500 |
| 525 // if have all ones or zeros for the "dst" input to the color filter then we | 501 // Insert the color filter. This will soon be replaced by a color effect. |
| 526 // may be able to make additional optimizations. | 502 if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) { |
| 527 if (needColorFilterUniform && needComputedColor && !inColor.size()) { | 503 const char* colorFilterColorUniName = NULL; |
| 528 GrAssert(GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.fColorInput); | 504 fUniformHandles.fColorFilterUni = builder.addUniform(GrGLShaderBuilder:: kFragment_ShaderType, |
| 529 bool uniformCoeffIsZero = SkXfermode::kIDC_Coeff == uniformCoeff || | 505 kVec4f_GrSLType, "F ilterColor", |
| 530 SkXfermode::kIDA_Coeff == uniformCoeff; | 506 &colorFilterColorUn iName); |
| 531 if (uniformCoeffIsZero) { | 507 |
| 532 uniformCoeff = SkXfermode::kZero_Coeff; | 508 builder.fsCodeAppend("\tvec4 filteredColor;\n"); |
| 533 bool bogus; | 509 const char* color; |
| 534 need_blend_inputs(SkXfermode::kZero_Coeff, colorCoeff, | 510 // add_color_filter requires a real input string. |
| 535 &needColorFilterUniform, &bogus); | 511 if (knownColorValue == kOnes_GrSLConstantVec) { |
| 512 color = GrGLSLOnesVecf(4); | |
| 513 } else if (knownColorValue == kZeros_GrSLConstantVec) { | |
| 514 color = GrGLSLZerosVecf(4); | |
| 515 } else { | |
| 516 color = inColor.c_str(); | |
| 536 } | 517 } |
| 537 } | 518 add_color_filter(&builder, "filteredColor", filterColorCoeff, |
| 538 const char* colorFilterColorUniName = NULL; | |
| 539 if (needColorFilterUniform) { | |
| 540 fUniformHandles.fColorFilterUni = builder.addUniform( | |
| 541 GrGLShaderBuilder::kFrag ment_ShaderType, | |
| 542 kVec4f_GrSLType, "Filter Color", | |
| 543 &colorFilterColorUniName ); | |
| 544 } | |
| 545 bool wroteFragColorZero = false; | |
| 546 if (SkXfermode::kZero_Coeff == uniformCoeff && | |
| 547 SkXfermode::kZero_Coeff == colorCoeff) { | |
| 548 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), GrG LSLZerosVecf(4)); | |
| 549 wroteFragColorZero = true; | |
| 550 } else if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) { | |
| 551 builder.fsCodeAppend("\tvec4 filteredColor;\n"); | |
| 552 const char* color = adjustInColor(inColor); | |
| 553 add_color_filter(&builder, "filteredColor", uniformCoeff, | |
| 554 colorCoeff, colorFilterColorUniName, color); | 519 colorCoeff, colorFilterColorUniName, color); |
| 555 inColor = "filteredColor"; | 520 inColor = "filteredColor"; |
| 556 } | 521 } |
| 557 | 522 |
| 558 /////////////////////////////////////////////////////////////////////////// | 523 /////////////////////////////////////////////////////////////////////////// |
| 559 // compute the partial coverage (coverage stages and edge aa) | 524 // compute the partial coverage |
| 560 | 525 |
| 526 // incoming coverage to current stage being processed. | |
| 561 SkString inCoverage; | 527 SkString inCoverage; |
| 562 bool coverageIsZero = GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fCove rageInput; | 528 GrSLConstantVec knownCoverageValue = this->genInputCoverage(&builder, &inCov erage); |
| 563 // we don't need to compute coverage at all if we know the final shader | 529 |
| 564 // output will be zero and we don't have a dual src blend output. | 530 SkString outCoverage; |
|
robertphillips
2013/04/18 19:12:24
The '&' seems odd here - as does having startStage
bsalomon
2013/04/18 19:36:37
Agreed, this was just moved from the old code.. no
| |
| 565 if (!wroteFragColorZero || GrGLProgramDesc::kNone_DualSrcOutput != fDesc.fDu alSrcOutput) { | 531 const int& startStage = fDesc.fFirstCoverageStage; |
| 532 for (int s = startStage; s < GrDrawState::kNumStages; ++s) { | |
| 533 if (fDesc.fEffectKeys[s]) { | |
| 534 if (kZeros_GrSLConstantVec == knownCoverageValue) { | |
| 535 // Effects have no way to communicate zeros, they treat an empty string as ones. | |
| 536 inCoverage = "initialCoverage"; | |
| 537 builder.fsCodeAppendf("\tvec4 %s = %s;\n", inCoverage.c_str(), G rGLSLZerosVecf(4)); | |
| 538 } | |
| 539 // create var to hold stage output | |
| 540 outCoverage = "coverage"; | |
| 541 outCoverage.appendS32(s); | |
| 542 builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str()); | |
| 566 | 543 |
| 567 if (!coverageIsZero) { | 544 builder.setCurrentStage(s); |
| 568 switch (fDesc.fCoverageInput) { | 545 fEffects[s] = builder.createAndEmitGLEffect( |
| 569 case GrGLProgramDesc::kSolidWhite_ColorInput: | 546 *stages[s], |
| 570 // empty string implies solid white | 547 fDesc.fEffectKeys[s], |
| 571 break; | 548 inCoverage.size() ? inCoverage.c_str () : NULL, |
| 572 case GrGLProgramDesc::kAttribute_ColorInput: | 549 outCoverage.c_str(), |
| 573 gen_attribute_coverage(&builder, &inCoverage); | 550 &fUniformHandles.fEffectSamplerUnis[ s]); |
| 574 break; | 551 builder.setNonStage(); |
| 575 case GrGLProgramDesc::kUniform_ColorInput: | 552 inCoverage = outCoverage; |
| 576 this->genUniformCoverage(&builder, &inCoverage); | 553 knownCoverageValue = kNone_GrSLConstantVec; |
| 577 break; | 554 } |
| 578 default: | 555 } |
| 579 GrCrash("Unexpected input coverage."); | |
| 580 } | |
| 581 | 556 |
| 582 SkString outCoverage; | 557 // discard if coverage is zero |
|
robertphillips
2013/04/18 19:12:24
constant on LHS?
bsalomon
2013/04/18 19:36:37
Done.
| |
| 583 const int& startStage = fDesc.fFirstCoverageStage; | 558 if (fDesc.fDiscardIfZeroCoverage && knownCoverageValue != kOnes_GrSLConstant Vec) { |
| 584 for (int s = startStage; s < GrDrawState::kNumStages; ++s) { | 559 if (kZeros_GrSLConstantVec == knownCoverageValue) { |
| 585 if (fDesc.fEffectKeys[s]) { | 560 // This is unfortunate. |
| 586 // create var to hold stage output | 561 builder.fsCodeAppend("\tdiscard;\n"); |
| 587 outCoverage = "coverage"; | 562 } else { |
| 588 outCoverage.appendS32(s); | 563 builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\ t\tdiscard;\n\t}\n", |
| 589 builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str()); | 564 inCoverage.c_str()); |
| 565 } | |
| 566 } | |
| 590 | 567 |
| 591 builder.setCurrentStage(s); | 568 if (GrGLProgramDesc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) { |
| 592 fEffects[s] = builder.createAndEmitGLEffect( | 569 builder.fFSOutputs.push_back().set(kVec4f_GrSLType, |
| 593 *stages[s], | 570 GrGLShaderVar::kOut_TypeModifier, |
| 594 fDesc.fEffectKeys[s], | 571 dual_source_output_name()); |
| 595 inCoverage.size() ? inCovera ge.c_str() : NULL, | 572 SkString coeff; |
| 596 outCoverage.c_str(), | 573 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; |
| 597 &fUniformHandles.fEffectSamp lerUnis[s]); | 574 if (GrGLProgramDesc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput) { |
| 598 builder.setNonStage(); | 575 if (GrGLProgramDesc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOut put) { |
| 599 inCoverage = outCoverage; | 576 // Get (1-A) into coeff |
| 600 } | 577 SkString inColorAlpha; |
| 601 } | 578 GrGLSLGetComponent4f(&inColorAlpha, |
| 602 | 579 inColor.c_str(), |
| 603 // discard if coverage is zero | 580 kA_GrColorComponentFlag, |
| 604 if (fDesc.fDiscardIfZeroCoverage && !outCoverage.isEmpty()) { | 581 knownColorValue, |
| 605 builder.fsCodeAppendf( | 582 true); |
| 606 "\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\ t}\n", | 583 knownCoeffValue = GrGLSLSubtractf<1>(&coeff, |
| 607 outCoverage.c_str()); | 584 NULL, |
| 585 inColorAlpha.c_str(), | |
| 586 kOnes_GrSLConstantVec, | |
| 587 knownColorValue, | |
| 588 true); | |
| 589 } else { | |
| 590 GrAssert(GrGLProgramDesc::kCoverageISC_DualSrcOutput == fDesc.fD ualSrcOutput); | |
| 591 // Get (1-RGBA) into coeff | |
| 592 knownCoeffValue = GrGLSLSubtractf<4>(&coeff, | |
| 593 NULL, | |
| 594 inColor.c_str(), | |
| 595 kOnes_GrSLConstantVec, | |
| 596 knownColorValue, | |
| 597 true); | |
| 608 } | 598 } |
| 609 } | 599 } |
| 610 | 600 // Get coeff * coverage into modulate and then write that to the dual so urce output. |
| 611 if (GrGLProgramDesc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) { | 601 SkString modulate; |
| 612 builder.fFSOutputs.push_back().set(kVec4f_GrSLType, | 602 GrGLSLModulatef<4>(&modulate, |
| 613 GrGLShaderVar::kOut_TypeModifier, | 603 coeff.c_str(), |
| 614 dual_source_output_name()); | 604 inCoverage.c_str(), |
| 615 bool outputIsZero = coverageIsZero; | 605 knownCoeffValue, |
| 616 SkString coeff; | 606 knownCoverageValue, |
| 617 if (!outputIsZero && | 607 false); |
| 618 GrGLProgramDesc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput && !wroteFragColorZero) { | 608 builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulat e.c_str()); |
| 619 if (!inColor.size()) { | 609 dualSourceOutputWritten = true; |
| 620 outputIsZero = true; | |
| 621 } else { | |
| 622 if (GrGLProgramDesc::kCoverageISA_DualSrcOutput == fDesc.fDu alSrcOutput) { | |
| 623 coeff.printf("(1 - %s.a)", inColor.c_str()); | |
| 624 } else { | |
| 625 coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str()); | |
| 626 } | |
| 627 } | |
| 628 } | |
| 629 if (outputIsZero) { | |
| 630 builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), GrGLSLZerosVecf(4)); | |
| 631 } else { | |
| 632 SkString modulate; | |
| 633 GrGLSLModulate4f(&modulate, coeff.c_str(), inCoverage.c_str()); | |
| 634 builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulate.c_str()); | |
| 635 } | |
| 636 dualSourceOutputWritten = true; | |
| 637 } | |
| 638 } | 610 } |
| 639 | 611 |
| 640 /////////////////////////////////////////////////////////////////////////// | 612 /////////////////////////////////////////////////////////////////////////// |
| 641 // combine color and coverage as frag color | 613 // combine color and coverage as frag color |
| 642 | 614 |
| 643 if (!wroteFragColorZero) { | 615 // Get color * coverage into modulate and write that to frag shader's output . |
| 644 if (coverageIsZero) { | 616 SkString modulate; |
| 645 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), GrGLSLZerosVecf(4)); | 617 GrGLSLModulatef<4>(&modulate, |
| 646 } else { | 618 inColor.c_str(), |
| 647 SkString modulate; | 619 inCoverage.c_str(), |
| 648 GrGLSLModulate4f(&modulate, inColor.c_str(), inCoverage.c_str()); | 620 knownColorValue, |
| 649 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), modulate.c_str()); | 621 knownCoverageValue, |
| 650 } | 622 false); |
| 651 } | 623 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), modulat e.c_str()); |
| 652 | 624 |
| 653 /////////////////////////////////////////////////////////////////////////// | 625 /////////////////////////////////////////////////////////////////////////// |
| 654 // insert GS | 626 // insert GS |
| 655 #if GR_DEBUG | 627 #if GR_DEBUG |
| 656 this->genGeometryShader(&builder); | 628 this->genGeometryShader(&builder); |
| 657 #endif | 629 #endif |
| 658 | 630 |
| 659 /////////////////////////////////////////////////////////////////////////// | 631 /////////////////////////////////////////////////////////////////////////// |
| 660 // compile and setup attribs and unis | 632 // compile and setup attribs and unis |
| 661 | 633 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 690 | 662 |
| 691 GL_CALL(AttachShader(fProgramID, fVShaderID)); | 663 GL_CALL(AttachShader(fProgramID, fVShaderID)); |
| 692 if (fGShaderID) { | 664 if (fGShaderID) { |
| 693 GL_CALL(AttachShader(fProgramID, fGShaderID)); | 665 GL_CALL(AttachShader(fProgramID, fGShaderID)); |
| 694 } | 666 } |
| 695 GL_CALL(AttachShader(fProgramID, fFShaderID)); | 667 GL_CALL(AttachShader(fProgramID, fFShaderID)); |
| 696 | 668 |
| 697 if (bindColorOut) { | 669 if (bindColorOut) { |
| 698 GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name() )); | 670 GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name() )); |
| 699 } | 671 } |
| 700 if (bindDualSrcOut) { | 672 if (bindDualSrcOut) { |
|
robertphillips
2013/04/18 19:12:24
???
bsalomon
2013/04/18 19:36:37
Oops, left in from debugging.
| |
| 701 GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output _name())); | 673 //GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_outp ut_name())); |
| 702 } | 674 } |
| 703 | 675 |
| 704 // Bind the attrib locations to same values for all shaders | 676 // Bind the attrib locations to same values for all shaders |
| 705 GL_CALL(BindAttribLocation(fProgramID, | 677 GL_CALL(BindAttribLocation(fProgramID, |
| 706 fDesc.fPositionAttributeIndex, | 678 fDesc.fPositionAttributeIndex, |
| 707 builder.positionAttribute().c_str())); | 679 builder.positionAttribute().c_str())); |
| 708 if (-1 != fDesc.fLocalCoordAttributeIndex) { | 680 if (-1 != fDesc.fLocalCoordAttributeIndex) { |
| 709 GL_CALL(BindAttribLocation(fProgramID, | 681 GL_CALL(BindAttribLocation(fProgramID, |
| 710 fDesc.fLocalCoordAttributeIndex, | 682 fDesc.fLocalCoordAttributeIndex, |
| 711 builder.localCoordsAttribute().c_str())); | 683 builder.localCoordsAttribute().c_str())); |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 966 SkScalarToFloat(m[SkMatrix::kMTransX]), | 938 SkScalarToFloat(m[SkMatrix::kMTransX]), |
| 967 SkScalarToFloat(m[SkMatrix::kMTransY]), | 939 SkScalarToFloat(m[SkMatrix::kMTransY]), |
| 968 SkScalarToFloat(m[SkMatrix::kMPersp2]) | 940 SkScalarToFloat(m[SkMatrix::kMPersp2]) |
| 969 }; | 941 }; |
| 970 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); | 942 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); |
| 971 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 943 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
| 972 fMatrixState.fRenderTargetSize = size; | 944 fMatrixState.fRenderTargetSize = size; |
| 973 fMatrixState.fRenderTargetOrigin = rt->origin(); | 945 fMatrixState.fRenderTargetOrigin = rt->origin(); |
| 974 } | 946 } |
| 975 } | 947 } |
| OLD | NEW |