Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: src/effects/gradients/SkTwoPointConicalGradient.cpp

Issue 25474006: Move VertexBuilder to a GrGLFullShaderBuilder subclass (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkTwoPointConicalGradient.h" 8 #include "SkTwoPointConicalGradient.h"
9 9
10 static int valid_divide(float numer, float denom, float* ratio) { 10 static int valid_divide(float numer, float denom, float* ratio) {
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 335
336 // For brevity 336 // For brevity
337 typedef GrGLUniformManager::UniformHandle UniformHandle; 337 typedef GrGLUniformManager::UniformHandle UniformHandle;
338 338
339 class GrGLConical2Gradient : public GrGLGradientEffect { 339 class GrGLConical2Gradient : public GrGLGradientEffect {
340 public: 340 public:
341 341
342 GrGLConical2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffe ct&); 342 GrGLConical2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffe ct&);
343 virtual ~GrGLConical2Gradient() { } 343 virtual ~GrGLConical2Gradient() { }
344 344
345 virtual void emitCode(GrGLFullShaderBuilder*,
bsalomon 2013/10/03 14:44:52 Eek.. do we need both virtuals for emitting code o
Chris Dalton 2013/10/03 21:43:22 Done.
346 const GrDrawEffect&,
347 EffectKey,
348 const char* outputColor,
349 const char* inputColor,
350 const TransformedCoordsArray&,
351 const TextureSamplerArray&) SK_OVERRIDE;
352
345 virtual void emitCode(GrGLShaderBuilder*, 353 virtual void emitCode(GrGLShaderBuilder*,
346 const GrDrawEffect&, 354 const GrDrawEffect&,
347 EffectKey, 355 EffectKey,
348 const char* outputColor, 356 const char* outputColor,
349 const char* inputColor, 357 const char* inputColor,
350 const TransformedCoordsArray&, 358 const TransformedCoordsArray&,
351 const TextureSamplerArray&) SK_OVERRIDE; 359 const TextureSamplerArray&) SK_OVERRIDE;
360
361 void emitUniforms(GrGLShaderBuilder* builder, EffectKey key);
362
363 void emitFragmentCode(GrGLShaderBuilder*,
364 EffectKey,
365 const char* outputColor,
366 const char* inputColor,
367 const TransformedCoordsArray&,
368 const TextureSamplerArray&);
369
352 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE; 370 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE;
353 371
354 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); 372 static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
355 373
356 protected: 374 protected:
357 375
358 UniformHandle fVSParamUni; 376 UniformHandle fVSParamUni;
359 UniformHandle fFSParamUni; 377 UniformHandle fFSParamUni;
360 378
361 const char* fVSVaryingName; 379 const char* fVSVaryingName;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 , fVSVaryingName(NULL) 495 , fVSVaryingName(NULL)
478 , fFSVaryingName(NULL) 496 , fFSVaryingName(NULL)
479 , fCachedCenter(SK_ScalarMax) 497 , fCachedCenter(SK_ScalarMax)
480 , fCachedRadius(-SK_ScalarMax) 498 , fCachedRadius(-SK_ScalarMax)
481 , fCachedDiffRadius(-SK_ScalarMax) { 499 , fCachedDiffRadius(-SK_ScalarMax) {
482 500
483 const GrConical2Gradient& data = drawEffect.castEffect<GrConical2Gradient>() ; 501 const GrConical2Gradient& data = drawEffect.castEffect<GrConical2Gradient>() ;
484 fIsDegenerate = data.isDegenerate(); 502 fIsDegenerate = data.isDegenerate();
485 } 503 }
486 504
487 void GrGLConical2Gradient::emitCode(GrGLShaderBuilder* builder, 505 void GrGLConical2Gradient::emitCode(GrGLFullShaderBuilder* builder,
488 const GrDrawEffect&, 506 const GrDrawEffect&,
489 EffectKey key, 507 EffectKey key,
490 const char* outputColor, 508 const char* outputColor,
491 const char* inputColor, 509 const char* inputColor,
492 const TransformedCoordsArray& coords, 510 const TransformedCoordsArray& coords,
493 const TextureSamplerArray& samplers) { 511 const TextureSamplerArray& samplers) {
494 this->emitUniforms(builder, key); 512 this->emitUniforms(builder, key);
495 // 2 copies of uniform array, 1 for each of vertex & fragment shader,
496 // to work around Xoom bug. Doesn't seem to cause performance decrease
497 // in test apps, but need to keep an eye on it.
498 fVSParamUni = builder->addUniformArray(GrGLShaderBuilder::kVertex_Visibility ,
499 kFloat_GrSLType, "Conical2VSParams", 6);
500 fFSParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibili ty,
501 kFloat_GrSLType, "Conical2FSParams", 6);
502 513
503 // For radial gradients without perspective we can pass the linear 514 if (kVec2f_GrSLType == coords[0].type()) {
504 // part of the quadratic as a varying. 515 // For conical gradients without perspective we can pass the linear
505 GrGLShaderBuilder::VertexBuilder* vertexBuilder = 516 // part of the quadratic as a varying.
506 (kVec2f_GrSLType == coords[0].type()) ? builder->getVertexBuilder() : NU LL;
507 if (NULL != vertexBuilder) {
508 vertexBuilder->addVarying(kFloat_GrSLType, "Conical2BCoeff",
509 &fVSVaryingName, &fFSVaryingName);
510 }
511
512 // VS
513 {
514 SkString p2; // distance between centers 517 SkString p2; // distance between centers
515 SkString p3; // start radius 518 SkString p3; // start radius
516 SkString p5; // difference in radii (r1 - r0) 519 SkString p5; // difference in radii (r1 - r0)
517 builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); 520 builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2);
518 builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); 521 builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3);
519 builder->getUniformVariable(fVSParamUni).appendArrayAccess(5, &p5); 522 builder->getUniformVariable(fVSParamUni).appendArrayAccess(5, &p5);
520 523
521 // For radial gradients without perspective we can pass the linear 524 builder->addVarying(kFloat_GrSLType, "Conical2BCoeff", &fVSVaryingName, &fFSVaryingName);
522 // part of the quadratic as a varying. 525
523 if (NULL != vertexBuilder) { 526 // r2Var = -2 * (r2Parm[2] * varCoord.x - r2Param[3] * r2Param[5])
524 // r2Var = -2 * (r2Parm[2] * varCoord.x - r2Param[3] * r2Param[5]) 527 builder->vsCodeAppendf("\t%s = -2.0 * (%s * %s.x + %s * %s);\n",
525 vertexBuilder->vsCodeAppendf("\t%s = -2.0 * (%s * %s.x + %s * %s);\n ", 528 fVSVaryingName, p2.c_str(),
526 fVSVaryingName, p2.c_str(), 529 coords[0].getVSName().c_str(), p3.c_str(), p5.c_s tr());
527 coords[0].getVSName().c_str(), p3.c_ str(), p5.c_str());
528 }
529 } 530 }
530 531
531 // FS 532 this->emitFragmentCode(builder, key, outputColor, inputColor, coords, sample rs);
532 { 533 }
533 SkString coords2D = builder->ensureFSCoords2D(coords, 0);
534 SkString cName("c");
535 SkString ac4Name("ac4");
536 SkString dName("d");
537 SkString qName("q");
538 SkString r0Name("r0");
539 SkString r1Name("r1");
540 SkString tName("t");
541 SkString p0; // 4a
542 SkString p1; // 1/a
543 SkString p2; // distance between centers
544 SkString p3; // start radius
545 SkString p4; // start radius squared
546 SkString p5; // difference in radii (r1 - r0)
547 534
548 builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0); 535 void GrGLConical2Gradient::emitCode(GrGLShaderBuilder* builder,
549 builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1); 536 const GrDrawEffect&,
550 builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2); 537 EffectKey key,
551 builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3); 538 const char* outputColor,
552 builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4); 539 const char* inputColor,
553 builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5); 540 const TransformedCoordsArray& coords,
541 const TextureSamplerArray& samplers) {
542 this->emitUniforms(builder, key);
543 this->emitFragmentCode(builder, key, outputColor, inputColor, coords, sample rs);
544 }
554 545
555 // If we we're able to interpolate the linear component, 546 void GrGLConical2Gradient::emitUniforms(GrGLShaderBuilder* builder, EffectKey ke y) {
556 // bVar is the varying; otherwise compute it 547 this->INHERITED::emitUniforms(builder, key);
557 SkString bVar; 548 // 2 copies of uniform array, 1 for each of vertex & fragment shader,
558 if (NULL != vertexBuilder) { 549 // to work around Xoom bug. Doesn't seem to cause performance decrease
559 bVar = fFSVaryingName; 550 // in test apps, but need to keep an eye on it.
560 } else { 551 fVSParamUni = builder->addUniformArray(GrGLShaderBuilder::kVertex_Visibility ,
561 bVar = "b"; 552 kFloat_GrSLType, "Conical2VSParams", 6);
562 builder->fsCodeAppendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n ", 553 fFSParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibili ty,
563 bVar.c_str(), p2.c_str(), coords2D.c_str(), 554 kFloat_GrSLType, "Conical2FSParams", 6);
564 p3.c_str(), p5.c_str()); 555 }
565 }
566 556
567 // output will default to transparent black (we simply won't write anyth ing 557 void GrGLConical2Gradient::emitFragmentCode(GrGLShaderBuilder* builder,
568 // else to it if invalid, instead of discarding or returning prematurely ) 558 EffectKey key,
569 builder->fsCodeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor); 559 const char* outputColor,
560 const char* inputColor,
561 const TransformedCoordsArray& coords ,
562 const TextureSamplerArray& samplers) {
563 SkString coords2D = builder->ensureFSCoords2D(coords, 0);
564 SkString cName("c");
565 SkString ac4Name("ac4");
566 SkString dName("d");
567 SkString qName("q");
568 SkString r0Name("r0");
569 SkString r1Name("r1");
570 SkString tName("t");
571 SkString p0; // 4a
572 SkString p1; // 1/a
573 SkString p2; // distance between centers
574 SkString p3; // start radius
575 SkString p4; // start radius squared
576 SkString p5; // difference in radii (r1 - r0)
570 577
571 // c = (x^2)+(y^2) - params[4] 578 builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0);
572 builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n", cName.c_str() , 579 builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1);
573 coords2D.c_str(), coords2D.c_str(), 580 builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2);
574 p4.c_str()); 581 builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3);
582 builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4);
583 builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5);
575 584
576 // Non-degenerate case (quadratic) 585 // If we we're able to interpolate the linear component,
577 if (!fIsDegenerate) { 586 // bVar is the varying; otherwise compute it
587 SkString bVar;
588 if (NULL != fFSVaryingName) {
589 bVar = fFSVaryingName;
590 } else {
591 bVar = "b";
592 builder->fsCodeAppendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n",
593 bVar.c_str(), p2.c_str(), coords2D.c_str(),
594 p3.c_str(), p5.c_str());
595 }
578 596
579 // ac4 = params[0] * c 597 // output will default to transparent black (we simply won't write anything
580 builder->fsCodeAppendf("\tfloat %s = %s * %s;\n", ac4Name.c_str(), p 0.c_str(), 598 // else to it if invalid, instead of discarding or returning prematurely)
581 cName.c_str()); 599 builder->fsCodeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", outputColor);
582 600
583 // d = b^2 - ac4 601 // c = (x^2)+(y^2) - params[4]
584 builder->fsCodeAppendf("\tfloat %s = %s * %s - %s;\n", dName.c_str() , 602 builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n", cName.c_str(),
585 bVar.c_str(), bVar.c_str(), ac4Name.c_str()); 603 coords2D.c_str(), coords2D.c_str(),
604 p4.c_str());
586 605
587 // only proceed if discriminant is >= 0 606 // Non-degenerate case (quadratic)
588 builder->fsCodeAppendf("\tif (%s >= 0.0) {\n", dName.c_str()); 607 if (!fIsDegenerate) {
589 608
590 // intermediate value we'll use to compute the roots 609 // ac4 = params[0] * c
591 // q = -0.5 * (b +/- sqrt(d)) 610 builder->fsCodeAppendf("\tfloat %s = %s * %s;\n", ac4Name.c_str(), p0.c_ str(),
592 builder->fsCodeAppendf("\t\tfloat %s = -0.5 * (%s + (%s < 0.0 ? -1.0 : 1.0)" 611 cName.c_str());
593 " * sqrt(%s));\n", qName.c_str(), bVar.c_str( ),
594 bVar.c_str(), dName.c_str());
595 612
596 // compute both roots 613 // d = b^2 - ac4
597 // r0 = q * params[1] 614 builder->fsCodeAppendf("\tfloat %s = %s * %s - %s;\n", dName.c_str(),
598 builder->fsCodeAppendf("\t\tfloat %s = %s * %s;\n", r0Name.c_str(), 615 bVar.c_str(), bVar.c_str(), ac4Name.c_str());
599 qName.c_str(), p1.c_str());
600 // r1 = c / q
601 builder->fsCodeAppendf("\t\tfloat %s = %s / %s;\n", r1Name.c_str(),
602 cName.c_str(), qName.c_str());
603 616
604 // Note: If there are two roots that both generate radius(t) > 0, th e 617 // only proceed if discriminant is >= 0
605 // Canvas spec says to choose the larger t. 618 builder->fsCodeAppendf("\tif (%s >= 0.0) {\n", dName.c_str());
606 619
607 // so we'll look at the larger one first: 620 // intermediate value we'll use to compute the roots
608 builder->fsCodeAppendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str( ), 621 // q = -0.5 * (b +/- sqrt(d))
609 r0Name.c_str(), r1Name.c_str()); 622 builder->fsCodeAppendf("\t\tfloat %s = -0.5 * (%s + (%s < 0.0 ? -1.0 : 1 .0)"
623 " * sqrt(%s));\n", qName.c_str(), bVar.c_str(),
624 bVar.c_str(), dName.c_str());
610 625
611 // if r(t) > 0, then we're done; t will be our x coordinate 626 // compute both roots
612 builder->fsCodeAppendf("\t\tif (%s * %s + %s > 0.0) {\n", tName.c_st r(), 627 // r0 = q * params[1]
613 p5.c_str(), p3.c_str()); 628 builder->fsCodeAppendf("\t\tfloat %s = %s * %s;\n", r0Name.c_str(),
629 qName.c_str(), p1.c_str());
630 // r1 = c / q
631 builder->fsCodeAppendf("\t\tfloat %s = %s / %s;\n", r1Name.c_str(),
632 cName.c_str(), qName.c_str());
614 633
615 builder->fsCodeAppend("\t\t"); 634 // Note: If there are two roots that both generate radius(t) > 0, the
616 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor , samplers); 635 // Canvas spec says to choose the larger t.
617 636
618 // otherwise, if r(t) for the larger root was <= 0, try the other ro ot 637 // so we'll look at the larger one first:
619 builder->fsCodeAppend("\t\t} else {\n"); 638 builder->fsCodeAppendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str(),
620 builder->fsCodeAppendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(), 639 r0Name.c_str(), r1Name.c_str());
621 r0Name.c_str(), r1Name.c_str());
622 640
623 // if r(t) > 0 for the smaller root, then t will be our x coordinate 641 // if r(t) > 0, then we're done; t will be our x coordinate
624 builder->fsCodeAppendf("\t\t\tif (%s * %s + %s > 0.0) {\n", 642 builder->fsCodeAppendf("\t\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
625 tName.c_str(), p5.c_str(), p3.c_str()); 643 p5.c_str(), p3.c_str());
626 644
627 builder->fsCodeAppend("\t\t\t"); 645 builder->fsCodeAppend("\t\t");
628 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor , samplers); 646 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, sa mplers);
629 647
630 // end if (r(t) > 0) for smaller root 648 // otherwise, if r(t) for the larger root was <= 0, try the other root
631 builder->fsCodeAppend("\t\t\t}\n"); 649 builder->fsCodeAppend("\t\t} else {\n");
632 // end if (r(t) > 0), else, for larger root 650 builder->fsCodeAppendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(),
633 builder->fsCodeAppend("\t\t}\n"); 651 r0Name.c_str(), r1Name.c_str());
634 // end if (discriminant >= 0)
635 builder->fsCodeAppend("\t}\n");
636 } else {
637 652
638 // linear case: t = -c/b 653 // if r(t) > 0 for the smaller root, then t will be our x coordinate
639 builder->fsCodeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(), 654 builder->fsCodeAppendf("\t\t\tif (%s * %s + %s > 0.0) {\n",
640 cName.c_str(), bVar.c_str()); 655 tName.c_str(), p5.c_str(), p3.c_str());
641 656
642 // if r(t) > 0, then t will be the x coordinate 657 builder->fsCodeAppend("\t\t\t");
643 builder->fsCodeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str( ), 658 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, sa mplers);
644 p5.c_str(), p3.c_str()); 659
645 builder->fsCodeAppend("\t"); 660 // end if (r(t) > 0) for smaller root
646 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor , samplers); 661 builder->fsCodeAppend("\t\t\t}\n");
647 builder->fsCodeAppend("\t}\n"); 662 // end if (r(t) > 0), else, for larger root
648 } 663 builder->fsCodeAppend("\t\t}\n");
664 // end if (discriminant >= 0)
665 builder->fsCodeAppend("\t}\n");
666 } else {
667
668 // linear case: t = -c/b
669 builder->fsCodeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(),
670 cName.c_str(), bVar.c_str());
671
672 // if r(t) > 0, then t will be the x coordinate
673 builder->fsCodeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
674 p5.c_str(), p3.c_str());
675 builder->fsCodeAppend("\t");
676 this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, sa mplers);
677 builder->fsCodeAppend("\t}\n");
649 } 678 }
650 } 679 }
651 680
652 void GrGLConical2Gradient::setData(const GrGLUniformManager& uman, 681 void GrGLConical2Gradient::setData(const GrGLUniformManager& uman,
653 const GrDrawEffect& drawEffect) { 682 const GrDrawEffect& drawEffect) {
654 INHERITED::setData(uman, drawEffect); 683 INHERITED::setData(uman, drawEffect);
655 const GrConical2Gradient& data = drawEffect.castEffect<GrConical2Gradient>() ; 684 const GrConical2Gradient& data = drawEffect.castEffect<GrConical2Gradient>() ;
656 SkASSERT(data.isDegenerate() == fIsDegenerate); 685 SkASSERT(data.isDegenerate() == fIsDegenerate);
657 SkScalar centerX1 = data.center(); 686 SkScalar centerX1 = data.center();
658 SkScalar radius0 = data.radius(); 687 SkScalar radius0 = data.radius();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 str->appendScalar(fCenter2.fY); 780 str->appendScalar(fCenter2.fY);
752 str->append(") radius2: "); 781 str->append(") radius2: ");
753 str->appendScalar(fRadius2); 782 str->appendScalar(fRadius2);
754 str->append(" "); 783 str->append(" ");
755 784
756 this->INHERITED::toString(str); 785 this->INHERITED::toString(str);
757 786
758 str->append(")"); 787 str->append(")");
759 } 788 }
760 #endif 789 #endif
OLDNEW
« no previous file with comments | « no previous file | src/effects/gradients/SkTwoPointRadialGradient.cpp » ('j') | src/gpu/GrAARectRenderer.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698