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" |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 break; | 391 break; |
392 default: | 392 default: |
393 GrCrash("Unexpected xfer coeff."); | 393 GrCrash("Unexpected xfer coeff."); |
394 break; | 394 break; |
395 } | 395 } |
396 } | 396 } |
397 /** | 397 /** |
398 * Adds a line to the fragment shader code which modifies the color by | 398 * Adds a line to the fragment shader code which modifies the color by |
399 * the specified color filter. | 399 * the specified color filter. |
400 */ | 400 */ |
401 void add_color_filter(SkString* fsCode, const char * outputVar, | 401 void add_color_filter(GrGLShaderBuilder* builder, |
| 402 const char * outputVar, |
402 SkXfermode::Coeff uniformCoeff, | 403 SkXfermode::Coeff uniformCoeff, |
403 SkXfermode::Coeff colorCoeff, | 404 SkXfermode::Coeff colorCoeff, |
404 const char* filterColor, | 405 const char* filterColor, |
405 const char* inColor) { | 406 const char* inColor) { |
406 SkString colorStr, constStr; | 407 SkString colorStr, constStr; |
407 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); | 408 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); |
408 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); | 409 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); |
409 | 410 |
410 fsCode->appendf("\t%s = ", outputVar); | 411 SkString sum; |
411 GrGLSLAdd4f(fsCode, colorStr.c_str(), constStr.c_str()); | 412 GrGLSLAdd4f(&sum, colorStr.c_str(), constStr.c_str()); |
412 fsCode->append(";\n"); | 413 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); |
413 } | 414 } |
414 } | 415 } |
415 | 416 |
416 bool GrGLProgram::genEdgeCoverage(SkString* coverageVar, | 417 bool GrGLProgram::genEdgeCoverage(SkString* coverageVar, |
417 GrGLShaderBuilder* builder) const { | 418 GrGLShaderBuilder* builder) const { |
418 if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) { | 419 if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) { |
419 const char *vsName, *fsName; | 420 const char *vsName, *fsName; |
420 builder->addVarying(kVec4f_GrSLType, "Edge", &vsName, &fsName); | 421 builder->addVarying(kVec4f_GrSLType, "Edge", &vsName, &fsName); |
421 builder->fVSAttrs.push_back().set(kVec4f_GrSLType, | 422 builder->fVSAttrs.push_back().set(kVec4f_GrSLType, |
422 GrGLShaderVar::kAttribute_TypeModifier
, | 423 GrGLShaderVar::kAttribute_TypeModifier
, |
423 EDGE_ATTR_NAME); | 424 EDGE_ATTR_NAME); |
424 builder->fVSCode.appendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName); | 425 builder->vsCodeAppendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName); |
425 switch (fDesc.fVertexEdgeType) { | 426 switch (fDesc.fVertexEdgeType) { |
426 case GrDrawState::kHairLine_EdgeType: | 427 case GrDrawState::kHairLine_EdgeType: |
427 builder->fFSCode.appendf("\tfloat edgeAlpha = abs(dot(vec3(%s.xy,1),
%s.xyz));\n", builder->fragmentPosition(), fsName); | 428 builder->fsCodeAppendf("\tfloat edgeAlpha = abs(dot(vec3(%s.xy,1), %
s.xyz));\n", builder->fragmentPosition(), fsName); |
428 builder->fFSCode.append("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"
); | 429 builder->fsCodeAppendf("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n")
; |
429 break; | 430 break; |
430 case GrDrawState::kQuad_EdgeType: | 431 case GrDrawState::kQuad_EdgeType: |
431 builder->fFSCode.append("\tfloat edgeAlpha;\n"); | 432 builder->fsCodeAppendf("\tfloat edgeAlpha;\n"); |
432 // keep the derivative instructions outside the conditional | 433 // keep the derivative instructions outside the conditional |
433 builder->fFSCode.appendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); | 434 builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); |
434 builder->fFSCode.appendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); | 435 builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); |
435 builder->fFSCode.appendf("\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsNa
me, fsName); | 436 builder->fsCodeAppendf("\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName
, fsName); |
436 // today we know z and w are in device space. We could use derivativ
es | 437 // today we know z and w are in device space. We could use derivativ
es |
437 builder->fFSCode.appendf("\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5,
1.0);\n", fsName, fsName); | 438 builder->fsCodeAppendf("\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1
.0);\n", fsName, fsName); |
438 builder->fFSCode.append ("\t} else {\n"); | 439 builder->fsCodeAppendf ("\t} else {\n"); |
439 builder->fFSCode.appendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvd
x.y,\n" | 440 builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.
y,\n" |
440 "\t\t 2.0*%s.x*duvdy.x - duvd
y.y);\n", | 441 "\t\t 2.0*%s.x*duvdy.x - duvdy.
y);\n", |
441 fsName, fsName); | 442 fsName, fsName); |
442 builder->fFSCode.appendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fs
Name, fsName, fsName); | 443 builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsNa
me, fsName, fsName); |
443 builder->fFSCode.append("\t\tedgeAlpha = clamp(0.5 - edgeAlpha / len
gth(gF), 0.0, 1.0);\n" | 444 builder->fsCodeAppendf("\t\tedgeAlpha = clamp(0.5 - edgeAlpha / leng
th(gF), 0.0, 1.0);\n" |
444 "\t}\n"); | 445 "\t}\n"); |
445 if (kES2_GrGLBinding == fContext.info().binding()) { | 446 if (kES2_GrGLBinding == fContext.info().binding()) { |
446 builder->fHeader.printf("#extension GL_OES_standard_derivatives:
enable\n"); | 447 builder->fHeader.append("#extension GL_OES_standard_derivatives:
enable\n"); |
447 } | 448 } |
448 break; | 449 break; |
449 case GrDrawState::kHairQuad_EdgeType: | 450 case GrDrawState::kHairQuad_EdgeType: |
450 builder->fFSCode.appendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); | 451 builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); |
451 builder->fFSCode.appendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); | 452 builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); |
452 builder->fFSCode.appendf("\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.
y,\n" | 453 builder->fsCodeAppendf("\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,
\n" |
453 "\t 2.0*%s.x*duvdy.x - duvdy.
y);\n", | 454 "\t 2.0*%s.x*duvdy.x - duvdy.y)
;\n", |
454 fsName, fsName); | 455 fsName, fsName); |
455 builder->fFSCode.appendf("\tfloat edgeAlpha = (%s.x*%s.x - %s.y);\n"
, fsName, fsName, fsName); | 456 builder->fsCodeAppendf("\tfloat edgeAlpha = (%s.x*%s.x - %s.y);\n",
fsName, fsName, fsName); |
456 builder->fFSCode.append("\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / do
t(gF, gF));\n"); | 457 builder->fsCodeAppend("\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(
gF, gF));\n"); |
457 builder->fFSCode.append("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"
); | 458 builder->fsCodeAppend("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); |
458 if (kES2_GrGLBinding == fContext.info().binding()) { | 459 if (kES2_GrGLBinding == fContext.info().binding()) { |
459 builder->fHeader.printf("#extension GL_OES_standard_derivatives:
enable\n"); | 460 builder->fHeader.printf("#extension GL_OES_standard_derivatives:
enable\n"); |
460 } | 461 } |
461 break; | 462 break; |
462 case GrDrawState::kCircle_EdgeType: | 463 case GrDrawState::kCircle_EdgeType: |
463 builder->fFSCode.append("\tfloat edgeAlpha;\n"); | 464 builder->fsCodeAppend("\tfloat edgeAlpha;\n"); |
464 builder->fFSCode.appendf("\tfloat d = distance(%s.xy, %s.xy);\n", bu
ilder->fragmentPosition(), fsName); | 465 builder->fsCodeAppendf("\tfloat d = distance(%s.xy, %s.xy);\n", buil
der->fragmentPosition(), fsName); |
465 builder->fFSCode.appendf("\tfloat outerAlpha = smoothstep(d - 0.5, d
+ 0.5, %s.z);\n", fsName); | 466 builder->fsCodeAppendf("\tfloat outerAlpha = smoothstep(d - 0.5, d +
0.5, %s.z);\n", fsName); |
466 builder->fFSCode.appendf("\tfloat innerAlpha = %s.w == 0.0 ? 1.0 : s
moothstep(%s.w - 0.5, %s.w + 0.5, d);\n", fsName, fsName, fsName); | 467 builder->fsCodeAppendf("\tfloat innerAlpha = %s.w == 0.0 ? 1.0 : smo
othstep(%s.w - 0.5, %s.w + 0.5, d);\n", fsName, fsName, fsName); |
467 builder->fFSCode.append("\tedgeAlpha = outerAlpha * innerAlpha;\n"); | 468 builder->fsCodeAppend("\tedgeAlpha = outerAlpha * innerAlpha;\n"); |
468 break; | 469 break; |
469 case GrDrawState::kEllipse_EdgeType: | 470 case GrDrawState::kEllipse_EdgeType: |
470 builder->fFSCode.append("\tfloat edgeAlpha;\n"); | 471 builder->fsCodeAppend("\tfloat edgeAlpha;\n"); |
471 builder->fFSCode.appendf("\tvec2 offset = (%s.xy - %s.xy);\n", build
er->fragmentPosition(), fsName); | 472 builder->fsCodeAppendf("\tvec2 offset = (%s.xy - %s.xy);\n", builder
->fragmentPosition(), fsName); |
472 builder->fFSCode.appendf("\toffset.y *= %s.w;\n", fsName); | 473 builder->fsCodeAppendf("\toffset.y *= %s.w;\n", fsName); |
473 builder->fFSCode.append("\tfloat d = length(offset);\n"); | 474 builder->fsCodeAppend("\tfloat d = length(offset);\n"); |
474 builder->fFSCode.appendf("\tedgeAlpha = smoothstep(d - 0.5, d + 0.5,
%s.z);\n", fsName); | 475 builder->fsCodeAppendf("\tedgeAlpha = smoothstep(d - 0.5, d + 0.5, %
s.z);\n", fsName); |
475 break; | 476 break; |
476 default: | 477 default: |
477 GrCrash("Unknown Edge Type!"); | 478 GrCrash("Unknown Edge Type!"); |
478 break; | 479 break; |
479 } | 480 } |
480 if (fDesc.fDiscardIfOutsideEdge) { | 481 if (fDesc.fDiscardIfOutsideEdge) { |
481 builder->fFSCode.appendf("\tif (edgeAlpha <= 0.0) {\n\t\tdiscard;\n\
t}\n"); | 482 builder->fsCodeAppend("\tif (edgeAlpha <= 0.0) {\n\t\tdiscard;\n\t}\
n"); |
482 } | 483 } |
483 *coverageVar = "edgeAlpha"; | 484 *coverageVar = "edgeAlpha"; |
484 return true; | 485 return true; |
485 } else { | 486 } else { |
486 coverageVar->reset(); | 487 coverageVar->reset(); |
487 return false; | 488 return false; |
488 } | 489 } |
489 } | 490 } |
490 | 491 |
491 void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { | 492 void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { |
492 switch (fDesc.fColorInput) { | 493 switch (fDesc.fColorInput) { |
493 case GrGLProgram::Desc::kAttribute_ColorInput: { | 494 case GrGLProgram::Desc::kAttribute_ColorInput: { |
494 builder->fVSAttrs.push_back().set(kVec4f_GrSLType, | 495 builder->fVSAttrs.push_back().set(kVec4f_GrSLType, |
495 GrGLShaderVar::kAttribute_TypeModifier, | 496 GrGLShaderVar::kAttribute_TypeModifier, |
496 COL_ATTR_NAME); | 497 COL_ATTR_NAME); |
497 const char *vsName, *fsName; | 498 const char *vsName, *fsName; |
498 builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); | 499 builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); |
499 builder->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName); | 500 builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName); |
500 *inColor = fsName; | 501 *inColor = fsName; |
501 } break; | 502 } break; |
502 case GrGLProgram::Desc::kUniform_ColorInput: { | 503 case GrGLProgram::Desc::kUniform_ColorInput: { |
503 const char* name; | 504 const char* name; |
504 fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::k
Fragment_ShaderType, | 505 fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::k
Fragment_ShaderType, |
505 kVec4f_GrSLType, "Co
lor", &name); | 506 kVec4f_GrSLType, "Co
lor", &name); |
506 *inColor = name; | 507 *inColor = name; |
507 break; | 508 break; |
508 } | 509 } |
509 case GrGLProgram::Desc::kTransBlack_ColorInput: | 510 case GrGLProgram::Desc::kTransBlack_ColorInput: |
510 GrAssert(!"needComputedColor should be false."); | 511 GrAssert(!"needComputedColor should be false."); |
511 break; | 512 break; |
512 case GrGLProgram::Desc::kSolidWhite_ColorInput: | 513 case GrGLProgram::Desc::kSolidWhite_ColorInput: |
513 break; | 514 break; |
514 default: | 515 default: |
515 GrCrash("Unknown color type."); | 516 GrCrash("Unknown color type."); |
516 break; | 517 break; |
517 } | 518 } |
518 } | 519 } |
519 | 520 |
520 void GrGLProgram::genUniformCoverage(GrGLShaderBuilder* builder, SkString* inOut
Coverage) { | 521 void GrGLProgram::genUniformCoverage(GrGLShaderBuilder* builder, SkString* inOut
Coverage) { |
521 const char* covUniName; | 522 const char* covUniName; |
522 fUniformHandles.fCoverageUni = builder->addUniform(GrGLShaderBuilder::kFragm
ent_ShaderType, | 523 fUniformHandles.fCoverageUni = builder->addUniform(GrGLShaderBuilder::kFragm
ent_ShaderType, |
523 kVec4f_GrSLType, "Coverag
e", &covUniName); | 524 kVec4f_GrSLType, "Coverag
e", &covUniName); |
524 if (inOutCoverage->size()) { | 525 if (inOutCoverage->size()) { |
525 builder->fFSCode.appendf("\tvec4 uniCoverage = %s * %s;\n", | 526 builder->fsCodeAppendf("\tvec4 uniCoverage = %s * %s;\n", |
526 covUniName, inOutCoverage->c_str()); | 527 covUniName, inOutCoverage->c_str()); |
527 *inOutCoverage = "uniCoverage"; | 528 *inOutCoverage = "uniCoverage"; |
528 } else { | 529 } else { |
529 *inOutCoverage = covUniName; | 530 *inOutCoverage = covUniName; |
530 } | 531 } |
531 } | 532 } |
532 | 533 |
533 namespace { | 534 namespace { |
534 void gen_attribute_coverage(GrGLShaderBuilder* segments, | 535 void gen_attribute_coverage(GrGLShaderBuilder* builder, |
535 SkString* inOutCoverage) { | 536 SkString* inOutCoverage) { |
536 segments->fVSAttrs.push_back().set(kVec4f_GrSLType, | 537 builder->fVSAttrs.push_back().set(kVec4f_GrSLType, |
537 GrGLShaderVar::kAttribute_TypeModifier, | 538 GrGLShaderVar::kAttribute_TypeModifier, |
538 COV_ATTR_NAME); | 539 COV_ATTR_NAME); |
539 const char *vsName, *fsName; | 540 const char *vsName, *fsName; |
540 segments->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); | 541 builder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); |
541 segments->fVSCode.appendf("\t%s = " COV_ATTR_NAME ";\n", vsName); | 542 builder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName); |
542 if (inOutCoverage->size()) { | 543 if (inOutCoverage->size()) { |
543 segments->fFSCode.appendf("\tvec4 attrCoverage = %s * %s;\n", | 544 builder->fsCodeAppendf("\tvec4 attrCoverage = %s * %s;\n", fsName, inOut
Coverage->c_str()); |
544 fsName, inOutCoverage->c_str()); | |
545 *inOutCoverage = "attrCoverage"; | 545 *inOutCoverage = "attrCoverage"; |
546 } else { | 546 } else { |
547 *inOutCoverage = fsName; | 547 *inOutCoverage = fsName; |
548 } | 548 } |
549 } | 549 } |
550 } | 550 } |
551 | 551 |
552 void GrGLProgram::genGeometryShader(GrGLShaderBuilder* segments) const { | 552 void GrGLProgram::genGeometryShader(GrGLShaderBuilder* builder) const { |
553 #if GR_GL_EXPERIMENTAL_GS | 553 #if GR_GL_EXPERIMENTAL_GS |
| 554 // TODO: The builder should add all this glue code. |
554 if (fDesc.fExperimentalGS) { | 555 if (fDesc.fExperimentalGS) { |
555 GrAssert(fContext.info().glslGeneration() >= k150_GrGLSLGeneration); | 556 GrAssert(fContext.info().glslGeneration() >= k150_GrGLSLGeneration); |
556 segments->fGSHeader.append("layout(triangles) in;\n" | 557 builder->fGSHeader.append("layout(triangles) in;\n" |
557 "layout(triangle_strip, max_vertices = 6) out
;\n"); | 558 "layout(triangle_strip, max_vertices = 6) out
;\n"); |
558 segments->fGSCode.append("\tfor (int i = 0; i < 3; ++i) {\n" | 559 builder->gsCodeAppend("\tfor (int i = 0; i < 3; ++i) {\n" |
559 "\t\tgl_Position = gl_in[i].gl_Position;\n"); | 560 "\t\tgl_Position = gl_in[i].gl_Position;\n"); |
560 if (fDesc.fEmitsPointSize) { | 561 if (fDesc.fEmitsPointSize) { |
561 segments->fGSCode.append("\t\tgl_PointSize = 1.0;\n"); | 562 builder->gsCodeAppend("\t\tgl_PointSize = 1.0;\n"); |
562 } | 563 } |
563 GrAssert(segments->fGSInputs.count() == segments->fGSOutputs.count()); | 564 GrAssert(builder->fGSInputs.count() == builder->fGSOutputs.count()); |
564 int count = segments->fGSInputs.count(); | 565 int count = builder->fGSInputs.count(); |
565 for (int i = 0; i < count; ++i) { | 566 for (int i = 0; i < count; ++i) { |
566 segments->fGSCode.appendf("\t\t%s = %s[i];\n", | 567 builder->gsCodeAppendf("\t\t%s = %s[i];\n", |
567 segments->fGSOutputs[i].getName().c_str(), | 568 builder->fGSOutputs[i].getName().c_str(), |
568 segments->fGSInputs[i].getName().c_str()); | 569 builder->fGSInputs[i].getName().c_str()); |
569 } | 570 } |
570 segments->fGSCode.append("\t\tEmitVertex();\n" | 571 builder->gsCodeAppend("\t\tEmitVertex();\n" |
571 "\t}\n" | 572 "\t}\n" |
572 "\tEndPrimitive();\n"); | 573 "\tEndPrimitive();\n"); |
573 } | 574 } |
574 #endif | 575 #endif |
575 } | 576 } |
576 | 577 |
577 const char* GrGLProgram::adjustInColor(const SkString& inColor) const { | 578 const char* GrGLProgram::adjustInColor(const SkString& inColor) const { |
578 if (inColor.size()) { | 579 if (inColor.size()) { |
579 return inColor.c_str(); | 580 return inColor.c_str(); |
580 } else { | 581 } else { |
581 if (Desc::kSolidWhite_ColorInput == fDesc.fColorInput) { | 582 if (Desc::kSolidWhite_ColorInput == fDesc.fColorInput) { |
582 return GrGLSLOnesVecf(4); | 583 return GrGLSLOnesVecf(4); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 &colorOutput); | 752 &colorOutput); |
752 if (isColorDeclared) { | 753 if (isColorDeclared) { |
753 builder.fFSOutputs.push_back(colorOutput); | 754 builder.fFSOutputs.push_back(colorOutput); |
754 } | 755 } |
755 | 756 |
756 const char* viewMName; | 757 const char* viewMName; |
757 fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVert
ex_ShaderType, | 758 fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVert
ex_ShaderType, |
758 kMat33f_GrSLType, "ViewM
", &viewMName); | 759 kMat33f_GrSLType, "ViewM
", &viewMName); |
759 | 760 |
760 | 761 |
761 builder.fVSCode.appendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" | 762 builder.vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" |
762 "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", | 763 "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", |
763 viewMName, builder.positionAttribute().getName().c_s
tr()); | 764 viewMName, builder.positionAttribute().getName().c_str
()); |
764 | 765 |
765 // incoming color to current stage being processed. | 766 // incoming color to current stage being processed. |
766 SkString inColor; | 767 SkString inColor; |
767 | 768 |
768 if (needComputedColor) { | 769 if (needComputedColor) { |
769 this->genInputColor(&builder, &inColor); | 770 this->genInputColor(&builder, &inColor); |
770 } | 771 } |
771 | 772 |
772 // we output point size in the GS if present | 773 // we output point size in the GS if present |
773 if (fDesc.fEmitsPointSize && !builder.fUsesGS){ | 774 if (fDesc.fEmitsPointSize && !builder.fUsesGS){ |
774 builder.fVSCode.append("\tgl_PointSize = 1.0;\n"); | 775 builder.vsCodeAppend("\tgl_PointSize = 1.0;\n"); |
775 } | 776 } |
776 | 777 |
777 // add texture coordinates that are used to the list of vertex attr decls | 778 // add texture coordinates that are used to the list of vertex attr decls |
778 if (GrDrawState::AttributesBindExplicitTexCoords(attribBindings)) { | 779 if (GrDrawState::AttributesBindExplicitTexCoords(attribBindings)) { |
779 builder.fVSAttrs.push_back().set(kVec2f_GrSLType, | 780 builder.fVSAttrs.push_back().set(kVec2f_GrSLType, |
780 GrGLShaderVar::kAttribute_TypeModifier, | 781 GrGLShaderVar::kAttribute_TypeModifier, |
781 TEX_ATTR_NAME); | 782 TEX_ATTR_NAME); |
782 } | 783 } |
783 | 784 |
784 /////////////////////////////////////////////////////////////////////////// | 785 /////////////////////////////////////////////////////////////////////////// |
785 // compute the final color | 786 // compute the final color |
786 | 787 |
787 // if we have color stages string them together, feeding the output color | 788 // if we have color stages string them together, feeding the output color |
788 // of each to the next and generating code for each stage. | 789 // of each to the next and generating code for each stage. |
789 if (needComputedColor) { | 790 if (needComputedColor) { |
790 SkString outColor; | 791 SkString outColor; |
791 for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) { | 792 for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) { |
792 if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) { | 793 if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) { |
793 // create var to hold stage result | 794 // create var to hold stage result |
794 outColor = "color"; | 795 outColor = "color"; |
795 outColor.appendS32(s); | 796 outColor.appendS32(s); |
796 builder.fFSCode.appendf("\tvec4 %s;\n", outColor.c_str()); | 797 builder.fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); |
797 | 798 |
798 const char* inCoords; | 799 const char* inCoords; |
799 // figure out what our input coords are | 800 // figure out what our input coords are |
800 if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings, s)
) { | 801 if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings, s)
) { |
801 inCoords = builder.positionAttribute().c_str(); | 802 inCoords = builder.positionAttribute().c_str(); |
802 } else { | 803 } else { |
803 // must have input tex coordinates if stage is enabled. | 804 // must have input tex coordinates if stage is enabled. |
804 inCoords = TEX_ATTR_NAME; | 805 inCoords = TEX_ATTR_NAME; |
805 } | 806 } |
806 | 807 |
(...skipping 26 matching lines...) Expand all Loading... |
833 const char* colorFilterColorUniName = NULL; | 834 const char* colorFilterColorUniName = NULL; |
834 if (needColorFilterUniform) { | 835 if (needColorFilterUniform) { |
835 fUniformHandles.fColorFilterUni = builder.addUniform( | 836 fUniformHandles.fColorFilterUni = builder.addUniform( |
836 GrGLShaderBuilder::kFrag
ment_ShaderType, | 837 GrGLShaderBuilder::kFrag
ment_ShaderType, |
837 kVec4f_GrSLType, "Filter
Color", | 838 kVec4f_GrSLType, "Filter
Color", |
838 &colorFilterColorUniName
); | 839 &colorFilterColorUniName
); |
839 } | 840 } |
840 bool wroteFragColorZero = false; | 841 bool wroteFragColorZero = false; |
841 if (SkXfermode::kZero_Coeff == uniformCoeff && | 842 if (SkXfermode::kZero_Coeff == uniformCoeff && |
842 SkXfermode::kZero_Coeff == colorCoeff) { | 843 SkXfermode::kZero_Coeff == colorCoeff) { |
843 builder.fFSCode.appendf("\t%s = %s;\n", | 844 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(), GrG
LSLZerosVecf(4)); |
844 colorOutput.getName().c_str(), | |
845 GrGLSLZerosVecf(4)); | |
846 wroteFragColorZero = true; | 845 wroteFragColorZero = true; |
847 } else if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) { | 846 } else if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) { |
848 builder.fFSCode.append("\tvec4 filteredColor;\n"); | 847 builder.fsCodeAppend("\tvec4 filteredColor;\n"); |
849 const char* color = adjustInColor(inColor); | 848 const char* color = adjustInColor(inColor); |
850 add_color_filter(&builder.fFSCode, "filteredColor", uniformCoeff, | 849 add_color_filter(&builder, "filteredColor", uniformCoeff, |
851 colorCoeff, colorFilterColorUniName, color); | 850 colorCoeff, colorFilterColorUniName, color); |
852 inColor = "filteredColor"; | 851 inColor = "filteredColor"; |
853 } | 852 } |
854 | 853 |
855 /////////////////////////////////////////////////////////////////////////// | 854 /////////////////////////////////////////////////////////////////////////// |
856 // compute the partial coverage (coverage stages and edge aa) | 855 // compute the partial coverage (coverage stages and edge aa) |
857 | 856 |
858 SkString inCoverage; | 857 SkString inCoverage; |
859 bool coverageIsZero = Desc::kTransBlack_ColorInput == fDesc.fCoverageInput; | 858 bool coverageIsZero = Desc::kTransBlack_ColorInput == fDesc.fCoverageInput; |
860 // we don't need to compute coverage at all if we know the final shader | 859 // we don't need to compute coverage at all if we know the final shader |
861 // output will be zero and we don't have a dual src blend output. | 860 // output will be zero and we don't have a dual src blend output. |
(...skipping 18 matching lines...) Expand all Loading... |
880 GrCrash("Unexpected input coverage."); | 879 GrCrash("Unexpected input coverage."); |
881 } | 880 } |
882 | 881 |
883 SkString outCoverage; | 882 SkString outCoverage; |
884 const int& startStage = fDesc.fFirstCoverageStage; | 883 const int& startStage = fDesc.fFirstCoverageStage; |
885 for (int s = startStage; s < GrDrawState::kNumStages; ++s) { | 884 for (int s = startStage; s < GrDrawState::kNumStages; ++s) { |
886 if (fDesc.fEffectKeys[s]) { | 885 if (fDesc.fEffectKeys[s]) { |
887 // create var to hold stage output | 886 // create var to hold stage output |
888 outCoverage = "coverage"; | 887 outCoverage = "coverage"; |
889 outCoverage.appendS32(s); | 888 outCoverage.appendS32(s); |
890 builder.fFSCode.appendf("\tvec4 %s;\n", outCoverage.c_str())
; | 889 builder.fsCodeAppendf("\tvec4 %s;\n", outCoverage.c_str()); |
891 | 890 |
892 const char* inCoords; | 891 const char* inCoords; |
893 // figure out what our input coords are | 892 // figure out what our input coords are |
894 if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings
, s)) { | 893 if (!GrDrawState::StageBindsExplicitTexCoords(attribBindings
, s)) { |
895 inCoords = builder.positionAttribute().c_str(); | 894 inCoords = builder.positionAttribute().c_str(); |
896 } else { | 895 } else { |
897 // must have input tex coordinates if stage is | 896 // must have input tex coordinates if stage is |
898 // enabled. | 897 // enabled. |
899 inCoords = TEX_ATTR_NAME; | 898 inCoords = TEX_ATTR_NAME; |
900 } | 899 } |
901 | 900 |
902 // stages don't know how to deal with a scalar input. (Maybe
they should. We | 901 // stages don't know how to deal with a scalar input. (Maybe
they should. We |
903 // could pass a GrGLShaderVar) | 902 // could pass a GrGLShaderVar) |
904 if (inCoverageIsScalar) { | 903 if (inCoverageIsScalar) { |
905 builder.fFSCode.appendf("\tvec4 %s4 = vec4(%s);\n", | 904 builder.fsCodeAppendf("\tvec4 %s4 = vec4(%s);\n", |
906 inCoverage.c_str(), inCoverage.c
_str()); | 905 inCoverage.c_str(), inCoverage.c_s
tr()); |
907 inCoverage.append("4"); | 906 inCoverage.append("4"); |
908 } | 907 } |
909 builder.setCurrentStage(s); | 908 builder.setCurrentStage(s); |
910 fEffects[s] = builder.createAndEmitGLEffect( | 909 fEffects[s] = builder.createAndEmitGLEffect( |
911 *stages[s], | 910 *stages[s], |
912 fDesc.fEffectKeys[s], | 911 fDesc.fEffectKeys[s], |
913 inCoverage.size() ? inCovera
ge.c_str() : NULL, | 912 inCoverage.size() ? inCovera
ge.c_str() : NULL, |
914 outCoverage.c_str(), | 913 outCoverage.c_str(), |
915 inCoords, | 914 inCoords, |
916 &fUniformHandles.fSamplerUni
s[s]); | 915 &fUniformHandles.fSamplerUni
s[s]); |
(...skipping 15 matching lines...) Expand all Loading... |
932 outputIsZero = true; | 931 outputIsZero = true; |
933 } else { | 932 } else { |
934 if (Desc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput
) { | 933 if (Desc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput
) { |
935 coeff.printf("(1 - %s.a)", inColor.c_str()); | 934 coeff.printf("(1 - %s.a)", inColor.c_str()); |
936 } else { | 935 } else { |
937 coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str()); | 936 coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str()); |
938 } | 937 } |
939 } | 938 } |
940 } | 939 } |
941 if (outputIsZero) { | 940 if (outputIsZero) { |
942 builder.fFSCode.appendf("\t%s = %s;\n", | 941 builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(),
GrGLSLZerosVecf(4)); |
943 dual_source_output_name(), | |
944 GrGLSLZerosVecf(4)); | |
945 } else { | 942 } else { |
946 builder.fFSCode.appendf("\t%s =", dual_source_output_name()); | 943 SkString modulate; |
947 GrGLSLModulate4f(&builder.fFSCode, coeff.c_str(), inCoverage.c_s
tr()); | 944 GrGLSLModulate4f(&modulate, coeff.c_str(), inCoverage.c_str()); |
948 builder.fFSCode.append(";\n"); | 945 builder.fsCodeAppendf("\t%s = %s;\n", dual_source_output_name(),
modulate.c_str()); |
949 } | 946 } |
950 dualSourceOutputWritten = true; | 947 dualSourceOutputWritten = true; |
951 } | 948 } |
952 } | 949 } |
953 | 950 |
954 /////////////////////////////////////////////////////////////////////////// | 951 /////////////////////////////////////////////////////////////////////////// |
955 // combine color and coverage as frag color | 952 // combine color and coverage as frag color |
956 | 953 |
957 if (!wroteFragColorZero) { | 954 if (!wroteFragColorZero) { |
958 if (coverageIsZero) { | 955 if (coverageIsZero) { |
959 builder.fFSCode.appendf("\t%s = %s;\n", | 956 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(),
GrGLSLZerosVecf(4)); |
960 colorOutput.getName().c_str(), | |
961 GrGLSLZerosVecf(4)); | |
962 } else { | 957 } else { |
963 builder.fFSCode.appendf("\t%s = ", colorOutput.getName().c_str()); | 958 SkString modulate; |
964 GrGLSLModulate4f(&builder.fFSCode, inColor.c_str(), inCoverage.c_str
()); | 959 GrGLSLModulate4f(&modulate, inColor.c_str(), inCoverage.c_str()); |
965 builder.fFSCode.append(";\n"); | 960 builder.fsCodeAppendf("\t%s = %s;\n", colorOutput.getName().c_str(),
modulate.c_str()); |
966 } | 961 } |
967 } | 962 } |
968 | 963 |
969 /////////////////////////////////////////////////////////////////////////// | 964 /////////////////////////////////////////////////////////////////////////// |
970 // insert GS | 965 // insert GS |
971 #if GR_DEBUG | 966 #if GR_DEBUG |
972 this->genGeometryShader(&builder); | 967 this->genGeometryShader(&builder); |
973 #endif | 968 #endif |
974 | 969 |
975 /////////////////////////////////////////////////////////////////////////// | 970 /////////////////////////////////////////////////////////////////////////// |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 SkScalarToFloat(m[SkMatrix::kMTransX]), | 1213 SkScalarToFloat(m[SkMatrix::kMTransX]), |
1219 SkScalarToFloat(m[SkMatrix::kMTransY]), | 1214 SkScalarToFloat(m[SkMatrix::kMTransY]), |
1220 SkScalarToFloat(m[SkMatrix::kMPersp2]) | 1215 SkScalarToFloat(m[SkMatrix::kMPersp2]) |
1221 }; | 1216 }; |
1222 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); | 1217 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); |
1223 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 1218 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
1224 fMatrixState.fRenderTargetSize = size; | 1219 fMatrixState.fRenderTargetSize = size; |
1225 fMatrixState.fRenderTargetOrigin = rt->origin(); | 1220 fMatrixState.fRenderTargetOrigin = rt->origin(); |
1226 } | 1221 } |
1227 } | 1222 } |
OLD | NEW |