OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
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 "SkBlurMaskFilter.h" | 9 #include "SkBlurMaskFilter.h" |
10 #include "SkBlurMask.h" | 10 #include "SkBlurMask.h" |
11 #include "SkGpuBlurUtils.h" | 11 #include "SkGpuBlurUtils.h" |
12 #include "SkReadBuffer.h" | 12 #include "SkReadBuffer.h" |
13 #include "SkWriteBuffer.h" | 13 #include "SkWriteBuffer.h" |
14 #include "SkMaskFilter.h" | 14 #include "SkMaskFilter.h" |
15 #include "SkRRect.h" | 15 #include "SkRRect.h" |
16 #include "SkRTConf.h" | 16 #include "SkRTConf.h" |
17 #include "SkStringUtils.h" | 17 #include "SkStringUtils.h" |
18 #include "SkStrokeRec.h" | 18 #include "SkStrokeRec.h" |
19 | 19 |
20 #if SK_SUPPORT_GPU | 20 #if SK_SUPPORT_GPU |
21 #include "GrContext.h" | 21 #include "GrContext.h" |
22 #include "GrTexture.h" | 22 #include "GrTexture.h" |
23 #include "GrEffect.h" | 23 #include "GrProcessor.h" |
24 #include "gl/GrGLEffect.h" | 24 #include "gl/GrGLProcessor.h" |
25 #include "gl/builders/GrGLProgramBuilder.h" | 25 #include "gl/builders/GrGLProgramBuilder.h" |
26 #include "effects/GrSimpleTextureEffect.h" | 26 #include "effects/GrSimpleTextureEffect.h" |
27 #include "GrTBackendEffectFactory.h" | 27 #include "GrTBackendProcessorFactory.h" |
28 #include "SkGrPixelRef.h" | 28 #include "SkGrPixelRef.h" |
29 #include "SkDraw.h" | 29 #include "SkDraw.h" |
30 #endif | 30 #endif |
31 | 31 |
32 SkScalar SkBlurMaskFilter::ConvertRadiusToSigma(SkScalar radius) { | 32 SkScalar SkBlurMaskFilter::ConvertRadiusToSigma(SkScalar radius) { |
33 return SkBlurMask::ConvertRadiusToSigma(radius); | 33 return SkBlurMask::ConvertRadiusToSigma(radius); |
34 } | 34 } |
35 | 35 |
36 class SkBlurMaskFilterImpl : public SkMaskFilter { | 36 class SkBlurMaskFilterImpl : public SkMaskFilter { |
37 public: | 37 public: |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { | 547 void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { |
548 buffer.writeScalar(fSigma); | 548 buffer.writeScalar(fSigma); |
549 buffer.writeUInt(fBlurStyle); | 549 buffer.writeUInt(fBlurStyle); |
550 buffer.writeUInt(fBlurFlags); | 550 buffer.writeUInt(fBlurFlags); |
551 } | 551 } |
552 | 552 |
553 #if SK_SUPPORT_GPU | 553 #if SK_SUPPORT_GPU |
554 | 554 |
555 class GrGLRectBlurEffect; | 555 class GrGLRectBlurEffect; |
556 | 556 |
557 class GrRectBlurEffect : public GrEffect { | 557 class GrRectBlurEffect : public GrFragmentProcessor { |
558 public: | 558 public: |
559 virtual ~GrRectBlurEffect(); | 559 virtual ~GrRectBlurEffect(); |
560 | 560 |
561 static const char* Name() { return "RectBlur"; } | 561 static const char* Name() { return "RectBlur"; } |
562 | 562 |
563 typedef GrGLRectBlurEffect GLEffect; | 563 typedef GrGLRectBlurEffect GLProcessor; |
564 | 564 |
565 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 565 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR
IDE; |
566 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 566 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
567 | 567 |
568 /** | 568 /** |
569 * Create a simple filter effect with custom bicubic coefficients. | 569 * Create a simple filter effect with custom bicubic coefficients. |
570 */ | 570 */ |
571 static GrEffect* Create(GrContext *context, const SkRect& rect, float sigma)
{ | 571 static GrFragmentProcessor* Create(GrContext *context, const SkRect& rect, f
loat sigma) { |
572 GrTexture *blurProfileTexture = NULL; | 572 GrTexture *blurProfileTexture = NULL; |
573 int doubleProfileSize = SkScalarCeilToInt(12*sigma); | 573 int doubleProfileSize = SkScalarCeilToInt(12*sigma); |
574 | 574 |
575 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.heigh
t()) { | 575 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.heigh
t()) { |
576 // if the blur sigma is too large so the gaussian overlaps the whole | 576 // if the blur sigma is too large so the gaussian overlaps the whole |
577 // rect in either direction, fall back to CPU path for now. | 577 // rect in either direction, fall back to CPU path for now. |
578 | 578 |
579 return NULL; | 579 return NULL; |
580 } | 580 } |
581 | 581 |
582 bool createdBlurProfileTexture = CreateBlurProfileTexture(context, sigma
, &blurProfileTexture); | 582 bool createdBlurProfileTexture = CreateBlurProfileTexture(context, sigma
, &blurProfileTexture); |
583 SkAutoTUnref<GrTexture> hunref(blurProfileTexture); | 583 SkAutoTUnref<GrTexture> hunref(blurProfileTexture); |
584 if (!createdBlurProfileTexture) { | 584 if (!createdBlurProfileTexture) { |
585 return NULL; | 585 return NULL; |
586 } | 586 } |
587 return SkNEW_ARGS(GrRectBlurEffect, (rect, sigma, blurProfileTexture)); | 587 return SkNEW_ARGS(GrRectBlurEffect, (rect, sigma, blurProfileTexture)); |
588 } | 588 } |
589 | 589 |
590 const SkRect& getRect() const { return fRect; } | 590 const SkRect& getRect() const { return fRect; } |
591 float getSigma() const { return fSigma; } | 591 float getSigma() const { return fSigma; } |
592 | 592 |
593 private: | 593 private: |
594 GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blur_profile); | 594 GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blur_profile); |
595 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; | 595 virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; |
596 | 596 |
597 static bool CreateBlurProfileTexture(GrContext *context, float sigma, | 597 static bool CreateBlurProfileTexture(GrContext *context, float sigma, |
598 GrTexture **blurProfileTexture); | 598 GrTexture **blurProfileTexture); |
599 | 599 |
600 SkRect fRect; | 600 SkRect fRect; |
601 float fSigma; | 601 float fSigma; |
602 GrTextureAccess fBlurProfileAccess; | 602 GrTextureAccess fBlurProfileAccess; |
603 | 603 |
604 GR_DECLARE_EFFECT_TEST; | 604 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
605 | 605 |
606 typedef GrEffect INHERITED; | 606 typedef GrFragmentProcessor INHERITED; |
607 }; | 607 }; |
608 | 608 |
609 class GrGLRectBlurEffect : public GrGLEffect { | 609 class GrGLRectBlurEffect : public GrGLFragmentProcessor { |
610 public: | 610 public: |
611 GrGLRectBlurEffect(const GrBackendEffectFactory& factory, | 611 GrGLRectBlurEffect(const GrBackendProcessorFactory& factory, |
612 const GrEffect&); | 612 const GrProcessor&); |
613 virtual void emitCode(GrGLProgramBuilder*, | 613 virtual void emitCode(GrGLProgramBuilder*, |
614 const GrEffect&, | 614 const GrFragmentProcessor&, |
615 const GrEffectKey&, | 615 const GrProcessorKey&, |
616 const char* outputColor, | 616 const char* outputColor, |
617 const char* inputColor, | 617 const char* inputColor, |
618 const TransformedCoordsArray&, | 618 const TransformedCoordsArray&, |
619 const TextureSamplerArray&) SK_OVERRIDE; | 619 const TextureSamplerArray&) SK_OVERRIDE; |
620 | 620 |
621 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVER
RIDE; | 621 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O
VERRIDE; |
622 | 622 |
623 private: | 623 private: |
624 typedef GrGLProgramDataManager::UniformHandle UniformHandle; | 624 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
625 | 625 |
626 UniformHandle fProxyRectUniform; | 626 UniformHandle fProxyRectUniform; |
627 UniformHandle fProfileSizeUniform; | 627 UniformHandle fProfileSizeUniform; |
628 | 628 |
629 typedef GrGLEffect INHERITED; | 629 typedef GrGLFragmentProcessor INHERITED; |
630 }; | 630 }; |
631 | 631 |
632 | 632 |
633 | 633 |
634 GrGLRectBlurEffect::GrGLRectBlurEffect(const GrBackendEffectFactory& factory, co
nst GrEffect&) | 634 GrGLRectBlurEffect::GrGLRectBlurEffect(const GrBackendProcessorFactory& factory,
const GrProcessor&) |
635 : INHERITED(factory) { | 635 : INHERITED(factory) { |
636 } | 636 } |
637 | 637 |
638 void OutputRectBlurProfileLookup(GrGLFragmentShaderBuilder* fsBuilder, | 638 void OutputRectBlurProfileLookup(GrGLFragmentShaderBuilder* fsBuilder, |
639 const GrGLShaderBuilder::TextureSampler& sample
r, | 639 const GrGLShaderBuilder::TextureSampler& sample
r, |
640 const char *output, | 640 const char *output, |
641 const char *profileSize, const char *loc, | 641 const char *profileSize, const char *loc, |
642 const char *blurred_width, | 642 const char *blurred_width, |
643 const char *sharp_width) { | 643 const char *sharp_width) { |
644 fsBuilder->codeAppendf("\tfloat %s;\n", output); | 644 fsBuilder->codeAppendf("\tfloat %s;\n", output); |
645 fsBuilder->codeAppendf("\t\t{\n"); | 645 fsBuilder->codeAppendf("\t\t{\n"); |
646 fsBuilder->codeAppendf("\t\t\tfloat coord = (0.5 * (abs(2.0*%s - %s) - %s))/
%s;\n", | 646 fsBuilder->codeAppendf("\t\t\tfloat coord = (0.5 * (abs(2.0*%s - %s) - %s))/
%s;\n", |
647 loc, blurred_width, sharp_width, profileSize); | 647 loc, blurred_width, sharp_width, profileSize); |
648 fsBuilder->codeAppendf("\t\t\t%s = ", output); | 648 fsBuilder->codeAppendf("\t\t\t%s = ", output); |
649 fsBuilder->appendTextureLookup(sampler, "vec2(coord,0.5)"); | 649 fsBuilder->appendTextureLookup(sampler, "vec2(coord,0.5)"); |
650 fsBuilder->codeAppend(".a;\n"); | 650 fsBuilder->codeAppend(".a;\n"); |
651 fsBuilder->codeAppendf("\t\t}\n"); | 651 fsBuilder->codeAppendf("\t\t}\n"); |
652 } | 652 } |
653 | 653 |
654 void GrGLRectBlurEffect::emitCode(GrGLProgramBuilder* builder, | 654 void GrGLRectBlurEffect::emitCode(GrGLProgramBuilder* builder, |
655 const GrEffect&, | 655 const GrFragmentProcessor&, |
656 const GrEffectKey& key, | 656 const GrProcessorKey& key, |
657 const char* outputColor, | 657 const char* outputColor, |
658 const char* inputColor, | 658 const char* inputColor, |
659 const TransformedCoordsArray& coords, | 659 const TransformedCoordsArray& coords, |
660 const TextureSamplerArray& samplers) { | 660 const TextureSamplerArray& samplers) { |
661 | 661 |
662 const char *rectName; | 662 const char *rectName; |
663 const char *profileSizeName; | 663 const char *profileSizeName; |
664 | 664 |
665 fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 665 fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
666 kVec4f_GrSLType, | 666 kVec4f_GrSLType, |
(...skipping 22 matching lines...) Expand all Loading... |
689 fsBuilder->codeAppendf("\tvec2 wh = smallDims - vec2(center,center);\n"); | 689 fsBuilder->codeAppendf("\tvec2 wh = smallDims - vec2(center,center);\n"); |
690 | 690 |
691 OutputRectBlurProfileLookup(fsBuilder, samplers[0], "horiz_lookup", profileS
izeName, "translatedPos.x", "width", "wh.x"); | 691 OutputRectBlurProfileLookup(fsBuilder, samplers[0], "horiz_lookup", profileS
izeName, "translatedPos.x", "width", "wh.x"); |
692 OutputRectBlurProfileLookup(fsBuilder, samplers[0], "vert_lookup", profileSi
zeName, "translatedPos.y", "height", "wh.y"); | 692 OutputRectBlurProfileLookup(fsBuilder, samplers[0], "vert_lookup", profileSi
zeName, "translatedPos.y", "height", "wh.y"); |
693 | 693 |
694 fsBuilder->codeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n"); | 694 fsBuilder->codeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n"); |
695 fsBuilder->codeAppendf("\t%s = src * vec4(final);\n", outputColor ); | 695 fsBuilder->codeAppendf("\t%s = src * vec4(final);\n", outputColor ); |
696 } | 696 } |
697 | 697 |
698 void GrGLRectBlurEffect::setData(const GrGLProgramDataManager& pdman, | 698 void GrGLRectBlurEffect::setData(const GrGLProgramDataManager& pdman, |
699 const GrEffect& effect) { | 699 const GrProcessor& proc) { |
700 const GrRectBlurEffect& rbe = effect.cast<GrRectBlurEffect>(); | 700 const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>(); |
701 SkRect rect = rbe.getRect(); | 701 SkRect rect = rbe.getRect(); |
702 | 702 |
703 pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBot
tom); | 703 pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBot
tom); |
704 pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma())); | 704 pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma())); |
705 } | 705 } |
706 | 706 |
707 bool GrRectBlurEffect::CreateBlurProfileTexture(GrContext *context, float sigma, | 707 bool GrRectBlurEffect::CreateBlurProfileTexture(GrContext *context, float sigma, |
708 GrTexture **blurProfileTexture) { | 708 GrTexture **blurProfileTexture) { |
709 GrTextureParams params; | 709 GrTextureParams params; |
710 GrTextureDesc texDesc; | 710 GrTextureDesc texDesc; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 fRect(rect), | 749 fRect(rect), |
750 fSigma(sigma), | 750 fSigma(sigma), |
751 fBlurProfileAccess(blur_profile) { | 751 fBlurProfileAccess(blur_profile) { |
752 this->addTextureAccess(&fBlurProfileAccess); | 752 this->addTextureAccess(&fBlurProfileAccess); |
753 this->setWillReadFragmentPosition(); | 753 this->setWillReadFragmentPosition(); |
754 } | 754 } |
755 | 755 |
756 GrRectBlurEffect::~GrRectBlurEffect() { | 756 GrRectBlurEffect::~GrRectBlurEffect() { |
757 } | 757 } |
758 | 758 |
759 const GrBackendEffectFactory& GrRectBlurEffect::getFactory() const { | 759 const GrBackendFragmentProcessorFactory& GrRectBlurEffect::getFactory() const { |
760 return GrTBackendEffectFactory<GrRectBlurEffect>::getInstance(); | 760 return GrTBackendFragmentProcessorFactory<GrRectBlurEffect>::getInstance(); |
761 } | 761 } |
762 | 762 |
763 bool GrRectBlurEffect::onIsEqual(const GrEffect& sBase) const { | 763 bool GrRectBlurEffect::onIsEqual(const GrProcessor& sBase) const { |
764 const GrRectBlurEffect& s = sBase.cast<GrRectBlurEffect>(); | 764 const GrRectBlurEffect& s = sBase.cast<GrRectBlurEffect>(); |
765 return this->getSigma() == s.getSigma() && this->getRect() == s.getRect(); | 765 return this->getSigma() == s.getSigma() && this->getRect() == s.getRect(); |
766 } | 766 } |
767 | 767 |
768 void GrRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* vali
dFlags) const { | 768 void GrRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* vali
dFlags) const { |
769 *validFlags = 0; | 769 *validFlags = 0; |
770 return; | 770 return; |
771 } | 771 } |
772 | 772 |
773 GR_DEFINE_EFFECT_TEST(GrRectBlurEffect); | 773 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect); |
774 | 774 |
775 GrEffect* GrRectBlurEffect::TestCreate(SkRandom* random, | 775 GrFragmentProcessor* GrRectBlurEffect::TestCreate(SkRandom* random, |
776 GrContext* context, | 776 GrContext* context, |
777 const GrDrawTargetCaps&, | 777 const GrDrawTargetCaps&, |
778 GrTexture**) { | 778 GrTexture**) { |
779 float sigma = random->nextRangeF(3,8); | 779 float sigma = random->nextRangeF(3,8); |
780 float width = random->nextRangeF(200,300); | 780 float width = random->nextRangeF(200,300); |
781 float height = random->nextRangeF(200,300); | 781 float height = random->nextRangeF(200,300); |
782 return GrRectBlurEffect::Create(context, SkRect::MakeWH(width, height), sigm
a); | 782 return GrRectBlurEffect::Create(context, SkRect::MakeWH(width, height), sigm
a); |
783 } | 783 } |
784 | 784 |
785 | 785 |
786 bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context, | 786 bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context, |
787 GrPaint* grp, | 787 GrPaint* grp, |
788 const SkStrokeRec& strokeRec, | 788 const SkStrokeRec& strokeRec, |
(...skipping 10 matching lines...) Expand all Loading... |
799 if (!strokeRec.isFillStyle()) { | 799 if (!strokeRec.isFillStyle()) { |
800 return false; | 800 return false; |
801 } | 801 } |
802 | 802 |
803 SkMatrix ctm = context->getMatrix(); | 803 SkMatrix ctm = context->getMatrix(); |
804 SkScalar xformedSigma = this->computeXformedSigma(ctm); | 804 SkScalar xformedSigma = this->computeXformedSigma(ctm); |
805 | 805 |
806 int pad=SkScalarCeilToInt(6*xformedSigma)/2; | 806 int pad=SkScalarCeilToInt(6*xformedSigma)/2; |
807 rect.outset(SkIntToScalar(pad), SkIntToScalar(pad)); | 807 rect.outset(SkIntToScalar(pad), SkIntToScalar(pad)); |
808 | 808 |
809 SkAutoTUnref<GrEffect> effect(GrRectBlurEffect::Create(context, rect, xforme
dSigma)); | 809 SkAutoTUnref<GrFragmentProcessor> fp(GrRectBlurEffect::Create(context, rect,
xformedSigma)); |
810 if (!effect) { | 810 if (!fp) { |
811 return false; | 811 return false; |
812 } | 812 } |
813 | 813 |
814 GrContext::AutoMatrix am; | 814 GrContext::AutoMatrix am; |
815 if (!am.setIdentity(context, grp)) { | 815 if (!am.setIdentity(context, grp)) { |
816 return false; | 816 return false; |
817 } | 817 } |
818 | 818 |
819 grp->addCoverageEffect(effect); | 819 grp->addCoverageProcessor(fp); |
820 | 820 |
821 context->drawRect(*grp, rect); | 821 context->drawRect(*grp, rect); |
822 return true; | 822 return true; |
823 } | 823 } |
824 | 824 |
825 class GrGLRRectBlurEffect; | 825 class GrGLRRectBlurEffect; |
826 | 826 |
827 class GrRRectBlurEffect : public GrEffect { | 827 class GrRRectBlurEffect : public GrFragmentProcessor { |
828 public: | 828 public: |
829 | 829 |
830 static GrEffect* Create(GrContext* context, float sigma, const SkRRect&); | 830 static GrFragmentProcessor* Create(GrContext* context, float sigma, const Sk
RRect&); |
831 | 831 |
832 virtual ~GrRRectBlurEffect() {}; | 832 virtual ~GrRRectBlurEffect() {}; |
833 static const char* Name() { return "GrRRectBlur"; } | 833 static const char* Name() { return "GrRRectBlur"; } |
834 | 834 |
835 const SkRRect& getRRect() const { return fRRect; } | 835 const SkRRect& getRRect() const { return fRRect; } |
836 float getSigma() const { return fSigma; } | 836 float getSigma() const { return fSigma; } |
837 | 837 |
838 typedef GrGLRRectBlurEffect GLEffect; | 838 typedef GrGLRRectBlurEffect GLProcessor; |
839 | 839 |
840 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 840 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
841 | 841 |
842 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 842 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR
IDE; |
843 | 843 |
844 private: | 844 private: |
845 GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture); | 845 GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture); |
846 | 846 |
847 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; | 847 virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; |
848 | 848 |
849 SkRRect fRRect; | 849 SkRRect fRRect; |
850 float fSigma; | 850 float fSigma; |
851 GrTextureAccess fNinePatchAccess; | 851 GrTextureAccess fNinePatchAccess; |
852 | 852 |
853 GR_DECLARE_EFFECT_TEST; | 853 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
854 | 854 |
855 typedef GrEffect INHERITED; | 855 typedef GrFragmentProcessor INHERITED; |
856 }; | 856 }; |
857 | 857 |
858 | 858 |
859 GrEffect* GrRRectBlurEffect::Create(GrContext* context, float sigma, const SkRRe
ct& rrect) { | 859 GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma, |
| 860 const SkRRect& rrect) { |
860 if (!rrect.isSimpleCircular()) { | 861 if (!rrect.isSimpleCircular()) { |
861 return NULL; | 862 return NULL; |
862 } | 863 } |
863 | 864 |
864 // Make sure we can successfully ninepatch this rrect -- the blur sigma has
to be | 865 // Make sure we can successfully ninepatch this rrect -- the blur sigma has
to be |
865 // sufficiently small relative to both the size of the corner radius and the | 866 // sufficiently small relative to both the size of the corner radius and the |
866 // width (and height) of the rrect. | 867 // width (and height) of the rrect. |
867 | 868 |
868 unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f); | 869 unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f); |
869 unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x()); | 870 unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 return NULL; | 926 return NULL; |
926 } | 927 } |
927 | 928 |
928 return SkNEW_ARGS(GrRRectBlurEffect, (sigma, rrect, blurNinePatchTexture)); | 929 return SkNEW_ARGS(GrRRectBlurEffect, (sigma, rrect, blurNinePatchTexture)); |
929 } | 930 } |
930 | 931 |
931 void GrRRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* val
idFlags) const { | 932 void GrRRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* val
idFlags) const { |
932 *validFlags = 0; | 933 *validFlags = 0; |
933 } | 934 } |
934 | 935 |
935 const GrBackendEffectFactory& GrRRectBlurEffect::getFactory() const { | 936 const GrBackendFragmentProcessorFactory& GrRRectBlurEffect::getFactory() const { |
936 return GrTBackendEffectFactory<GrRRectBlurEffect>::getInstance(); | 937 return GrTBackendFragmentProcessorFactory<GrRRectBlurEffect>::getInstance(); |
937 } | 938 } |
938 | 939 |
939 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur
e *ninePatchTexture) | 940 GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTextur
e *ninePatchTexture) |
940 : fRRect(rrect), | 941 : fRRect(rrect), |
941 fSigma(sigma), | 942 fSigma(sigma), |
942 fNinePatchAccess(ninePatchTexture) { | 943 fNinePatchAccess(ninePatchTexture) { |
943 this->addTextureAccess(&fNinePatchAccess); | 944 this->addTextureAccess(&fNinePatchAccess); |
944 this->setWillReadFragmentPosition(); | 945 this->setWillReadFragmentPosition(); |
945 } | 946 } |
946 | 947 |
947 bool GrRRectBlurEffect::onIsEqual(const GrEffect& other) const { | 948 bool GrRRectBlurEffect::onIsEqual(const GrProcessor& other) const { |
948 const GrRRectBlurEffect& rrbe = other.cast<GrRRectBlurEffect>(); | 949 const GrRRectBlurEffect& rrbe = other.cast<GrRRectBlurEffect>(); |
949 return fRRect.getSimpleRadii().fX == rrbe.fRRect.getSimpleRadii().fX && fSig
ma == rrbe.fSigma; | 950 return fRRect.getSimpleRadii().fX == rrbe.fRRect.getSimpleRadii().fX && fSig
ma == rrbe.fSigma; |
950 } | 951 } |
951 | 952 |
952 ////////////////////////////////////////////////////////////////////////////// | 953 ////////////////////////////////////////////////////////////////////////////// |
953 | 954 |
954 GR_DEFINE_EFFECT_TEST(GrRRectBlurEffect); | 955 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect); |
955 | 956 |
956 GrEffect* GrRRectBlurEffect::TestCreate(SkRandom* random, | 957 GrFragmentProcessor* GrRRectBlurEffect::TestCreate(SkRandom* random, |
957 GrContext* context, | 958 GrContext* context, |
958 const GrDrawTargetCaps& caps, | 959 const GrDrawTargetCaps& caps, |
959 GrTexture*[]) { | 960 GrTexture*[]) { |
960 SkScalar w = random->nextRangeScalar(100.f, 1000.f); | 961 SkScalar w = random->nextRangeScalar(100.f, 1000.f); |
961 SkScalar h = random->nextRangeScalar(100.f, 1000.f); | 962 SkScalar h = random->nextRangeScalar(100.f, 1000.f); |
962 SkScalar r = random->nextRangeF(1.f, 9.f); | 963 SkScalar r = random->nextRangeF(1.f, 9.f); |
963 SkScalar sigma = random->nextRangeF(1.f,10.f); | 964 SkScalar sigma = random->nextRangeF(1.f,10.f); |
964 SkRRect rrect; | 965 SkRRect rrect; |
965 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); | 966 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); |
966 return GrRRectBlurEffect::Create(context, sigma, rrect); | 967 return GrRRectBlurEffect::Create(context, sigma, rrect); |
967 } | 968 } |
968 | 969 |
969 ////////////////////////////////////////////////////////////////////////////// | 970 ////////////////////////////////////////////////////////////////////////////// |
970 | 971 |
971 class GrGLRRectBlurEffect : public GrGLEffect { | 972 class GrGLRRectBlurEffect : public GrGLFragmentProcessor { |
972 public: | 973 public: |
973 GrGLRRectBlurEffect(const GrBackendEffectFactory&, const GrEffect&); | 974 GrGLRRectBlurEffect(const GrBackendProcessorFactory&, const GrProcessor&); |
974 | 975 |
975 virtual void emitCode(GrGLProgramBuilder* builder, | 976 virtual void emitCode(GrGLProgramBuilder*, |
976 const GrEffect& effect, | 977 const GrFragmentProcessor&, |
977 const GrEffectKey& key, | 978 const GrProcessorKey&, |
978 const char* outputColor, | 979 const char* outputColor, |
979 const char* inputColor, | 980 const char* inputColor, |
980 const TransformedCoordsArray&, | 981 const TransformedCoordsArray&, |
981 const TextureSamplerArray&) SK_OVERRIDE; | 982 const TextureSamplerArray&) SK_OVERRIDE; |
982 | 983 |
983 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVER
RIDE; | 984 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O
VERRIDE; |
984 | 985 |
985 private: | 986 private: |
986 GrGLProgramDataManager::UniformHandle fProxyRectUniform; | 987 GrGLProgramDataManager::UniformHandle fProxyRectUniform; |
987 GrGLProgramDataManager::UniformHandle fCornerRadiusUniform; | 988 GrGLProgramDataManager::UniformHandle fCornerRadiusUniform; |
988 GrGLProgramDataManager::UniformHandle fBlurRadiusUniform; | 989 GrGLProgramDataManager::UniformHandle fBlurRadiusUniform; |
989 typedef GrGLEffect INHERITED; | 990 typedef GrGLFragmentProcessor INHERITED; |
990 }; | 991 }; |
991 | 992 |
992 GrGLRRectBlurEffect::GrGLRRectBlurEffect(const GrBackendEffectFactory& factory, | 993 GrGLRRectBlurEffect::GrGLRRectBlurEffect(const GrBackendProcessorFactory& factor
y, |
993 const GrEffect& effect) | 994 const GrProcessor&) |
994 : INHERITED (factory) { | 995 : INHERITED (factory) { |
995 } | 996 } |
996 | 997 |
997 void GrGLRRectBlurEffect::emitCode(GrGLProgramBuilder* builder, | 998 void GrGLRRectBlurEffect::emitCode(GrGLProgramBuilder* builder, |
998 const GrEffect& effect, | 999 const GrFragmentProcessor&, |
999 const GrEffectKey& key, | 1000 const GrProcessorKey&, |
1000 const char* outputColor, | 1001 const char* outputColor, |
1001 const char* inputColor, | 1002 const char* inputColor, |
1002 const TransformedCoordsArray&, | 1003 const TransformedCoordsArray&, |
1003 const TextureSamplerArray& samplers) { | 1004 const TextureSamplerArray& samplers) { |
1004 const char *rectName; | 1005 const char *rectName; |
1005 const char *cornerRadiusName; | 1006 const char *cornerRadiusName; |
1006 const char *blurRadiusName; | 1007 const char *blurRadiusName; |
1007 | 1008 |
1008 // The proxy rect has left, top, right, and bottom edges correspond to | 1009 // The proxy rect has left, top, right, and bottom edges correspond to |
1009 // components x, y, z, and w, respectively. | 1010 // components x, y, z, and w, respectively. |
1010 | 1011 |
1011 fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 1012 fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
1012 kVec4f_GrSLType, | 1013 kVec4f_GrSLType, |
1013 "proxyRect", | 1014 "proxyRect", |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1045 | 1046 |
1046 fsBuilder->codeAppendf("\t\tvec2 proxyDims = vec2(2.0*threshold+1.0);\n"); | 1047 fsBuilder->codeAppendf("\t\tvec2 proxyDims = vec2(2.0*threshold+1.0);\n"); |
1047 fsBuilder->codeAppendf("\t\tvec2 texCoord = translatedFragPos / proxyDims;\n
"); | 1048 fsBuilder->codeAppendf("\t\tvec2 texCoord = translatedFragPos / proxyDims;\n
"); |
1048 | 1049 |
1049 fsBuilder->codeAppendf("\t%s = ", outputColor); | 1050 fsBuilder->codeAppendf("\t%s = ", outputColor); |
1050 fsBuilder->appendTextureLookupAndModulate(inputColor, samplers[0], "texCoord
"); | 1051 fsBuilder->appendTextureLookupAndModulate(inputColor, samplers[0], "texCoord
"); |
1051 fsBuilder->codeAppend(";\n"); | 1052 fsBuilder->codeAppend(";\n"); |
1052 } | 1053 } |
1053 | 1054 |
1054 void GrGLRRectBlurEffect::setData(const GrGLProgramDataManager& pdman, | 1055 void GrGLRRectBlurEffect::setData(const GrGLProgramDataManager& pdman, |
1055 const GrEffect& effect) { | 1056 const GrProcessor& proc) { |
1056 const GrRRectBlurEffect& brre = effect.cast<GrRRectBlurEffect>(); | 1057 const GrRRectBlurEffect& brre = proc.cast<GrRRectBlurEffect>(); |
1057 SkRRect rrect = brre.getRRect(); | 1058 SkRRect rrect = brre.getRRect(); |
1058 | 1059 |
1059 float blurRadius = 3.f*SkScalarCeilToScalar(brre.getSigma()-1/6.0f); | 1060 float blurRadius = 3.f*SkScalarCeilToScalar(brre.getSigma()-1/6.0f); |
1060 pdman.set1f(fBlurRadiusUniform, blurRadius); | 1061 pdman.set1f(fBlurRadiusUniform, blurRadius); |
1061 | 1062 |
1062 SkRect rect = rrect.getBounds(); | 1063 SkRect rect = rrect.getBounds(); |
1063 rect.outset(blurRadius, blurRadius); | 1064 rect.outset(blurRadius, blurRadius); |
1064 pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBot
tom); | 1065 pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBot
tom); |
1065 | 1066 |
1066 SkScalar radius = 0; | 1067 SkScalar radius = 0; |
(...skipping 14 matching lines...) Expand all Loading... |
1081 if (!strokeRec.isFillStyle()) { | 1082 if (!strokeRec.isFillStyle()) { |
1082 return false; | 1083 return false; |
1083 } | 1084 } |
1084 | 1085 |
1085 SkRect proxy_rect = rrect.rect(); | 1086 SkRect proxy_rect = rrect.rect(); |
1086 SkMatrix ctm = context->getMatrix(); | 1087 SkMatrix ctm = context->getMatrix(); |
1087 SkScalar xformedSigma = this->computeXformedSigma(ctm); | 1088 SkScalar xformedSigma = this->computeXformedSigma(ctm); |
1088 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f); | 1089 float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f); |
1089 proxy_rect.outset(extra, extra); | 1090 proxy_rect.outset(extra, extra); |
1090 | 1091 |
1091 SkAutoTUnref<GrEffect> effect(GrRRectBlurEffect::Create( | 1092 SkAutoTUnref<GrFragmentProcessor> fp(GrRRectBlurEffect::Create(context, xfor
medSigma, rrect)); |
1092 context, xformedSigma, rrect)); | 1093 if (!fp) { |
1093 if (!effect) { | |
1094 return false; | 1094 return false; |
1095 } | 1095 } |
1096 | 1096 |
1097 GrContext::AutoMatrix am; | 1097 GrContext::AutoMatrix am; |
1098 if (!am.setIdentity(context, grp)) { | 1098 if (!am.setIdentity(context, grp)) { |
1099 return false; | 1099 return false; |
1100 } | 1100 } |
1101 | 1101 |
1102 grp->addCoverageEffect(effect); | 1102 grp->addCoverageProcessor(fp); |
1103 | 1103 |
1104 context->drawRect(*grp, proxy_rect); | 1104 context->drawRect(*grp, proxy_rect); |
1105 return true; | 1105 return true; |
1106 } | 1106 } |
1107 | 1107 |
1108 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRect& srcBounds, | 1108 bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRect& srcBounds, |
1109 const SkIRect& clipBounds, | 1109 const SkIRect& clipBounds, |
1110 const SkMatrix& ctm, | 1110 const SkMatrix& ctm, |
1111 SkRect* maskRect) const { | 1111 SkRect* maskRect) const { |
1112 SkScalar xformedSigma = this->computeXformedSigma(ctm); | 1112 SkScalar xformedSigma = this->computeXformedSigma(ctm); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1165 return false; | 1165 return false; |
1166 } | 1166 } |
1167 | 1167 |
1168 if (!isNormalBlur) { | 1168 if (!isNormalBlur) { |
1169 context->setIdentityMatrix(); | 1169 context->setIdentityMatrix(); |
1170 GrPaint paint; | 1170 GrPaint paint; |
1171 SkMatrix matrix; | 1171 SkMatrix matrix; |
1172 matrix.setIDiv(src->width(), src->height()); | 1172 matrix.setIDiv(src->width(), src->height()); |
1173 // Blend pathTexture over blurTexture. | 1173 // Blend pathTexture over blurTexture. |
1174 GrContext::AutoRenderTarget art(context, (*result)->asRenderTarget()); | 1174 GrContext::AutoRenderTarget art(context, (*result)->asRenderTarget()); |
1175 paint.addColorEffect(GrSimpleTextureEffect::Create(src, matrix))->unref(
); | 1175 paint.addColorProcessor(GrSimpleTextureEffect::Create(src, matrix))->unr
ef(); |
1176 if (kInner_SkBlurStyle == fBlurStyle) { | 1176 if (kInner_SkBlurStyle == fBlurStyle) { |
1177 // inner: dst = dst * src | 1177 // inner: dst = dst * src |
1178 paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff); | 1178 paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff); |
1179 } else if (kSolid_SkBlurStyle == fBlurStyle) { | 1179 } else if (kSolid_SkBlurStyle == fBlurStyle) { |
1180 // solid: dst = src + dst - src * dst | 1180 // solid: dst = src + dst - src * dst |
1181 // = (1 - dst) * src + 1 * dst | 1181 // = (1 - dst) * src + 1 * dst |
1182 paint.setBlendFunc(kIDC_GrBlendCoeff, kOne_GrBlendCoeff); | 1182 paint.setBlendFunc(kIDC_GrBlendCoeff, kOne_GrBlendCoeff); |
1183 } else if (kOuter_SkBlurStyle == fBlurStyle) { | 1183 } else if (kOuter_SkBlurStyle == fBlurStyle) { |
1184 // outer: dst = dst * (1 - src) | 1184 // outer: dst = dst * (1 - src) |
1185 // = 0 * src + (1 - src) * dst | 1185 // = 0 * src + (1 - src) * dst |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1219 } else { | 1219 } else { |
1220 str->append("None"); | 1220 str->append("None"); |
1221 } | 1221 } |
1222 str->append("))"); | 1222 str->append("))"); |
1223 } | 1223 } |
1224 #endif | 1224 #endif |
1225 | 1225 |
1226 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1226 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
1227 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1227 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
1228 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1228 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |