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 |