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 |