| 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 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 buffer.writeScalar(fRadius1); | 327 buffer.writeScalar(fRadius1); |
| 328 buffer.writeScalar(fRadius2); | 328 buffer.writeScalar(fRadius2); |
| 329 } | 329 } |
| 330 | 330 |
| 331 ///////////////////////////////////////////////////////////////////// | 331 ///////////////////////////////////////////////////////////////////// |
| 332 | 332 |
| 333 #if SK_SUPPORT_GPU | 333 #if SK_SUPPORT_GPU |
| 334 | 334 |
| 335 #include "GrTBackendEffectFactory.h" | 335 #include "GrTBackendEffectFactory.h" |
| 336 | 336 |
| 337 // For brevity | |
| 338 typedef GrGLUniformManager::UniformHandle UniformHandle; | |
| 339 static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidU
niformHandle; | |
| 340 | |
| 341 class GrGLConical2Gradient : public GrGLGradientEffect { | 337 class GrGLConical2Gradient : public GrGLGradientEffect { |
| 342 public: | 338 public: |
| 343 | 339 |
| 344 GrGLConical2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffe
ct&); | 340 GrGLConical2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffe
ct&); |
| 345 virtual ~GrGLConical2Gradient() { } | 341 virtual ~GrGLConical2Gradient() { } |
| 346 | 342 |
| 347 virtual void emitCode(GrGLShaderBuilder*, | 343 virtual void emitCode(GrGLShaderBuilder*, |
| 348 const GrDrawEffect&, | 344 const GrDrawEffect&, |
| 349 EffectKey, | 345 EffectKey, |
| 350 const char* outputColor, | 346 const char* outputColor, |
| 351 const char* inputColor, | 347 const char* inputColor, |
| 352 const TextureSamplerArray&) SK_OVERRIDE; | 348 const TextureSamplerArray&) SK_OVERRIDE; |
| 353 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; | 349 virtual void setData(const GrGLContext&, const GrDrawEffect&) SK_OVERRIDE; |
| 354 | 350 |
| 355 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); | 351 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); |
| 356 | 352 |
| 357 protected: | 353 protected: |
| 358 | 354 |
| 359 UniformHandle fVSParamUni; | 355 GrGLUniform* fVSParamUni; |
| 360 UniformHandle fFSParamUni; | 356 GrGLUniform* fFSParamUni; |
| 361 | 357 |
| 362 const char* fVSVaryingName; | 358 const char* fVSVaryingName; |
| 363 const char* fFSVaryingName; | 359 const char* fFSVaryingName; |
| 364 | 360 |
| 365 bool fIsDegenerate; | 361 bool fIsDegenerate; |
| 366 | 362 |
| 367 // @{ | 363 // @{ |
| 368 /// Values last uploaded as uniforms | 364 /// Values last uploaded as uniforms |
| 369 | 365 |
| 370 SkScalar fCachedCenter; | 366 SkScalar fCachedCenter; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 SkPaint paint; | 464 SkPaint paint; |
| 469 return shader->asNewEffect(context, paint); | 465 return shader->asNewEffect(context, paint); |
| 470 } | 466 } |
| 471 | 467 |
| 472 | 468 |
| 473 ///////////////////////////////////////////////////////////////////// | 469 ///////////////////////////////////////////////////////////////////// |
| 474 | 470 |
| 475 GrGLConical2Gradient::GrGLConical2Gradient(const GrBackendEffectFactory& factory
, | 471 GrGLConical2Gradient::GrGLConical2Gradient(const GrBackendEffectFactory& factory
, |
| 476 const GrDrawEffect& drawEffect) | 472 const GrDrawEffect& drawEffect) |
| 477 : INHERITED(factory) | 473 : INHERITED(factory) |
| 478 , fVSParamUni(kInvalidUniformHandle) | 474 , fVSParamUni(NULL) |
| 479 , fFSParamUni(kInvalidUniformHandle) | 475 , fFSParamUni(NULL) |
| 480 , fVSVaryingName(NULL) | 476 , fVSVaryingName(NULL) |
| 481 , fFSVaryingName(NULL) | 477 , fFSVaryingName(NULL) |
| 482 , fCachedCenter(SK_ScalarMax) | 478 , fCachedCenter(SK_ScalarMax) |
| 483 , fCachedRadius(-SK_ScalarMax) | 479 , fCachedRadius(-SK_ScalarMax) |
| 484 , fCachedDiffRadius(-SK_ScalarMax) { | 480 , fCachedDiffRadius(-SK_ScalarMax) { |
| 485 | 481 |
| 486 const GrConical2Gradient& data = drawEffect.castEffect<GrConical2Gradient>()
; | 482 const GrConical2Gradient& data = drawEffect.castEffect<GrConical2Gradient>()
; |
| 487 fIsDegenerate = data.isDegenerate(); | 483 fIsDegenerate = data.isDegenerate(); |
| 488 } | 484 } |
| 489 | 485 |
| 490 void GrGLConical2Gradient::emitCode(GrGLShaderBuilder* builder, | 486 void GrGLConical2Gradient::emitCode(GrGLShaderBuilder* builder, |
| 491 const GrDrawEffect&, | 487 const GrDrawEffect&, |
| 492 EffectKey key, | 488 EffectKey key, |
| 493 const char* outputColor, | 489 const char* outputColor, |
| 494 const char* inputColor, | 490 const char* inputColor, |
| 495 const TextureSamplerArray& samplers) { | 491 const TextureSamplerArray& samplers) { |
| 496 const char* fsCoords; | 492 const char* fsCoords; |
| 497 const char* vsCoordsVarying; | 493 const char* vsCoordsVarying; |
| 498 GrSLType coordsVaryingType; | 494 GrSLType coordsVaryingType; |
| 499 this->setupMatrix(builder, key, &fsCoords, &vsCoordsVarying, &coordsVaryingT
ype); | 495 this->setupMatrix(builder, key, &fsCoords, &vsCoordsVarying, &coordsVaryingT
ype); |
| 500 | 496 |
| 501 this->emitYCoordUniform(builder); | 497 GrGLShaderBuilder::Uniform* yCoordUni = this->emitYCoordUniform(builder); |
| 498 |
| 502 // 2 copies of uniform array, 1 for each of vertex & fragment shader, | 499 // 2 copies of uniform array, 1 for each of vertex & fragment shader, |
| 503 // to work around Xoom bug. Doesn't seem to cause performance decrease | 500 // to work around Xoom bug. Doesn't seem to cause performance decrease |
| 504 // in test apps, but need to keep an eye on it. | 501 // in test apps, but need to keep an eye on it. |
| 505 fVSParamUni = builder->addUniformArray(GrGLShaderBuilder::kVertex_ShaderType
, | 502 GrGLShaderBuilder::Uniform* vsParamUni = |
| 506 kFloat_GrSLType, "Conical2VSParams",
6); | 503 builder->addUniformArray(GrGLShaderBuilder::kVertex_ShaderType, |
| 507 fFSParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderTy
pe, | 504 kFloat_GrSLType, "Conical2VSParams", 6); |
| 508 kFloat_GrSLType, "Conical2FSParams",
6); | 505 fVSParamUni = vsParamUni->glUniform(); |
| 506 |
| 507 GrGLShaderBuilder::Uniform* fsParamUni = |
| 508 builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderType, |
| 509 kFloat_GrSLType, "Conical2FSParams", 6); |
| 510 fFSParamUni = fsParamUni->glUniform(); |
| 509 | 511 |
| 510 // For radial gradients without perspective we can pass the linear | 512 // For radial gradients without perspective we can pass the linear |
| 511 // part of the quadratic as a varying. | 513 // part of the quadratic as a varying. |
| 512 if (kVec2f_GrSLType == coordsVaryingType) { | 514 if (kVec2f_GrSLType == coordsVaryingType) { |
| 513 builder->addVarying(kFloat_GrSLType, "Conical2BCoeff", | 515 builder->addVarying(kFloat_GrSLType, "Conical2BCoeff", |
| 514 &fVSVaryingName, &fFSVaryingName); | 516 &fVSVaryingName, &fFSVaryingName); |
| 515 } | 517 } |
| 516 | 518 |
| 517 // VS | 519 // VS |
| 518 { | 520 { |
| 519 SkString p2; // distance between centers | 521 SkString p2; // distance between centers |
| 520 SkString p3; // start radius | 522 SkString p3; // start radius |
| 521 SkString p5; // difference in radii (r1 - r0) | 523 SkString p5; // difference in radii (r1 - r0) |
| 522 builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); | 524 vsParamUni->appendArrayAccess(2, &p2); |
| 523 builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); | 525 vsParamUni->appendArrayAccess(3, &p3); |
| 524 builder->getUniformVariable(fVSParamUni).appendArrayAccess(5, &p5); | 526 vsParamUni->appendArrayAccess(5, &p5); |
| 525 | 527 |
| 526 // For radial gradients without perspective we can pass the linear | 528 // For radial gradients without perspective we can pass the linear |
| 527 // part of the quadratic as a varying. | 529 // part of the quadratic as a varying. |
| 528 if (kVec2f_GrSLType == coordsVaryingType) { | 530 if (kVec2f_GrSLType == coordsVaryingType) { |
| 529 // r2Var = -2 * (r2Parm[2] * varCoord.x - r2Param[3] * r2Param[5]) | 531 // r2Var = -2 * (r2Parm[2] * varCoord.x - r2Param[3] * r2Param[5]) |
| 530 builder->vsCodeAppendf("\t%s = -2.0 * (%s * %s.x + %s * %s);\n", | 532 builder->vsCodeAppendf("\t%s = -2.0 * (%s * %s.x + %s * %s);\n", |
| 531 fVSVaryingName, p2.c_str(), | 533 fVSVaryingName, p2.c_str(), |
| 532 vsCoordsVarying, p3.c_str(), p5.c_str()); | 534 vsCoordsVarying, p3.c_str(), p5.c_str()); |
| 533 } | 535 } |
| 534 } | 536 } |
| 535 | 537 |
| 536 // FS | 538 // FS |
| 537 { | 539 { |
| 538 | 540 |
| 539 SkString cName("c"); | 541 SkString cName("c"); |
| 540 SkString ac4Name("ac4"); | 542 SkString ac4Name("ac4"); |
| 541 SkString dName("d"); | 543 SkString dName("d"); |
| 542 SkString qName("q"); | 544 SkString qName("q"); |
| 543 SkString r0Name("r0"); | 545 SkString r0Name("r0"); |
| 544 SkString r1Name("r1"); | 546 SkString r1Name("r1"); |
| 545 SkString tName("t"); | 547 SkString tName("t"); |
| 546 SkString p0; // 4a | 548 SkString p0; // 4a |
| 547 SkString p1; // 1/a | 549 SkString p1; // 1/a |
| 548 SkString p2; // distance between centers | 550 SkString p2; // distance between centers |
| 549 SkString p3; // start radius | 551 SkString p3; // start radius |
| 550 SkString p4; // start radius squared | 552 SkString p4; // start radius squared |
| 551 SkString p5; // difference in radii (r1 - r0) | 553 SkString p5; // difference in radii (r1 - r0) |
| 552 | 554 |
| 553 builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0); | 555 fsParamUni->appendArrayAccess(0, &p0); |
| 554 builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1); | 556 fsParamUni->appendArrayAccess(1, &p1); |
| 555 builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2); | 557 fsParamUni->appendArrayAccess(2, &p2); |
| 556 builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3); | 558 fsParamUni->appendArrayAccess(3, &p3); |
| 557 builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4); | 559 fsParamUni->appendArrayAccess(4, &p4); |
| 558 builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5); | 560 fsParamUni->appendArrayAccess(5, &p5); |
| 559 | 561 |
| 560 // If we we're able to interpolate the linear component, | 562 // If we we're able to interpolate the linear component, |
| 561 // bVar is the varying; otherwise compute it | 563 // bVar is the varying; otherwise compute it |
| 562 SkString bVar; | 564 SkString bVar; |
| 563 if (kVec2f_GrSLType == coordsVaryingType) { | 565 if (kVec2f_GrSLType == coordsVaryingType) { |
| 564 bVar = fFSVaryingName; | 566 bVar = fFSVaryingName; |
| 565 } else { | 567 } else { |
| 566 bVar = "b"; | 568 bVar = "b"; |
| 567 builder->fsCodeAppendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n
", | 569 builder->fsCodeAppendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n
", |
| 568 bVar.c_str(), p2.c_str(), fsCoords, | 570 bVar.c_str(), p2.c_str(), fsCoords, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 | 613 |
| 612 // so we'll look at the larger one first: | 614 // so we'll look at the larger one first: |
| 613 builder->fsCodeAppendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str(
), | 615 builder->fsCodeAppendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str(
), |
| 614 r0Name.c_str(), r1Name.c_str()); | 616 r0Name.c_str(), r1Name.c_str()); |
| 615 | 617 |
| 616 // if r(t) > 0, then we're done; t will be our x coordinate | 618 // if r(t) > 0, then we're done; t will be our x coordinate |
| 617 builder->fsCodeAppendf("\t\tif (%s * %s + %s > 0.0) {\n", tName.c_st
r(), | 619 builder->fsCodeAppendf("\t\tif (%s * %s + %s > 0.0) {\n", tName.c_st
r(), |
| 618 p5.c_str(), p3.c_str()); | 620 p5.c_str(), p3.c_str()); |
| 619 | 621 |
| 620 builder->fsCodeAppend("\t\t"); | 622 builder->fsCodeAppend("\t\t"); |
| 621 this->emitColorLookup(builder, tName.c_str(), outputColor, inputColo
r, samplers[0]); | 623 this->emitColorLookup(builder, yCoordUni, tName.c_str(), outputColor
, inputColor, samplers[0]); |
| 622 | 624 |
| 623 // otherwise, if r(t) for the larger root was <= 0, try the other ro
ot | 625 // otherwise, if r(t) for the larger root was <= 0, try the other ro
ot |
| 624 builder->fsCodeAppend("\t\t} else {\n"); | 626 builder->fsCodeAppend("\t\t} else {\n"); |
| 625 builder->fsCodeAppendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(), | 627 builder->fsCodeAppendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(), |
| 626 r0Name.c_str(), r1Name.c_str()); | 628 r0Name.c_str(), r1Name.c_str()); |
| 627 | 629 |
| 628 // if r(t) > 0 for the smaller root, then t will be our x coordinate | 630 // if r(t) > 0 for the smaller root, then t will be our x coordinate |
| 629 builder->fsCodeAppendf("\t\t\tif (%s * %s + %s > 0.0) {\n", | 631 builder->fsCodeAppendf("\t\t\tif (%s * %s + %s > 0.0) {\n", |
| 630 tName.c_str(), p5.c_str(), p3.c_str()); | 632 tName.c_str(), p5.c_str(), p3.c_str()); |
| 631 | 633 |
| 632 builder->fsCodeAppend("\t\t\t"); | 634 builder->fsCodeAppend("\t\t\t"); |
| 633 this->emitColorLookup(builder, tName.c_str(), outputColor, inputColo
r, samplers[0]); | 635 this->emitColorLookup(builder, yCoordUni, tName.c_str(), outputColor
, inputColor, samplers[0]); |
| 634 | 636 |
| 635 // end if (r(t) > 0) for smaller root | 637 // end if (r(t) > 0) for smaller root |
| 636 builder->fsCodeAppend("\t\t\t}\n"); | 638 builder->fsCodeAppend("\t\t\t}\n"); |
| 637 // end if (r(t) > 0), else, for larger root | 639 // end if (r(t) > 0), else, for larger root |
| 638 builder->fsCodeAppend("\t\t}\n"); | 640 builder->fsCodeAppend("\t\t}\n"); |
| 639 // end if (discriminant >= 0) | 641 // end if (discriminant >= 0) |
| 640 builder->fsCodeAppend("\t}\n"); | 642 builder->fsCodeAppend("\t}\n"); |
| 641 } else { | 643 } else { |
| 642 | 644 |
| 643 // linear case: t = -c/b | 645 // linear case: t = -c/b |
| 644 builder->fsCodeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(), | 646 builder->fsCodeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(), |
| 645 cName.c_str(), bVar.c_str()); | 647 cName.c_str(), bVar.c_str()); |
| 646 | 648 |
| 647 // if r(t) > 0, then t will be the x coordinate | 649 // if r(t) > 0, then t will be the x coordinate |
| 648 builder->fsCodeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(
), | 650 builder->fsCodeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(
), |
| 649 p5.c_str(), p3.c_str()); | 651 p5.c_str(), p3.c_str()); |
| 650 builder->fsCodeAppend("\t"); | 652 builder->fsCodeAppend("\t"); |
| 651 this->emitColorLookup(builder, tName.c_str(), outputColor, inputColo
r, samplers[0]); | 653 this->emitColorLookup(builder, yCoordUni, tName.c_str(), outputColor
, inputColor, samplers[0]); |
| 652 builder->fsCodeAppend("\t}\n"); | 654 builder->fsCodeAppend("\t}\n"); |
| 653 } | 655 } |
| 654 } | 656 } |
| 655 } | 657 } |
| 656 | 658 |
| 657 void GrGLConical2Gradient::setData(const GrGLUniformManager& uman, | 659 void GrGLConical2Gradient::setData(const GrGLContext& context, |
| 658 const GrDrawEffect& drawEffect) { | 660 const GrDrawEffect& drawEffect) { |
| 659 INHERITED::setData(uman, drawEffect); | 661 INHERITED::setData(context, drawEffect); |
| 660 const GrConical2Gradient& data = drawEffect.castEffect<GrConical2Gradient>()
; | 662 const GrConical2Gradient& data = drawEffect.castEffect<GrConical2Gradient>()
; |
| 661 GrAssert(data.isDegenerate() == fIsDegenerate); | 663 GrAssert(data.isDegenerate() == fIsDegenerate); |
| 662 SkScalar centerX1 = data.center(); | 664 SkScalar centerX1 = data.center(); |
| 663 SkScalar radius0 = data.radius(); | 665 SkScalar radius0 = data.radius(); |
| 664 SkScalar diffRadius = data.diffRadius(); | 666 SkScalar diffRadius = data.diffRadius(); |
| 665 | 667 |
| 666 if (fCachedCenter != centerX1 || | 668 if (fCachedCenter != centerX1 || |
| 667 fCachedRadius != radius0 || | 669 fCachedRadius != radius0 || |
| 668 fCachedDiffRadius != diffRadius) { | 670 fCachedDiffRadius != diffRadius) { |
| 669 | 671 |
| 670 SkScalar a = SkScalarMul(centerX1, centerX1) - diffRadius * diffRadius; | 672 SkScalar a = SkScalarMul(centerX1, centerX1) - diffRadius * diffRadius; |
| 671 | 673 |
| 672 // When we're in the degenerate (linear) case, the second | 674 // When we're in the degenerate (linear) case, the second |
| 673 // value will be INF but the program doesn't read it. (We | 675 // value will be INF but the program doesn't read it. (We |
| 674 // use the same 6 uniforms even though we don't need them | 676 // use the same 6 uniforms even though we don't need them |
| 675 // all in the linear case just to keep the code complexity | 677 // all in the linear case just to keep the code complexity |
| 676 // down). | 678 // down). |
| 677 float values[6] = { | 679 float values[6] = { |
| 678 SkScalarToFloat(a * 4), | 680 SkScalarToFloat(a * 4), |
| 679 1.f / (SkScalarToFloat(a)), | 681 1.f / (SkScalarToFloat(a)), |
| 680 SkScalarToFloat(centerX1), | 682 SkScalarToFloat(centerX1), |
| 681 SkScalarToFloat(radius0), | 683 SkScalarToFloat(radius0), |
| 682 SkScalarToFloat(SkScalarMul(radius0, radius0)), | 684 SkScalarToFloat(SkScalarMul(radius0, radius0)), |
| 683 SkScalarToFloat(diffRadius) | 685 SkScalarToFloat(diffRadius) |
| 684 }; | 686 }; |
| 685 | 687 |
| 686 uman.set1fv(fVSParamUni, 0, 6, values); | 688 fVSParamUni->set1fv(context, 0, 6, values); |
| 687 uman.set1fv(fFSParamUni, 0, 6, values); | 689 fFSParamUni->set1fv(context, 0, 6, values); |
| 688 fCachedCenter = centerX1; | 690 fCachedCenter = centerX1; |
| 689 fCachedRadius = radius0; | 691 fCachedRadius = radius0; |
| 690 fCachedDiffRadius = diffRadius; | 692 fCachedDiffRadius = diffRadius; |
| 691 } | 693 } |
| 692 } | 694 } |
| 693 | 695 |
| 694 GrGLEffect::EffectKey GrGLConical2Gradient::GenKey(const GrDrawEffect& drawEffec
t, | 696 GrGLEffect::EffectKey GrGLConical2Gradient::GenKey(const GrDrawEffect& drawEffec
t, |
| 695 const GrGLCaps&) { | 697 const GrGLCaps&) { |
| 696 enum { | 698 enum { |
| 697 kIsDegenerate = 1 << kMatrixKeyBitCnt, | 699 kIsDegenerate = 1 << kMatrixKeyBitCnt, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 str->appendScalar(fCenter2.fY); | 758 str->appendScalar(fCenter2.fY); |
| 757 str->append(") radius2: "); | 759 str->append(") radius2: "); |
| 758 str->appendScalar(fRadius2); | 760 str->appendScalar(fRadius2); |
| 759 str->append(" "); | 761 str->append(" "); |
| 760 | 762 |
| 761 this->INHERITED::toString(str); | 763 this->INHERITED::toString(str); |
| 762 | 764 |
| 763 str->append(")"); | 765 str->append(")"); |
| 764 } | 766 } |
| 765 #endif | 767 #endif |
| OLD | NEW |