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 "SkTwoPointConicalGradient.h" | 9 #include "SkTwoPointConicalGradient.h" |
10 | 10 |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 | 506 |
507 // For radial gradients without perspective we can pass the linear | 507 // For radial gradients without perspective we can pass the linear |
508 // part of the quadratic as a varying. | 508 // part of the quadratic as a varying. |
509 if (kVec2f_GrSLType == coordsVaryingType) { | 509 if (kVec2f_GrSLType == coordsVaryingType) { |
510 builder->addVarying(kFloat_GrSLType, "Conical2BCoeff", | 510 builder->addVarying(kFloat_GrSLType, "Conical2BCoeff", |
511 &fVSVaryingName, &fFSVaryingName); | 511 &fVSVaryingName, &fFSVaryingName); |
512 } | 512 } |
513 | 513 |
514 // VS | 514 // VS |
515 { | 515 { |
516 SkString* code = &builder->fVSCode; | |
517 SkString p2; // distance between centers | 516 SkString p2; // distance between centers |
518 SkString p3; // start radius | 517 SkString p3; // start radius |
519 SkString p5; // difference in radii (r1 - r0) | 518 SkString p5; // difference in radii (r1 - r0) |
520 builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); | 519 builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); |
521 builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); | 520 builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); |
522 builder->getUniformVariable(fVSParamUni).appendArrayAccess(5, &p5); | 521 builder->getUniformVariable(fVSParamUni).appendArrayAccess(5, &p5); |
523 | 522 |
524 // For radial gradients without perspective we can pass the linear | 523 // For radial gradients without perspective we can pass the linear |
525 // part of the quadratic as a varying. | 524 // part of the quadratic as a varying. |
526 if (kVec2f_GrSLType == coordsVaryingType) { | 525 if (kVec2f_GrSLType == coordsVaryingType) { |
527 // r2Var = -2 * (r2Parm[2] * varCoord.x - r2Param[3] * r2Param[5]) | 526 // r2Var = -2 * (r2Parm[2] * varCoord.x - r2Param[3] * r2Param[5]) |
528 code->appendf("\t%s = -2.0 * (%s * %s.x + %s * %s);\n", | 527 builder->vsCodeAppendf("\t%s = -2.0 * (%s * %s.x + %s * %s);\n", |
529 fVSVaryingName, p2.c_str(), | 528 fVSVaryingName, p2.c_str(), |
530 vsCoordsVarying, p3.c_str(), p5.c_str()); | 529 vsCoordsVarying, p3.c_str(), p5.c_str()); |
531 } | 530 } |
532 } | 531 } |
533 | 532 |
534 // FS | 533 // FS |
535 { | 534 { |
536 SkString* code = &builder->fFSCode; | |
537 | 535 |
538 SkString cName("c"); | 536 SkString cName("c"); |
539 SkString ac4Name("ac4"); | 537 SkString ac4Name("ac4"); |
540 SkString dName("d"); | 538 SkString dName("d"); |
541 SkString qName("q"); | 539 SkString qName("q"); |
542 SkString r0Name("r0"); | 540 SkString r0Name("r0"); |
543 SkString r1Name("r1"); | 541 SkString r1Name("r1"); |
544 SkString tName("t"); | 542 SkString tName("t"); |
545 SkString p0; // 4a | 543 SkString p0; // 4a |
546 SkString p1; // 1/a | 544 SkString p1; // 1/a |
547 SkString p2; // distance between centers | 545 SkString p2; // distance between centers |
548 SkString p3; // start radius | 546 SkString p3; // start radius |
549 SkString p4; // start radius squared | 547 SkString p4; // start radius squared |
550 SkString p5; // difference in radii (r1 - r0) | 548 SkString p5; // difference in radii (r1 - r0) |
551 | 549 |
552 builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0); | 550 builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0); |
553 builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1); | 551 builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1); |
554 builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2); | 552 builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2); |
555 builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3); | 553 builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3); |
556 builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4); | 554 builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4); |
557 builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5); | 555 builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5); |
558 | 556 |
559 // If we we're able to interpolate the linear component, | 557 // If we we're able to interpolate the linear component, |
560 // bVar is the varying; otherwise compute it | 558 // bVar is the varying; otherwise compute it |
561 SkString bVar; | 559 SkString bVar; |
562 if (kVec2f_GrSLType == coordsVaryingType) { | 560 if (kVec2f_GrSLType == coordsVaryingType) { |
563 bVar = fFSVaryingName; | 561 bVar = fFSVaryingName; |
564 } else { | 562 } else { |
565 bVar = "b"; | 563 bVar = "b"; |
566 code->appendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n", | 564 builder->fsCodeAppendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n
", |
567 bVar.c_str(), p2.c_str(), fsCoords, | 565 bVar.c_str(), p2.c_str(), fsCoords, |
568 p3.c_str(), p5.c_str()); | 566 p3.c_str(), p5.c_str()); |
569 } | 567 } |
570 | 568 |
571 // output will default to transparent black (we simply won't write anyth
ing | 569 // output will default to transparent black (we simply won't write anyth
ing |
572 // else to it if invalid, instead of discarding or returning prematurely
) | 570 // else to it if invalid, instead of discarding or returning prematurely
) |
573 code->appendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor); | 571 builder->fsCodeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor); |
574 | 572 |
575 // c = (x^2)+(y^2) - params[4] | 573 // c = (x^2)+(y^2) - params[4] |
576 code->appendf("\tfloat %s = dot(%s, %s) - %s;\n", cName.c_str(), | 574 builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n", cName.c_str()
, |
577 fsCoords, fsCoords, | 575 fsCoords, fsCoords, |
578 p4.c_str()); | 576 p4.c_str()); |
579 | 577 |
580 // Non-degenerate case (quadratic) | 578 // Non-degenerate case (quadratic) |
581 if (!fIsDegenerate) { | 579 if (!fIsDegenerate) { |
582 | 580 |
583 // ac4 = params[0] * c | 581 // ac4 = params[0] * c |
584 code->appendf("\tfloat %s = %s * %s;\n", ac4Name.c_str(), p0.c_str()
, | 582 builder->fsCodeAppendf("\tfloat %s = %s * %s;\n", ac4Name.c_str(), p
0.c_str(), |
585 cName.c_str()); | 583 cName.c_str()); |
586 | 584 |
587 // d = b^2 - ac4 | 585 // d = b^2 - ac4 |
588 code->appendf("\tfloat %s = %s * %s - %s;\n", dName.c_str(), | 586 builder->fsCodeAppendf("\tfloat %s = %s * %s - %s;\n", dName.c_str()
, |
589 bVar.c_str(), bVar.c_str(), ac4Name.c_str()); | 587 bVar.c_str(), bVar.c_str(), ac4Name.c_str()); |
590 | 588 |
591 // only proceed if discriminant is >= 0 | 589 // only proceed if discriminant is >= 0 |
592 code->appendf("\tif (%s >= 0.0) {\n", dName.c_str()); | 590 builder->fsCodeAppendf("\tif (%s >= 0.0) {\n", dName.c_str()); |
593 | 591 |
594 // intermediate value we'll use to compute the roots | 592 // intermediate value we'll use to compute the roots |
595 // q = -0.5 * (b +/- sqrt(d)) | 593 // q = -0.5 * (b +/- sqrt(d)) |
596 code->appendf("\t\tfloat %s = -0.5 * (%s + (%s < 0.0 ? -1.0 : 1.0)" | 594 builder->fsCodeAppendf("\t\tfloat %s = -0.5 * (%s + (%s < 0.0 ? -1.0
: 1.0)" |
597 " * sqrt(%s));\n", qName.c_str(), bVar.c_str(), | 595 " * sqrt(%s));\n", qName.c_str(), bVar.c_str(
), |
598 bVar.c_str(), dName.c_str()); | 596 bVar.c_str(), dName.c_str()); |
599 | 597 |
600 // compute both roots | 598 // compute both roots |
601 // r0 = q * params[1] | 599 // r0 = q * params[1] |
602 code->appendf("\t\tfloat %s = %s * %s;\n", r0Name.c_str(), | 600 builder->fsCodeAppendf("\t\tfloat %s = %s * %s;\n", r0Name.c_str(), |
603 qName.c_str(), p1.c_str()); | 601 qName.c_str(), p1.c_str()); |
604 // r1 = c / q | 602 // r1 = c / q |
605 code->appendf("\t\tfloat %s = %s / %s;\n", r1Name.c_str(), | 603 builder->fsCodeAppendf("\t\tfloat %s = %s / %s;\n", r1Name.c_str(), |
606 cName.c_str(), qName.c_str()); | 604 cName.c_str(), qName.c_str()); |
607 | 605 |
608 // Note: If there are two roots that both generate radius(t) > 0, th
e | 606 // Note: If there are two roots that both generate radius(t) > 0, th
e |
609 // Canvas spec says to choose the larger t. | 607 // Canvas spec says to choose the larger t. |
610 | 608 |
611 // so we'll look at the larger one first: | 609 // so we'll look at the larger one first: |
612 code->appendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str(), | 610 builder->fsCodeAppendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str(
), |
613 r0Name.c_str(), r1Name.c_str()); | 611 r0Name.c_str(), r1Name.c_str()); |
614 | 612 |
615 // if r(t) > 0, then we're done; t will be our x coordinate | 613 // if r(t) > 0, then we're done; t will be our x coordinate |
616 code->appendf("\t\tif (%s * %s + %s > 0.0) {\n", tName.c_str(), | 614 builder->fsCodeAppendf("\t\tif (%s * %s + %s > 0.0) {\n", tName.c_st
r(), |
617 p5.c_str(), p3.c_str()); | 615 p5.c_str(), p3.c_str()); |
618 | 616 |
619 code->appendf("\t\t"); | 617 builder->fsCodeAppend("\t\t"); |
620 this->emitColorLookup(builder, tName.c_str(), outputColor, inputColo
r, samplers[0]); | 618 this->emitColorLookup(builder, tName.c_str(), outputColor, inputColo
r, samplers[0]); |
621 | 619 |
622 // otherwise, if r(t) for the larger root was <= 0, try the other ro
ot | 620 // otherwise, if r(t) for the larger root was <= 0, try the other ro
ot |
623 code->appendf("\t\t} else {\n"); | 621 builder->fsCodeAppend("\t\t} else {\n"); |
624 code->appendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(), | 622 builder->fsCodeAppendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(), |
625 r0Name.c_str(), r1Name.c_str()); | 623 r0Name.c_str(), r1Name.c_str()); |
626 | 624 |
627 // if r(t) > 0 for the smaller root, then t will be our x coordinate | 625 // if r(t) > 0 for the smaller root, then t will be our x coordinate |
628 code->appendf("\t\t\tif (%s * %s + %s > 0.0) {\n", | 626 builder->fsCodeAppendf("\t\t\tif (%s * %s + %s > 0.0) {\n", |
629 tName.c_str(), p5.c_str(), p3.c_str()); | 627 tName.c_str(), p5.c_str(), p3.c_str()); |
630 | 628 |
631 code->appendf("\t\t\t"); | 629 builder->fsCodeAppend("\t\t\t"); |
632 this->emitColorLookup(builder, tName.c_str(), outputColor, inputColo
r, samplers[0]); | 630 this->emitColorLookup(builder, tName.c_str(), outputColor, inputColo
r, samplers[0]); |
633 | 631 |
634 // end if (r(t) > 0) for smaller root | 632 // end if (r(t) > 0) for smaller root |
635 code->appendf("\t\t\t}\n"); | 633 builder->fsCodeAppend("\t\t\t}\n"); |
636 // end if (r(t) > 0), else, for larger root | 634 // end if (r(t) > 0), else, for larger root |
637 code->appendf("\t\t}\n"); | 635 builder->fsCodeAppend("\t\t}\n"); |
638 // end if (discriminant >= 0) | 636 // end if (discriminant >= 0) |
639 code->appendf("\t}\n"); | 637 builder->fsCodeAppend("\t}\n"); |
640 } else { | 638 } else { |
641 | 639 |
642 // linear case: t = -c/b | 640 // linear case: t = -c/b |
643 code->appendf("\tfloat %s = -(%s / %s);\n", tName.c_str(), | 641 builder->fsCodeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(), |
644 cName.c_str(), bVar.c_str()); | 642 cName.c_str(), bVar.c_str()); |
645 | 643 |
646 // if r(t) > 0, then t will be the x coordinate | 644 // if r(t) > 0, then t will be the x coordinate |
647 code->appendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(), | 645 builder->fsCodeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(
), |
648 p5.c_str(), p3.c_str()); | 646 p5.c_str(), p3.c_str()); |
649 code->appendf("\t"); | 647 builder->fsCodeAppend("\t"); |
650 this->emitColorLookup(builder, tName.c_str(), outputColor, inputColo
r, samplers[0]); | 648 this->emitColorLookup(builder, tName.c_str(), outputColor, inputColo
r, samplers[0]); |
651 code->appendf("\t}\n"); | 649 builder->fsCodeAppend("\t}\n"); |
652 } | 650 } |
653 } | 651 } |
654 } | 652 } |
655 | 653 |
656 void GrGLConical2Gradient::setData(const GrGLUniformManager& uman, const GrEffec
tStage& stage) { | 654 void GrGLConical2Gradient::setData(const GrGLUniformManager& uman, const GrEffec
tStage& stage) { |
657 INHERITED::setData(uman, stage); | 655 INHERITED::setData(uman, stage); |
658 const GrConical2Gradient& data = GetEffectFromStage<GrConical2Gradient>(stag
e); | 656 const GrConical2Gradient& data = GetEffectFromStage<GrConical2Gradient>(stag
e); |
659 GrAssert(data.isDegenerate() == fIsDegenerate); | 657 GrAssert(data.isDegenerate() == fIsDegenerate); |
660 SkScalar centerX1 = data.center(); | 658 SkScalar centerX1 = data.center(); |
661 SkScalar radius0 = data.radius(); | 659 SkScalar radius0 = data.radius(); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 str->appendScalar(fCenter2.fY); | 751 str->appendScalar(fCenter2.fY); |
754 str->append(") radius2: "); | 752 str->append(") radius2: "); |
755 str->appendScalar(fRadius2); | 753 str->appendScalar(fRadius2); |
756 str->append(" "); | 754 str->append(" "); |
757 | 755 |
758 this->INHERITED::toString(str); | 756 this->INHERITED::toString(str); |
759 | 757 |
760 str->append(")"); | 758 str->append(")"); |
761 } | 759 } |
762 #endif | 760 #endif |
OLD | NEW |