| 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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY); | 367 fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY); |
| 368 fPtsToUnit.postScale(inv, inv); | 368 fPtsToUnit.postScale(inv, inv); |
| 369 } | 369 } |
| 370 | 370 |
| 371 ///////////////////////////////////////////////////////////////////// | 371 ///////////////////////////////////////////////////////////////////// |
| 372 | 372 |
| 373 #if SK_SUPPORT_GPU | 373 #if SK_SUPPORT_GPU |
| 374 | 374 |
| 375 #include "GrTBackendEffectFactory.h" | 375 #include "GrTBackendEffectFactory.h" |
| 376 | 376 |
| 377 // For brevity | |
| 378 typedef GrGLUniformManager::UniformHandle UniformHandle; | |
| 379 static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidU
niformHandle; | |
| 380 | |
| 381 class GrGLRadial2Gradient : public GrGLGradientEffect { | 377 class GrGLRadial2Gradient : public GrGLGradientEffect { |
| 382 | 378 |
| 383 public: | 379 public: |
| 384 | 380 |
| 385 GrGLRadial2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffec
t&); | 381 GrGLRadial2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffec
t&); |
| 386 virtual ~GrGLRadial2Gradient() { } | 382 virtual ~GrGLRadial2Gradient() { } |
| 387 | 383 |
| 388 virtual void emitCode(GrGLShaderBuilder*, | 384 virtual void emitCode(GrGLShaderBuilder*, |
| 389 const GrDrawEffect&, | 385 const GrDrawEffect&, |
| 390 EffectKey, | 386 EffectKey, |
| 391 const char* outputColor, | 387 const char* outputColor, |
| 392 const char* inputColor, | 388 const char* inputColor, |
| 393 const TextureSamplerArray&) SK_OVERRIDE; | 389 const TextureSamplerArray&) SK_OVERRIDE; |
| 394 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; | 390 virtual void setData(const GrGLContext&, const GrDrawEffect&) SK_OVERRIDE; |
| 395 | 391 |
| 396 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); | 392 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); |
| 397 | 393 |
| 398 protected: | 394 protected: |
| 399 | 395 |
| 400 UniformHandle fVSParamUni; | 396 GrGLUniform* fVSParamUni; |
| 401 UniformHandle fFSParamUni; | 397 GrGLUniform* fFSParamUni; |
| 402 | 398 |
| 403 const char* fVSVaryingName; | 399 const char* fVSVaryingName; |
| 404 const char* fFSVaryingName; | 400 const char* fFSVaryingName; |
| 405 | 401 |
| 406 bool fIsDegenerate; | 402 bool fIsDegenerate; |
| 407 | 403 |
| 408 // @{ | 404 // @{ |
| 409 /// Values last uploaded as uniforms | 405 /// Values last uploaded as uniforms |
| 410 | 406 |
| 411 SkScalar fCachedCenter; | 407 SkScalar fCachedCenter; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 tm)); | 505 tm)); |
| 510 SkPaint paint; | 506 SkPaint paint; |
| 511 return shader->asNewEffect(context, paint); | 507 return shader->asNewEffect(context, paint); |
| 512 } | 508 } |
| 513 | 509 |
| 514 ///////////////////////////////////////////////////////////////////// | 510 ///////////////////////////////////////////////////////////////////// |
| 515 | 511 |
| 516 GrGLRadial2Gradient::GrGLRadial2Gradient(const GrBackendEffectFactory& factory, | 512 GrGLRadial2Gradient::GrGLRadial2Gradient(const GrBackendEffectFactory& factory, |
| 517 const GrDrawEffect& drawEffect) | 513 const GrDrawEffect& drawEffect) |
| 518 : INHERITED(factory) | 514 : INHERITED(factory) |
| 519 , fVSParamUni(kInvalidUniformHandle) | 515 , fVSParamUni(NULL) |
| 520 , fFSParamUni(kInvalidUniformHandle) | 516 , fFSParamUni(NULL) |
| 521 , fVSVaryingName(NULL) | 517 , fVSVaryingName(NULL) |
| 522 , fFSVaryingName(NULL) | 518 , fFSVaryingName(NULL) |
| 523 , fCachedCenter(SK_ScalarMax) | 519 , fCachedCenter(SK_ScalarMax) |
| 524 , fCachedRadius(-SK_ScalarMax) | 520 , fCachedRadius(-SK_ScalarMax) |
| 525 , fCachedPosRoot(0) { | 521 , fCachedPosRoot(0) { |
| 526 | 522 |
| 527 const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>(); | 523 const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>(); |
| 528 fIsDegenerate = data.isDegenerate(); | 524 fIsDegenerate = data.isDegenerate(); |
| 529 } | 525 } |
| 530 | 526 |
| 531 void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder, | 527 void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder, |
| 532 const GrDrawEffect& drawEffect, | 528 const GrDrawEffect& drawEffect, |
| 533 EffectKey key, | 529 EffectKey key, |
| 534 const char* outputColor, | 530 const char* outputColor, |
| 535 const char* inputColor, | 531 const char* inputColor, |
| 536 const TextureSamplerArray& samplers) { | 532 const TextureSamplerArray& samplers) { |
| 537 | 533 |
| 538 this->emitYCoordUniform(builder); | 534 GrGLShaderBuilder::Uniform* yCoordUni = this->emitYCoordUniform(builder); |
| 539 const char* fsCoords; | 535 const char* fsCoords; |
| 540 const char* vsCoordsVarying; | 536 const char* vsCoordsVarying; |
| 541 GrSLType coordsVaryingType; | 537 GrSLType coordsVaryingType; |
| 542 this->setupMatrix(builder, key, &fsCoords, &vsCoordsVarying, &coordsVaryingT
ype); | 538 this->setupMatrix(builder, key, &fsCoords, &vsCoordsVarying, &coordsVaryingT
ype); |
| 543 | 539 |
| 544 // 2 copies of uniform array, 1 for each of vertex & fragment shader, | 540 // 2 copies of uniform array, 1 for each of vertex & fragment shader, |
| 545 // to work around Xoom bug. Doesn't seem to cause performance decrease | 541 // to work around Xoom bug. Doesn't seem to cause performance decrease |
| 546 // in test apps, but need to keep an eye on it. | 542 // in test apps, but need to keep an eye on it. |
| 547 fVSParamUni = builder->addUniformArray(GrGLShaderBuilder::kVertex_ShaderType
, | 543 GrGLShaderBuilder::Uniform* vsParamUni = |
| 548 kFloat_GrSLType, "Radial2VSParams", 6
); | 544 builder->addUniformArray(GrGLShaderBuilder::kVertex_ShaderType, |
| 549 fFSParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderTy
pe, | 545 kFloat_GrSLType, "Radial2VSParams", 6); |
| 550 kFloat_GrSLType, "Radial2FSParams", 6
); | 546 fVSParamUni = vsParamUni->glUniform(); |
| 547 |
| 548 GrGLShaderBuilder::Uniform* fsParamUni = |
| 549 builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderType, |
| 550 kFloat_GrSLType, "Radial2FSParams", 6); |
| 551 fFSParamUni = fsParamUni->glUniform(); |
| 551 | 552 |
| 552 // For radial gradients without perspective we can pass the linear | 553 // For radial gradients without perspective we can pass the linear |
| 553 // part of the quadratic as a varying. | 554 // part of the quadratic as a varying. |
| 554 if (kVec2f_GrSLType == coordsVaryingType) { | 555 if (kVec2f_GrSLType == coordsVaryingType) { |
| 555 builder->addVarying(kFloat_GrSLType, "Radial2BCoeff", &fVSVaryingName, &
fFSVaryingName); | 556 builder->addVarying(kFloat_GrSLType, "Radial2BCoeff", &fVSVaryingName, &
fFSVaryingName); |
| 556 } | 557 } |
| 557 | 558 |
| 558 // VS | 559 // VS |
| 559 { | 560 { |
| 560 SkString p2; | 561 SkString p2; |
| 561 SkString p3; | 562 SkString p3; |
| 562 builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); | 563 vsParamUni->appendArrayAccess(2, &p2); |
| 563 builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); | 564 vsParamUni->appendArrayAccess(3, &p3); |
| 564 | 565 |
| 565 // For radial gradients without perspective we can pass the linear | 566 // For radial gradients without perspective we can pass the linear |
| 566 // part of the quadratic as a varying. | 567 // part of the quadratic as a varying. |
| 567 if (kVec2f_GrSLType == coordsVaryingType) { | 568 if (kVec2f_GrSLType == coordsVaryingType) { |
| 568 // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3]) | 569 // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3]) |
| 569 builder->vsCodeAppendf("\t%s = 2.0 *(%s * %s.x - %s);\n", | 570 builder->vsCodeAppendf("\t%s = 2.0 *(%s * %s.x - %s);\n", |
| 570 fVSVaryingName, p2.c_str(), | 571 fVSVaryingName, p2.c_str(), |
| 571 vsCoordsVarying, p3.c_str()); | 572 vsCoordsVarying, p3.c_str()); |
| 572 } | 573 } |
| 573 } | 574 } |
| 574 | 575 |
| 575 // FS | 576 // FS |
| 576 { | 577 { |
| 577 SkString cName("c"); | 578 SkString cName("c"); |
| 578 SkString ac4Name("ac4"); | 579 SkString ac4Name("ac4"); |
| 579 SkString rootName("root"); | 580 SkString rootName("root"); |
| 580 SkString t; | 581 SkString t; |
| 581 SkString p0; | 582 SkString p0; |
| 582 SkString p1; | 583 SkString p1; |
| 583 SkString p2; | 584 SkString p2; |
| 584 SkString p3; | 585 SkString p3; |
| 585 SkString p4; | 586 SkString p4; |
| 586 SkString p5; | 587 SkString p5; |
| 587 builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0); | 588 fsParamUni->appendArrayAccess(0, &p0); |
| 588 builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1); | 589 fsParamUni->appendArrayAccess(1, &p1); |
| 589 builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2); | 590 fsParamUni->appendArrayAccess(2, &p2); |
| 590 builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3); | 591 fsParamUni->appendArrayAccess(3, &p3); |
| 591 builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4); | 592 fsParamUni->appendArrayAccess(4, &p4); |
| 592 builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5); | 593 fsParamUni->appendArrayAccess(5, &p5); |
| 593 | 594 |
| 594 // If we we're able to interpolate the linear component, | 595 // If we we're able to interpolate the linear component, |
| 595 // bVar is the varying; otherwise compute it | 596 // bVar is the varying; otherwise compute it |
| 596 SkString bVar; | 597 SkString bVar; |
| 597 if (kVec2f_GrSLType == coordsVaryingType) { | 598 if (kVec2f_GrSLType == coordsVaryingType) { |
| 598 bVar = fFSVaryingName; | 599 bVar = fFSVaryingName; |
| 599 } else { | 600 } else { |
| 600 bVar = "b"; | 601 bVar = "b"; |
| 601 builder->fsCodeAppendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n", | 602 builder->fsCodeAppendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n", |
| 602 bVar.c_str(), p2.c_str(), fsCoords, p3.c_str(
)); | 603 bVar.c_str(), p2.c_str(), fsCoords, p3.c_str(
)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 625 ac4Name.c_str()); | 626 ac4Name.c_str()); |
| 626 | 627 |
| 627 // t is: (-b + params[5] * sqrt(b^2-4ac)) * params[1] | 628 // t is: (-b + params[5] * sqrt(b^2-4ac)) * params[1] |
| 628 t.printf("(-%s + %s * %s) * %s", bVar.c_str(), p5.c_str(), | 629 t.printf("(-%s + %s * %s) * %s", bVar.c_str(), p5.c_str(), |
| 629 rootName.c_str(), p1.c_str()); | 630 rootName.c_str(), p1.c_str()); |
| 630 } else { | 631 } else { |
| 631 // t is: -c/b | 632 // t is: -c/b |
| 632 t.printf("-%s / %s", cName.c_str(), bVar.c_str()); | 633 t.printf("-%s / %s", cName.c_str(), bVar.c_str()); |
| 633 } | 634 } |
| 634 | 635 |
| 635 this->emitColorLookup(builder, t.c_str(), outputColor, inputColor, sampl
ers[0]); | 636 this->emitColorLookup(builder, yCoordUni, t.c_str(), outputColor, inputC
olor, samplers[0]); |
| 636 } | 637 } |
| 637 } | 638 } |
| 638 | 639 |
| 639 void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman, | 640 void GrGLRadial2Gradient::setData(const GrGLContext& context, |
| 640 const GrDrawEffect& drawEffect) { | 641 const GrDrawEffect& drawEffect) { |
| 641 INHERITED::setData(uman, drawEffect); | 642 INHERITED::setData(context, drawEffect); |
| 642 const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>(); | 643 const GrRadial2Gradient& data = drawEffect.castEffect<GrRadial2Gradient>(); |
| 643 GrAssert(data.isDegenerate() == fIsDegenerate); | 644 GrAssert(data.isDegenerate() == fIsDegenerate); |
| 644 SkScalar centerX1 = data.center(); | 645 SkScalar centerX1 = data.center(); |
| 645 SkScalar radius0 = data.radius(); | 646 SkScalar radius0 = data.radius(); |
| 646 if (fCachedCenter != centerX1 || | 647 if (fCachedCenter != centerX1 || |
| 647 fCachedRadius != radius0 || | 648 fCachedRadius != radius0 || |
| 648 fCachedPosRoot != data.isPosRoot()) { | 649 fCachedPosRoot != data.isPosRoot()) { |
| 649 | 650 |
| 650 SkScalar a = SkScalarMul(centerX1, centerX1) - SK_Scalar1; | 651 SkScalar a = SkScalarMul(centerX1, centerX1) - SK_Scalar1; |
| 651 | 652 |
| 652 // When we're in the degenerate (linear) case, the second | 653 // When we're in the degenerate (linear) case, the second |
| 653 // value will be INF but the program doesn't read it. (We | 654 // value will be INF but the program doesn't read it. (We |
| 654 // use the same 6 uniforms even though we don't need them | 655 // use the same 6 uniforms even though we don't need them |
| 655 // all in the linear case just to keep the code complexity | 656 // all in the linear case just to keep the code complexity |
| 656 // down). | 657 // down). |
| 657 float values[6] = { | 658 float values[6] = { |
| 658 SkScalarToFloat(a), | 659 SkScalarToFloat(a), |
| 659 1 / (2.f * SkScalarToFloat(a)), | 660 1 / (2.f * SkScalarToFloat(a)), |
| 660 SkScalarToFloat(centerX1), | 661 SkScalarToFloat(centerX1), |
| 661 SkScalarToFloat(radius0), | 662 SkScalarToFloat(radius0), |
| 662 SkScalarToFloat(SkScalarMul(radius0, radius0)), | 663 SkScalarToFloat(SkScalarMul(radius0, radius0)), |
| 663 data.isPosRoot() ? 1.f : -1.f | 664 data.isPosRoot() ? 1.f : -1.f |
| 664 }; | 665 }; |
| 665 | 666 |
| 666 uman.set1fv(fVSParamUni, 0, 6, values); | 667 fVSParamUni->set1fv(context, 0, 6, values); |
| 667 uman.set1fv(fFSParamUni, 0, 6, values); | 668 fFSParamUni->set1fv(context, 0, 6, values); |
| 668 fCachedCenter = centerX1; | 669 fCachedCenter = centerX1; |
| 669 fCachedRadius = radius0; | 670 fCachedRadius = radius0; |
| 670 fCachedPosRoot = data.isPosRoot(); | 671 fCachedPosRoot = data.isPosRoot(); |
| 671 } | 672 } |
| 672 } | 673 } |
| 673 | 674 |
| 674 GrGLEffect::EffectKey GrGLRadial2Gradient::GenKey(const GrDrawEffect& drawEffect
, | 675 GrGLEffect::EffectKey GrGLRadial2Gradient::GenKey(const GrDrawEffect& drawEffect
, |
| 675 const GrGLCaps&) { | 676 const GrGLCaps&) { |
| 676 enum { | 677 enum { |
| 677 kIsDegenerate = 1 << kMatrixKeyBitCnt, | 678 kIsDegenerate = 1 << kMatrixKeyBitCnt, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 708 } | 709 } |
| 709 | 710 |
| 710 #else | 711 #else |
| 711 | 712 |
| 712 GrEffectRef* SkTwoPointRadialGradient::asNewEffect(GrContext*, const SkPaint&) c
onst { | 713 GrEffectRef* SkTwoPointRadialGradient::asNewEffect(GrContext*, const SkPaint&) c
onst { |
| 713 SkDEBUGFAIL("Should not call in GPU-less build"); | 714 SkDEBUGFAIL("Should not call in GPU-less build"); |
| 714 return NULL; | 715 return NULL; |
| 715 } | 716 } |
| 716 | 717 |
| 717 #endif | 718 #endif |
| OLD | NEW |