| 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 |