| 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 |