| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "SkTwoPointRadialGradient.h" | 9 #include "SkTwoPointRadialGradient.h" |
| 10 | 10 |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 // For brevity | 377 // For brevity |
| 378 typedef GrGLUniformManager::UniformHandle UniformHandle; | 378 typedef GrGLUniformManager::UniformHandle UniformHandle; |
| 379 | 379 |
| 380 class GrGLRadial2Gradient : public GrGLGradientEffect { | 380 class GrGLRadial2Gradient : public GrGLGradientEffect { |
| 381 | 381 |
| 382 public: | 382 public: |
| 383 | 383 |
| 384 GrGLRadial2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffec
t&); | 384 GrGLRadial2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffec
t&); |
| 385 virtual ~GrGLRadial2Gradient() { } | 385 virtual ~GrGLRadial2Gradient() { } |
| 386 | 386 |
| 387 virtual void emitCode(GrGLFullShaderBuilder*, |
| 388 const GrDrawEffect&, |
| 389 EffectKey, |
| 390 const char* outputColor, |
| 391 const char* inputColor, |
| 392 const TransformedCoordsArray&, |
| 393 const TextureSamplerArray&) SK_OVERRIDE; |
| 394 |
| 387 virtual void emitCode(GrGLShaderBuilder*, | 395 virtual void emitCode(GrGLShaderBuilder*, |
| 388 const GrDrawEffect&, | 396 const GrDrawEffect&, |
| 389 EffectKey, | 397 EffectKey, |
| 390 const char* outputColor, | 398 const char* outputColor, |
| 391 const char* inputColor, | 399 const char* inputColor, |
| 392 const TransformedCoordsArray&, | 400 const TransformedCoordsArray&, |
| 393 const TextureSamplerArray&) SK_OVERRIDE; | 401 const TextureSamplerArray&) SK_OVERRIDE; |
| 402 |
| 403 void emitUniforms(GrGLShaderBuilder* builder, EffectKey key); |
| 404 |
| 405 void emitFragmentCode(GrGLShaderBuilder*, |
| 406 EffectKey, |
| 407 const char* outputColor, |
| 408 const char* inputColor, |
| 409 const TransformedCoordsArray&, |
| 410 const TextureSamplerArray&); |
| 411 |
| 394 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; | 412 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; |
| 395 | 413 |
| 396 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); | 414 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); |
| 397 | 415 |
| 398 protected: | 416 protected: |
| 399 | 417 |
| 400 UniformHandle fVSParamUni; | 418 UniformHandle fVSParamUni; |
| 401 UniformHandle fFSParamUni; | 419 UniformHandle fFSParamUni; |
| 402 | 420 |
| 403 const char* fVSVaryingName; | 421 const char* fVSVaryingName; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 , fVSVaryingName(NULL) | 537 , fVSVaryingName(NULL) |
| 520 , fFSVaryingName(NULL) | 538 , fFSVaryingName(NULL) |
| 521 , fCachedCenter(SK_ScalarMax) | 539 , fCachedCenter(SK_ScalarMax) |
| 522 , fCachedRadius(-SK_ScalarMax) | 540 , fCachedRadius(-SK_ScalarMax) |
| 523 , fCachedPosRoot(0) { | 541 , fCachedPosRoot(0) { |
| 524 | 542 |
| 525 const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>(); | 543 const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>(); |
| 526 fIsDegenerate = data.isDegenerate(); | 544 fIsDegenerate = data.isDegenerate(); |
| 527 } | 545 } |
| 528 | 546 |
| 529 void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder, | 547 void GrGLRadial2Gradient::emitCode(GrGLFullShaderBuilder* builder, |
| 530 const GrDrawEffect& drawEffect, | 548 const GrDrawEffect& drawEffect, |
| 531 EffectKey key, | 549 EffectKey key, |
| 532 const char* outputColor, | 550 const char* outputColor, |
| 533 const char* inputColor, | 551 const char* inputColor, |
| 534 const TransformedCoordsArray& coords, | 552 const TransformedCoordsArray& coords, |
| 535 const TextureSamplerArray& samplers) { | 553 const TextureSamplerArray& samplers) { |
| 554 this->emitUniforms(builder, key); |
| 536 | 555 |
| 556 if (kVec2f_GrSLType == coords[0].type()) { |
| 557 // For radial gradients without perspective we can pass the linear |
| 558 // part of the quadratic as a varying. |
| 559 SkString p2; |
| 560 SkString p3; |
| 561 builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); |
| 562 builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); |
| 563 |
| 564 builder->addVarying(kFloat_GrSLType, "Radial2BCoeff", &fVSVaryingName, &
fFSVaryingName); |
| 565 |
| 566 // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3]) |
| 567 builder->vsCodeAppendf("\t%s = 2.0 *(%s * %s.x - %s);\n", |
| 568 fVSVaryingName, p2.c_str(), |
| 569 coords[0].getVSName().c_str(), p3.c_str()); |
| 570 } |
| 571 |
| 572 this->emitFragmentCode(builder, key, outputColor, inputColor, coords, sample
rs); |
| 573 } |
| 574 |
| 575 void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder, |
| 576 const GrDrawEffect&, |
| 577 EffectKey key, |
| 578 const char* outputColor, |
| 579 const char* inputColor, |
| 580 const TransformedCoordsArray& coords, |
| 581 const TextureSamplerArray& samplers) { |
| 537 this->emitUniforms(builder, key); | 582 this->emitUniforms(builder, key); |
| 583 this->emitFragmentCode(builder, key, outputColor, inputColor, coords, sample
rs); |
| 584 } |
| 585 |
| 586 void GrGLRadial2Gradient::emitUniforms(GrGLShaderBuilder* builder, EffectKey key
) { |
| 587 this->INHERITED::emitUniforms(builder, key); |
| 538 // 2 copies of uniform array, 1 for each of vertex & fragment shader, | 588 // 2 copies of uniform array, 1 for each of vertex & fragment shader, |
| 539 // to work around Xoom bug. Doesn't seem to cause performance decrease | 589 // to work around Xoom bug. Doesn't seem to cause performance decrease |
| 540 // in test apps, but need to keep an eye on it. | 590 // in test apps, but need to keep an eye on it. |
| 541 fVSParamUni = builder->addUniformArray(GrGLShaderBuilder::kVertex_Visibility
, | 591 fVSParamUni = builder->addUniformArray(GrGLShaderBuilder::kVertex_Visibility
, |
| 542 kFloat_GrSLType, "Radial2VSParams", 6
); | 592 kFloat_GrSLType, "Radial2VSParams", 6
); |
| 543 fFSParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibili
ty, | 593 fFSParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibili
ty, |
| 544 kFloat_GrSLType, "Radial2FSParams", 6
); | 594 kFloat_GrSLType, "Radial2FSParams", 6
); |
| 595 } |
| 545 | 596 |
| 546 // For radial gradients without perspective we can pass the linear | 597 void GrGLRadial2Gradient::emitFragmentCode(GrGLShaderBuilder* builder, |
| 547 // part of the quadratic as a varying. | 598 EffectKey key, |
| 548 GrGLShaderBuilder::VertexBuilder* vertexBuilder = | 599 const char* outputColor, |
| 549 (kVec2f_GrSLType == coords[0].type()) ? builder->getVertexBuilder() : NU
LL; | 600 const char* inputColor, |
| 550 if (NULL != vertexBuilder) { | 601 const TransformedCoordsArray& coords, |
| 551 vertexBuilder->addVarying(kFloat_GrSLType, "Radial2BCoeff", | 602 const TextureSamplerArray& samplers)
{ |
| 552 &fVSVaryingName, &fFSVaryingName); | 603 SkString coords2D = builder->ensureFSCoords2D(coords, 0); |
| 604 SkString cName("c"); |
| 605 SkString ac4Name("ac4"); |
| 606 SkString rootName("root"); |
| 607 SkString t; |
| 608 SkString p0; |
| 609 SkString p1; |
| 610 SkString p2; |
| 611 SkString p3; |
| 612 SkString p4; |
| 613 SkString p5; |
| 614 builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0); |
| 615 builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1); |
| 616 builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2); |
| 617 builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3); |
| 618 builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4); |
| 619 builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5); |
| 620 |
| 621 // If we we're able to interpolate the linear component, |
| 622 // bVar is the varying; otherwise compute it |
| 623 SkString bVar; |
| 624 if (NULL != fFSVaryingName) { |
| 625 bVar = fFSVaryingName; |
| 626 } else { |
| 627 bVar = "b"; |
| 628 builder->fsCodeAppendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n", |
| 629 bVar.c_str(), p2.c_str(), coords2D.c_str(), p3.c_
str()); |
| 553 } | 630 } |
| 554 | 631 |
| 555 // VS | 632 // c = (x^2)+(y^2) - params[4] |
| 556 { | 633 builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n", |
| 557 SkString p2; | 634 cName.c_str(), |
| 558 SkString p3; | 635 coords2D.c_str(), |
| 559 builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); | 636 coords2D.c_str(), |
| 560 builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); | 637 p4.c_str()); |
| 561 | 638 |
| 562 // For radial gradients without perspective we can pass the linear | 639 // If we aren't degenerate, emit some extra code, and accept a slightly |
| 563 // part of the quadratic as a varying. | 640 // more complex coord. |
| 564 if (NULL != vertexBuilder) { | 641 if (!fIsDegenerate) { |
| 565 // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3]) | 642 |
| 566 vertexBuilder->vsCodeAppendf("\t%s = 2.0 *(%s * %s.x - %s);\n", | 643 // ac4 = 4.0 * params[0] * c |
| 567 fVSVaryingName, p2.c_str(), | 644 builder->fsCodeAppendf("\tfloat %s = %s * 4.0 * %s;\n", |
| 568 coords[0].getVSName().c_str(), p3.c_s
tr()); | 645 ac4Name.c_str(), p0.c_str(), |
| 569 } | 646 cName.c_str()); |
| 647 |
| 648 // root = sqrt(b^2-4ac) |
| 649 // (abs to avoid exception due to fp precision) |
| 650 builder->fsCodeAppendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n", |
| 651 rootName.c_str(), bVar.c_str(), bVar.c_str(), |
| 652 ac4Name.c_str()); |
| 653 |
| 654 // t is: (-b + params[5] * sqrt(b^2-4ac)) * params[1] |
| 655 t.printf("(-%s + %s * %s) * %s", bVar.c_str(), p5.c_str(), |
| 656 rootName.c_str(), p1.c_str()); |
| 657 } else { |
| 658 // t is: -c/b |
| 659 t.printf("-%s / %s", cName.c_str(), bVar.c_str()); |
| 570 } | 660 } |
| 571 | 661 |
| 572 // FS | 662 this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers); |
| 573 { | |
| 574 SkString coords2D = builder->ensureFSCoords2D(coords, 0); | |
| 575 SkString cName("c"); | |
| 576 SkString ac4Name("ac4"); | |
| 577 SkString rootName("root"); | |
| 578 SkString t; | |
| 579 SkString p0; | |
| 580 SkString p1; | |
| 581 SkString p2; | |
| 582 SkString p3; | |
| 583 SkString p4; | |
| 584 SkString p5; | |
| 585 builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0); | |
| 586 builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1); | |
| 587 builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2); | |
| 588 builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3); | |
| 589 builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4); | |
| 590 builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5); | |
| 591 | |
| 592 // If we we're able to interpolate the linear component, | |
| 593 // bVar is the varying; otherwise compute it | |
| 594 SkString bVar; | |
| 595 if (NULL != vertexBuilder) { | |
| 596 bVar = fFSVaryingName; | |
| 597 } else { | |
| 598 bVar = "b"; | |
| 599 builder->fsCodeAppendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n", | |
| 600 bVar.c_str(), p2.c_str(), coords2D.c_str(), p
3.c_str()); | |
| 601 } | |
| 602 | |
| 603 // c = (x^2)+(y^2) - params[4] | |
| 604 builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n", | |
| 605 cName.c_str(), | |
| 606 coords2D.c_str(), | |
| 607 coords2D.c_str(), | |
| 608 p4.c_str()); | |
| 609 | |
| 610 // If we aren't degenerate, emit some extra code, and accept a slightly | |
| 611 // more complex coord. | |
| 612 if (!fIsDegenerate) { | |
| 613 | |
| 614 // ac4 = 4.0 * params[0] * c | |
| 615 builder->fsCodeAppendf("\tfloat %s = %s * 4.0 * %s;\n", | |
| 616 ac4Name.c_str(), p0.c_str(), | |
| 617 cName.c_str()); | |
| 618 | |
| 619 // root = sqrt(b^2-4ac) | |
| 620 // (abs to avoid exception due to fp precision) | |
| 621 builder->fsCodeAppendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n", | |
| 622 rootName.c_str(), bVar.c_str(), bVar.c_str(), | |
| 623 ac4Name.c_str()); | |
| 624 | |
| 625 // t is: (-b + params[5] * sqrt(b^2-4ac)) * params[1] | |
| 626 t.printf("(-%s + %s * %s) * %s", bVar.c_str(), p5.c_str(), | |
| 627 rootName.c_str(), p1.c_str()); | |
| 628 } else { | |
| 629 // t is: -c/b | |
| 630 t.printf("-%s / %s", cName.c_str(), bVar.c_str()); | |
| 631 } | |
| 632 | |
| 633 this->emitColor(builder, t.c_str(), key, outputColor, inputColor, sample
rs); | |
| 634 } | |
| 635 } | 663 } |
| 636 | 664 |
| 637 void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman, | 665 void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman, |
| 638 const GrDrawEffect& drawEffect) { | 666 const GrDrawEffect& drawEffect) { |
| 639 INHERITED::setData(uman, drawEffect); | 667 INHERITED::setData(uman, drawEffect); |
| 640 const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>(); | 668 const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>(); |
| 641 SkASSERT(data.isDegenerate() == fIsDegenerate); | 669 SkASSERT(data.isDegenerate() == fIsDegenerate); |
| 642 SkScalar centerX1 = data.center(); | 670 SkScalar centerX1 = data.center(); |
| 643 SkScalar radius0 = data.radius(); | 671 SkScalar radius0 = data.radius(); |
| 644 if (fCachedCenter != centerX1 || | 672 if (fCachedCenter != centerX1 || |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 } | 734 } |
| 707 | 735 |
| 708 #else | 736 #else |
| 709 | 737 |
| 710 GrEffectRef* SkTwoPointRadialGradient::asNewEffect(GrContext*, const SkPaint&) c
onst { | 738 GrEffectRef* SkTwoPointRadialGradient::asNewEffect(GrContext*, const SkPaint&) c
onst { |
| 711 SkDEBUGFAIL("Should not call in GPU-less build"); | 739 SkDEBUGFAIL("Should not call in GPU-less build"); |
| 712 return NULL; | 740 return NULL; |
| 713 } | 741 } |
| 714 | 742 |
| 715 #endif | 743 #endif |
| OLD | NEW |