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 |