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; |
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 |
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 // default coeff to ones for kCoverage_DualSrcOutput |
596 outCoverage.c_str(), | 573 SkString coeff; |
597 &fUniformHandles.fEffectSamp
lerUnis[s]); | 574 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; |
598 builder.setNonStage(); | 575 if (GrGLProgramDesc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput)
{ |
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, |
608 } | 585 inColorAlpha.c_str(), |
| 586 kOnes_GrSLConstantVec, |
| 587 knownColorValue, |
| 588 true); |
| 589 } else if (GrGLProgramDesc::kCoverageISC_DualSrcOutput == fDesc.fDualSrc
Output) { |
| 590 // Get (1-RGBA) into coeff |
| 591 knownCoeffValue = GrGLSLSubtractf<4>(&coeff, |
| 592 NULL, |
| 593 inColor.c_str(), |
| 594 kOnes_GrSLConstantVec, |
| 595 knownColorValue, |
| 596 true); |
609 } | 597 } |
610 | 598 // Get coeff * coverage into modulate and then write that to the dual so
urce output. |
611 if (GrGLProgramDesc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) { | 599 SkString modulate; |
612 builder.fFSOutputs.push_back().set(kVec4f_GrSLType, | 600 GrGLSLModulatef<4>(&modulate, |
613 GrGLShaderVar::kOut_TypeModifier, | 601 coeff.c_str(), |
614 dual_source_output_name()); | 602 inCoverage.c_str(), |
615 bool outputIsZero = coverageIsZero; | 603 knownCoeffValue, |
616 SkString coeff; | 604 knownCoverageValue, |
617 if (!outputIsZero && | 605 false); |
618 GrGLProgramDesc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput
&& !wroteFragColorZero) { | 606 builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(), modulat
e.c_str()); |
619 if (!inColor.size()) { | 607 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 } | 608 } |
639 | 609 |
640 /////////////////////////////////////////////////////////////////////////// | 610 /////////////////////////////////////////////////////////////////////////// |
641 // combine color and coverage as frag color | 611 // combine color and coverage as frag color |
642 | 612 |
643 if (!wroteFragColorZero) { | 613 // Get color * coverage into modulate and write that to frag shader's output
. |
644 if (coverageIsZero) { | 614 SkString modulate; |
645 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(),
GrGLSLZerosVecf(4)); | 615 GrGLSLModulatef<4>(&modulate, |
646 } else { | 616 inColor.c_str(), |
647 SkString modulate; | 617 inCoverage.c_str(), |
648 GrGLSLModulate4f(&modulate, inColor.c_str(), inCoverage.c_str()); | 618 knownColorValue, |
649 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(),
modulate.c_str()); | 619 knownCoverageValue, |
650 } | 620 false); |
651 } | 621 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), modulat
e.c_str()); |
652 | 622 |
653 /////////////////////////////////////////////////////////////////////////// | 623 /////////////////////////////////////////////////////////////////////////// |
654 // insert GS | 624 // insert GS |
655 #if GR_DEBUG | 625 #if GR_DEBUG |
656 this->genGeometryShader(&builder); | 626 this->genGeometryShader(&builder); |
657 #endif | 627 #endif |
658 | 628 |
659 /////////////////////////////////////////////////////////////////////////// | 629 /////////////////////////////////////////////////////////////////////////// |
660 // compile and setup attribs and unis | 630 // compile and setup attribs and unis |
661 | 631 |
(...skipping 29 matching lines...) Expand all Loading... |
691 GL_CALL(AttachShader(fProgramID, fVShaderID)); | 661 GL_CALL(AttachShader(fProgramID, fVShaderID)); |
692 if (fGShaderID) { | 662 if (fGShaderID) { |
693 GL_CALL(AttachShader(fProgramID, fGShaderID)); | 663 GL_CALL(AttachShader(fProgramID, fGShaderID)); |
694 } | 664 } |
695 GL_CALL(AttachShader(fProgramID, fFShaderID)); | 665 GL_CALL(AttachShader(fProgramID, fFShaderID)); |
696 | 666 |
697 if (bindColorOut) { | 667 if (bindColorOut) { |
698 GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name()
)); | 668 GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name()
)); |
699 } | 669 } |
700 if (bindDualSrcOut) { | 670 if (bindDualSrcOut) { |
701 GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output
_name())); | 671 //GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_outp
ut_name())); |
702 } | 672 } |
703 | 673 |
704 // Bind the attrib locations to same values for all shaders | 674 // Bind the attrib locations to same values for all shaders |
705 GL_CALL(BindAttribLocation(fProgramID, | 675 GL_CALL(BindAttribLocation(fProgramID, |
706 fDesc.fPositionAttributeIndex, | 676 fDesc.fPositionAttributeIndex, |
707 builder.positionAttribute().c_str())); | 677 builder.positionAttribute().c_str())); |
708 if (-1 != fDesc.fLocalCoordAttributeIndex) { | 678 if (-1 != fDesc.fLocalCoordAttributeIndex) { |
709 GL_CALL(BindAttribLocation(fProgramID, | 679 GL_CALL(BindAttribLocation(fProgramID, |
710 fDesc.fLocalCoordAttributeIndex, | 680 fDesc.fLocalCoordAttributeIndex, |
711 builder.localCoordsAttribute().c_str())); | 681 builder.localCoordsAttribute().c_str())); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 SkScalarToFloat(m[SkMatrix::kMTransX]), | 936 SkScalarToFloat(m[SkMatrix::kMTransX]), |
967 SkScalarToFloat(m[SkMatrix::kMTransY]), | 937 SkScalarToFloat(m[SkMatrix::kMTransY]), |
968 SkScalarToFloat(m[SkMatrix::kMPersp2]) | 938 SkScalarToFloat(m[SkMatrix::kMPersp2]) |
969 }; | 939 }; |
970 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); | 940 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); |
971 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 941 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
972 fMatrixState.fRenderTargetSize = size; | 942 fMatrixState.fRenderTargetSize = size; |
973 fMatrixState.fRenderTargetOrigin = rt->origin(); | 943 fMatrixState.fRenderTargetOrigin = rt->origin(); |
974 } | 944 } |
975 } | 945 } |
OLD | NEW |