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" |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
297 static SkCachedData* add_cached_rects(SkMask* mask, SkScalar sigma, SkBlurStyle style, | 297 static SkCachedData* add_cached_rects(SkMask* mask, SkScalar sigma, SkBlurStyle style, |
298 SkBlurQuality quality, const SkRect rects[ ], int count) { | 298 SkBlurQuality quality, const SkRect rects[ ], int count) { |
299 SkCachedData* cache = copy_mask_to_cacheddata(mask); | 299 SkCachedData* cache = copy_mask_to_cacheddata(mask); |
300 if (cache) { | 300 if (cache) { |
301 SkMaskCache::Add(sigma, style, quality, rects, count, *mask, cache); | 301 SkMaskCache::Add(sigma, style, quality, rects, count, *mask, cache); |
302 } | 302 } |
303 return cache; | 303 return cache; |
304 } | 304 } |
305 | 305 |
306 #ifdef SK_IGNORE_FAST_RRECT_BLUR | 306 #ifdef SK_IGNORE_FAST_RRECT_BLUR |
307 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , false, "Use the faster analytic blur approach for ninepatch rects" ); | 307 SK_CONF_DECLARE(bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect", false, "Use the faster analytic blur approach for ninepatch rects"); |
308 #else | 308 #else |
309 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , true, "Use the faster analytic blur approach for ninepatch round rects" ); | 309 SK_CONF_DECLARE(bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect", true, "Use the faster analytic blur approach for ninepatch round rects"); |
310 #endif | 310 #endif |
311 | 311 |
312 SkMaskFilter::FilterReturn | 312 SkMaskFilter::FilterReturn |
313 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma trix, | 313 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma trix, |
314 const SkIRect& clipBounds, | 314 const SkIRect& clipBounds, |
315 NinePatch* patch) const { | 315 NinePatch* patch) const { |
316 SkASSERT(patch != nullptr); | 316 SkASSERT(patch != nullptr); |
317 switch (rrect.getType()) { | 317 switch (rrect.getType()) { |
318 case SkRRect::kEmpty_Type: | 318 case SkRRect::kEmpty_Type: |
319 // Nothing to draw. | 319 // Nothing to draw. |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
437 | 437 |
438 patch->fMask.fBounds.offsetTo(0, 0); | 438 patch->fMask.fBounds.offsetTo(0, 0); |
439 patch->fOuterRect = dstM.fBounds; | 439 patch->fOuterRect = dstM.fBounds; |
440 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; | 440 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; |
441 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; | 441 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; |
442 SkASSERT(nullptr == patch->fCache); | 442 SkASSERT(nullptr == patch->fCache); |
443 patch->fCache = cache; // transfer ownership to patch | 443 patch->fCache = cache; // transfer ownership to patch |
444 return kTrue_FilterReturn; | 444 return kTrue_FilterReturn; |
445 } | 445 } |
446 | 446 |
447 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" ); | 447 SK_CONF_DECLARE(bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects"); |
448 | 448 |
449 SkMaskFilter::FilterReturn | 449 SkMaskFilter::FilterReturn |
450 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, | 450 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, |
451 const SkMatrix& matrix, | 451 const SkMatrix& matrix, |
452 const SkIRect& clipBounds, | 452 const SkIRect& clipBounds, |
453 NinePatch* patch) const { | 453 NinePatch* patch) const { |
454 if (count < 1 || count > 2) { | 454 if (count < 1 || count > 2) { |
455 return kUnimplemented_FilterReturn; | 455 return kUnimplemented_FilterReturn; |
456 } | 456 } |
457 | 457 |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
615 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.heigh t()) { | 615 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.heigh t()) { |
616 // if the blur sigma is too large so the gaussian overlaps the whole | 616 // if the blur sigma is too large so the gaussian overlaps the whole |
617 // rect in either direction, fall back to CPU path for now. | 617 // rect in either direction, fall back to CPU path for now. |
618 return nullptr; | 618 return nullptr; |
619 } | 619 } |
620 | 620 |
621 SkAutoTUnref<GrTexture> blurProfile(CreateBlurProfileTexture(textureProv ider, sigma)); | 621 SkAutoTUnref<GrTexture> blurProfile(CreateBlurProfileTexture(textureProv ider, sigma)); |
622 if (!blurProfile) { | 622 if (!blurProfile) { |
623 return nullptr; | 623 return nullptr; |
624 } | 624 } |
625 return new GrRectBlurEffect(rect, sigma, blurProfile); | 625 // in OpenGL ES, mediump floats have a minimum range of 2^14. If we have coordinates bigger |
626 // than that, the shader math will end up with infinities and result in the blur effect not | |
627 // working correctly. To avoid this, we switch into highp when the coord inates are too big. | |
628 // As 2^14 is the minimum range but the actual range can be bigger, we m ight end up | |
629 // switching to highp sooner than strictly necessary, but most devices t hat have a bigger | |
630 // range for mediump also have mediump being exactly the same as highp ( e.g. all non-OpenGL | |
631 // ES devices), and thus incur no additional penalty for the switch. | |
632 static const SkScalar kMAX_BLUR_COORD = SkIntToScalar(16000); | |
633 GrSLPrecision precision; | |
robertphillips
2015/10/19 15:17:54
Is this enough? Don't we also need to check for ne
| |
634 if (rect.top() > kMAX_BLUR_COORD || | |
635 rect.left() > kMAX_BLUR_COORD || | |
636 rect.bottom() > kMAX_BLUR_COORD || | |
637 rect.right() > kMAX_BLUR_COORD || | |
638 rect.width() > kMAX_BLUR_COORD || | |
639 rect.height() > kMAX_BLUR_COORD) { | |
640 precision = kHigh_GrSLPrecision; | |
641 } | |
642 else { | |
643 precision = kDefault_GrSLPrecision; | |
644 } | |
645 return new GrRectBlurEffect(rect, sigma, blurProfile, precision); | |
626 } | 646 } |
627 | 647 |
628 const SkRect& getRect() const { return fRect; } | 648 const SkRect& getRect() const { return fRect; } |
629 float getSigma() const { return fSigma; } | 649 float getSigma() const { return fSigma; } |
630 | 650 |
631 private: | 651 private: |
632 GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blurProfile); | 652 GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blurProfile, |
653 GrSLPrecision fPrecision); | |
633 | 654 |
634 GrGLFragmentProcessor* onCreateGLInstance() const override; | 655 GrGLFragmentProcessor* onCreateGLInstance() const override; |
635 | 656 |
636 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override; | 657 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override; |
637 | 658 |
638 bool onIsEqual(const GrFragmentProcessor&) const override; | 659 bool onIsEqual(const GrFragmentProcessor&) const override; |
639 | 660 |
640 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; | 661 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; |
641 | 662 |
642 static GrTexture* CreateBlurProfileTexture(GrTextureProvider*, float sigma); | 663 static GrTexture* CreateBlurProfileTexture(GrTextureProvider*, float sigma); |
643 | 664 |
644 SkRect fRect; | 665 SkRect fRect; |
645 float fSigma; | 666 float fSigma; |
646 GrTextureAccess fBlurProfileAccess; | 667 GrTextureAccess fBlurProfileAccess; |
668 GrSLPrecision fPrecision; | |
647 | 669 |
648 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 670 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
649 | 671 |
650 typedef GrFragmentProcessor INHERITED; | 672 typedef GrFragmentProcessor INHERITED; |
651 }; | 673 }; |
652 | 674 |
653 class GrGLRectBlurEffect : public GrGLFragmentProcessor { | 675 class GrGLRectBlurEffect : public GrGLFragmentProcessor { |
654 public: | 676 public: |
655 GrGLRectBlurEffect(const GrProcessor&) {} | 677 GrGLRectBlurEffect(const GrProcessor&, GrSLPrecision precision) |
678 : fPrecision(precision) { | |
679 } | |
656 void emitCode(EmitArgs&) override; | 680 void emitCode(EmitArgs&) override; |
657 | 681 |
682 static void GenKey(GrSLPrecision precision, GrProcessorKeyBuilder* b); | |
683 | |
658 protected: | 684 protected: |
659 void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override; | 685 void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override; |
660 | 686 |
661 private: | 687 private: |
662 typedef GrGLProgramDataManager::UniformHandle UniformHandle; | 688 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
663 | 689 |
664 UniformHandle fProxyRectUniform; | 690 UniformHandle fProxyRectUniform; |
665 UniformHandle fProfileSizeUniform; | 691 UniformHandle fProfileSizeUniform; |
692 GrSLPrecision fPrecision; | |
666 | 693 |
667 typedef GrGLFragmentProcessor INHERITED; | 694 typedef GrGLFragmentProcessor INHERITED; |
668 }; | 695 }; |
669 | 696 |
670 void OutputRectBlurProfileLookup(GrGLFragmentBuilder* fsBuilder, | 697 void OutputRectBlurProfileLookup(GrGLFragmentBuilder* fsBuilder, |
671 const GrGLShaderBuilder::TextureSampler& sample r, | 698 const GrGLShaderBuilder::TextureSampler& sample r, |
672 const char *output, | 699 const char *output, |
673 const char *profileSize, const char *loc, | 700 const char *profileSize, const char *loc, |
674 const char *blurred_width, | 701 const char *blurred_width, |
675 const char *sharp_width) { | 702 const char *sharp_width) { |
676 fsBuilder->codeAppendf("\tfloat %s;\n", output); | 703 fsBuilder->codeAppendf("float %s;", output); |
677 fsBuilder->codeAppendf("\t\t{\n"); | 704 fsBuilder->codeAppendf("{"); |
678 fsBuilder->codeAppendf("\t\t\tfloat coord = (0.5 * (abs(2.0*%s - %s) - %s))/ %s;\n", | 705 fsBuilder->codeAppendf("float coord = ((abs(%s - 0.5 * %s) - 0.5 * %s)) / %s ;", |
679 loc, blurred_width, sharp_width, profileSize); | 706 loc, blurred_width, sharp_width, profileSize); |
680 fsBuilder->codeAppendf("\t\t\t%s = ", output); | 707 fsBuilder->codeAppendf("%s = ", output); |
681 fsBuilder->appendTextureLookup(sampler, "vec2(coord,0.5)"); | 708 fsBuilder->appendTextureLookup(sampler, "vec2(coord,0.5)"); |
682 fsBuilder->codeAppend(".a;\n"); | 709 fsBuilder->codeAppend(".a;"); |
683 fsBuilder->codeAppendf("\t\t}\n"); | 710 fsBuilder->codeAppendf("}"); |
684 } | 711 } |
685 | 712 |
713 | |
714 void GrGLRectBlurEffect::GenKey(GrSLPrecision precision, GrProcessorKeyBuilder* b) { | |
715 b->add32(precision); | |
716 } | |
717 | |
718 | |
686 void GrGLRectBlurEffect::emitCode(EmitArgs& args) { | 719 void GrGLRectBlurEffect::emitCode(EmitArgs& args) { |
687 | 720 |
688 const char *rectName; | 721 const char *rectName; |
689 const char *profileSizeName; | 722 const char *profileSizeName; |
690 | 723 |
724 const char* precisionString = GrGLShaderVar::PrecisionString(fPrecision, kGL ES_GrGLStandard); | |
691 fProxyRectUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_ Visibility, | 725 fProxyRectUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_ Visibility, |
692 kVec4f_GrSLType, | 726 kVec4f_GrSLType, |
693 kDefault_GrSLPrecision, | 727 fPrecision, |
694 "proxyRect", | 728 "proxyRect", |
695 &rectName); | 729 &rectName); |
696 fProfileSizeUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragmen t_Visibility, | 730 fProfileSizeUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragmen t_Visibility, |
697 kFloat_GrSLType, | 731 kFloat_GrSLType, |
698 kDefault_GrSLPrecision, | 732 kDefault_GrSLPrecision, |
699 "profileSize", | 733 "profileSize", |
700 &profileSizeName); | 734 &profileSizeName); |
701 | 735 |
702 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); | 736 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
703 const char *fragmentPos = fsBuilder->fragmentPosition(); | 737 const char *fragmentPos = fsBuilder->fragmentPosition(); |
704 | 738 |
705 if (args.fInputColor) { | 739 if (args.fInputColor) { |
706 fsBuilder->codeAppendf("\tvec4 src=%s;\n", args.fInputColor); | 740 fsBuilder->codeAppendf("vec4 src=%s;", args.fInputColor); |
707 } else { | 741 } else { |
708 fsBuilder->codeAppendf("\tvec4 src=vec4(1)\n;"); | 742 fsBuilder->codeAppendf("vec4 src=vec4(1);"); |
709 } | 743 } |
710 | 744 |
711 fsBuilder->codeAppendf("\tvec2 translatedPos = %s.xy - %s.xy;\n", fragmentPo s, rectName ); | 745 fsBuilder->codeAppendf("%s vec2 translatedPos = %s.xy - %s.xy;", precisionSt ring, fragmentPos, |
712 fsBuilder->codeAppendf("\tfloat width = %s.z - %s.x;\n", rectName, rectName) ; | 746 rectName); |
713 fsBuilder->codeAppendf("\tfloat height = %s.w - %s.y;\n", rectName, rectName ); | 747 fsBuilder->codeAppendf("%s float width = %s.z - %s.x;", precisionString, rec tName, rectName); |
748 fsBuilder->codeAppendf("%s float height = %s.w - %s.y;", precisionString, re ctName, rectName); | |
714 | 749 |
715 fsBuilder->codeAppendf("\tvec2 smallDims = vec2(width - %s, height-%s);\n", profileSizeName, profileSizeName); | 750 fsBuilder->codeAppendf("%s vec2 smallDims = vec2(width - %s, height - %s);", precisionString, |
716 fsBuilder->codeAppendf("\tfloat center = 2.0 * floor(%s/2.0 + .25) - 1.0;\n" , profileSizeName); | 751 profileSizeName, profileSizeName); |
717 fsBuilder->codeAppendf("\tvec2 wh = smallDims - vec2(center,center);\n"); | 752 fsBuilder->codeAppendf("%s float center = 2.0 * floor(%s/2.0 + .25) - 1.0;", precisionString, |
753 profileSizeName); | |
754 fsBuilder->codeAppendf("%s vec2 wh = smallDims - vec2(center,center);", prec isionString); | |
718 | 755 |
719 OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "horiz_lookup", pr ofileSizeName, | 756 OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "horiz_lookup", pr ofileSizeName, |
720 "translatedPos.x", "width", "wh.x"); | 757 "translatedPos.x", "width", "wh.x"); |
721 OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "vert_lookup", pro fileSizeName, | 758 OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "vert_lookup", pro fileSizeName, |
722 "translatedPos.y", "height", "wh.y"); | 759 "translatedPos.y", "height", "wh.y"); |
723 | 760 |
724 fsBuilder->codeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n"); | 761 fsBuilder->codeAppendf("float final = horiz_lookup * vert_lookup;"); |
725 fsBuilder->codeAppendf("\t%s = src * final;\n", args.fOutputColor ); | 762 fsBuilder->codeAppendf("%s = src * final;", args.fOutputColor); |
726 } | 763 } |
727 | 764 |
728 void GrGLRectBlurEffect::onSetData(const GrGLProgramDataManager& pdman, | 765 void GrGLRectBlurEffect::onSetData(const GrGLProgramDataManager& pdman, |
729 const GrProcessor& proc) { | 766 const GrProcessor& proc) { |
730 const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>(); | 767 const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>(); |
731 SkRect rect = rbe.getRect(); | 768 SkRect rect = rbe.getRect(); |
732 | 769 |
733 pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBot tom); | 770 pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBot tom); |
734 pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma())); | 771 pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma())); |
735 } | 772 } |
(...skipping 21 matching lines...) Expand all Loading... | |
757 | 794 |
758 blurProfile = textureProvider->createTexture(texDesc, true, profile.get( ), 0); | 795 blurProfile = textureProvider->createTexture(texDesc, true, profile.get( ), 0); |
759 if (blurProfile) { | 796 if (blurProfile) { |
760 textureProvider->assignUniqueKeyToTexture(key, blurProfile); | 797 textureProvider->assignUniqueKeyToTexture(key, blurProfile); |
761 } | 798 } |
762 } | 799 } |
763 | 800 |
764 return blurProfile; | 801 return blurProfile; |
765 } | 802 } |
766 | 803 |
767 GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *b lurProfile) | 804 GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *b lurProfile, |
805 GrSLPrecision precision) | |
768 : fRect(rect) | 806 : fRect(rect) |
769 , fSigma(sigma) | 807 , fSigma(sigma) |
770 , fBlurProfileAccess(blurProfile) { | 808 , fBlurProfileAccess(blurProfile) |
809 , fPrecision(precision) { | |
771 this->initClassID<GrRectBlurEffect>(); | 810 this->initClassID<GrRectBlurEffect>(); |
772 this->addTextureAccess(&fBlurProfileAccess); | 811 this->addTextureAccess(&fBlurProfileAccess); |
773 this->setWillReadFragmentPosition(); | 812 this->setWillReadFragmentPosition(); |
774 } | 813 } |
775 | 814 |
776 void GrRectBlurEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, | 815 void GrRectBlurEffect::onGetGLProcessorKey(const GrGLSLCaps& caps, |
777 GrProcessorKeyBuilder* b) const { | 816 GrProcessorKeyBuilder* b) const { |
778 GrGLRectBlurEffect::GenKey(*this, caps, b); | 817 GrGLRectBlurEffect::GenKey(fPrecision, b); |
779 } | 818 } |
780 | 819 |
781 GrGLFragmentProcessor* GrRectBlurEffect::onCreateGLInstance() const { | 820 GrGLFragmentProcessor* GrRectBlurEffect::onCreateGLInstance() const { |
782 return new GrGLRectBlurEffect(*this); | 821 return new GrGLRectBlurEffect(*this, fPrecision); |
783 } | 822 } |
784 | 823 |
785 bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& sBase) const { | 824 bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& sBase) const { |
786 const GrRectBlurEffect& s = sBase.cast<GrRectBlurEffect>(); | 825 const GrRectBlurEffect& s = sBase.cast<GrRectBlurEffect>(); |
787 return this->getSigma() == s.getSigma() && this->getRect() == s.getRect(); | 826 return this->getSigma() == s.getSigma() && this->getRect() == s.getRect(); |
788 } | 827 } |
789 | 828 |
790 void GrRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { | 829 void GrRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { |
791 inout->mulByUnknownSingleComponent(); | 830 inout->mulByUnknownSingleComponent(); |
792 } | 831 } |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
933 | 972 |
934 memset(mask.fImage, 0, mask.computeTotalImageSize()); | 973 memset(mask.fImage, 0, mask.computeTotalImageSize()); |
935 | 974 |
936 SkRect smallRect; | 975 SkRect smallRect; |
937 smallRect.setWH(SkIntToScalar(smallRectSide), SkIntToScalar(smallRectSid e)); | 976 smallRect.setWH(SkIntToScalar(smallRectSide), SkIntToScalar(smallRectSid e)); |
938 | 977 |
939 SkRRect smallRRect; | 978 SkRRect smallRRect; |
940 smallRRect.setRectXY(smallRect, SkIntToScalar(cornerRadius), SkIntToScal ar(cornerRadius)); | 979 smallRRect.setRectXY(smallRect, SkIntToScalar(cornerRadius), SkIntToScal ar(cornerRadius)); |
941 | 980 |
942 SkPath path; | 981 SkPath path; |
943 path.addRRect( smallRRect ); | 982 path.addRRect(smallRRect); |
944 | 983 |
945 SkDraw::DrawToMask(path, &mask.fBounds, nullptr, nullptr, &mask, | 984 SkDraw::DrawToMask(path, &mask.fBounds, nullptr, nullptr, &mask, |
946 SkMask::kJustRenderImage_CreateMode, SkPaint::kFill_S tyle); | 985 SkMask::kJustRenderImage_CreateMode, SkPaint::kFill_S tyle); |
947 | 986 |
948 SkMask blurredMask; | 987 SkMask blurredMask; |
949 SkBlurMask::BoxBlur(&blurredMask, mask, sigma, kNormal_SkBlurStyle, kHig h_SkBlurQuality, | 988 SkBlurMask::BoxBlur(&blurredMask, mask, sigma, kNormal_SkBlurStyle, kHig h_SkBlurQuality, |
950 nullptr, true ); | 989 nullptr, true); |
951 | 990 |
952 unsigned int texSide = smallRectSide + 2*blurRadius; | 991 unsigned int texSide = smallRectSide + 2*blurRadius; |
953 GrSurfaceDesc texDesc; | 992 GrSurfaceDesc texDesc; |
954 texDesc.fWidth = texSide; | 993 texDesc.fWidth = texSide; |
955 texDesc.fHeight = texSide; | 994 texDesc.fHeight = texSide; |
956 texDesc.fConfig = kAlpha_8_GrPixelConfig; | 995 texDesc.fConfig = kAlpha_8_GrPixelConfig; |
957 | 996 |
958 blurNinePatchTexture.reset( | 997 blurNinePatchTexture.reset( |
959 texProvider->createTexture(texDesc, true, blurredMask.fImage, 0)); | 998 texProvider->createTexture(texDesc, true, blurredMask.fImage, 0)); |
960 SkMask::FreeImage(blurredMask.fImage); | 999 SkMask::FreeImage(blurredMask.fImage); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1038 kFloat_GrSLType, | 1077 kFloat_GrSLType, |
1039 kDefault_GrSLPrecision, | 1078 kDefault_GrSLPrecision, |
1040 "blurRadius", | 1079 "blurRadius", |
1041 &blurRadiusName); | 1080 &blurRadiusName); |
1042 | 1081 |
1043 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); | 1082 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
1044 const char* fragmentPos = fsBuilder->fragmentPosition(); | 1083 const char* fragmentPos = fsBuilder->fragmentPosition(); |
1045 | 1084 |
1046 // warp the fragment position to the appropriate part of the 9patch blur tex ture | 1085 // warp the fragment position to the appropriate part of the 9patch blur tex ture |
1047 | 1086 |
1048 fsBuilder->codeAppendf("\t\tvec2 rectCenter = (%s.xy + %s.zw)/2.0;\n", rectN ame, rectName); | 1087 fsBuilder->codeAppendf("vec2 rectCenter = (%s.xy + %s.zw)/2.0;", rectName, r ectName); |
1049 fsBuilder->codeAppendf("\t\tvec2 translatedFragPos = %s.xy - %s.xy;\n", frag mentPos, rectName); | 1088 fsBuilder->codeAppendf("vec2 translatedFragPos = %s.xy - %s.xy;", fragmentPo s, rectName); |
1050 fsBuilder->codeAppendf("\t\tfloat threshold = %s + 2.0*%s;\n", cornerRadiusN ame, blurRadiusName ); | 1089 fsBuilder->codeAppendf("float threshold = %s + 2.0*%s;", cornerRadiusName, b lurRadiusName); |
1051 fsBuilder->codeAppendf("\t\tvec2 middle = %s.zw - %s.xy - 2.0*threshold;\n", rectName, rectName ); | 1090 fsBuilder->codeAppendf("vec2 middle = %s.zw - %s.xy - 2.0*threshold;", rectN ame, rectName); |
1052 | 1091 |
1053 fsBuilder->codeAppendf("\t\tif (translatedFragPos.x >= threshold && translat edFragPos.x < (middle.x+threshold)) {\n" ); | 1092 fsBuilder->codeAppendf("if (translatedFragPos.x >= threshold && translatedFr agPos.x < (middle.x+threshold)) {"); |
1054 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x = threshold;\n"); | 1093 fsBuilder->codeAppendf("translatedFragPos.x = threshold;\n"); |
1055 fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.x >= (middle.x + th reshold)) {\n"); | 1094 fsBuilder->codeAppendf("} else if (translatedFragPos.x >= (middle.x + thresh old)) {"); |
1056 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x -= middle.x - 1.0;\n"); | 1095 fsBuilder->codeAppendf("translatedFragPos.x -= middle.x - 1.0;"); |
1057 fsBuilder->codeAppendf("\t\t}\n"); | 1096 fsBuilder->codeAppendf("}"); |
1058 | 1097 |
1059 fsBuilder->codeAppendf("\t\tif (translatedFragPos.y > threshold && translate dFragPos.y < (middle.y+threshold)) {\n" ); | 1098 fsBuilder->codeAppendf("if (translatedFragPos.y > threshold && translatedFra gPos.y < (middle.y+threshold)) {"); |
1060 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y = threshold;\n"); | 1099 fsBuilder->codeAppendf("translatedFragPos.y = threshold;"); |
1061 fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.y >= (middle.y + th reshold)) {\n"); | 1100 fsBuilder->codeAppendf("} else if (translatedFragPos.y >= (middle.y + thresh old)) {"); |
1062 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y -= middle.y - 1.0;\n"); | 1101 fsBuilder->codeAppendf("translatedFragPos.y -= middle.y - 1.0;"); |
1063 fsBuilder->codeAppendf("\t\t}\n"); | 1102 fsBuilder->codeAppendf("}"); |
1064 | 1103 |
1065 fsBuilder->codeAppendf("\t\tvec2 proxyDims = vec2(2.0*threshold+1.0);\n"); | 1104 fsBuilder->codeAppendf("vec2 proxyDims = vec2(2.0*threshold+1.0);"); |
1066 fsBuilder->codeAppendf("\t\tvec2 texCoord = translatedFragPos / proxyDims;\n "); | 1105 fsBuilder->codeAppendf("vec2 texCoord = translatedFragPos / proxyDims;"); |
1067 | 1106 |
1068 fsBuilder->codeAppendf("\t%s = ", args.fOutputColor); | 1107 fsBuilder->codeAppendf("%s = ", args.fOutputColor); |
1069 fsBuilder->appendTextureLookupAndModulate(args.fInputColor, args.fSamplers[0 ], "texCoord"); | 1108 fsBuilder->appendTextureLookupAndModulate(args.fInputColor, args.fSamplers[0 ], "texCoord"); |
1070 fsBuilder->codeAppend(";\n"); | 1109 fsBuilder->codeAppend(";"); |
1071 } | 1110 } |
1072 | 1111 |
1073 void GrGLRRectBlurEffect::onSetData(const GrGLProgramDataManager& pdman, | 1112 void GrGLRRectBlurEffect::onSetData(const GrGLProgramDataManager& pdman, |
1074 const GrProcessor& proc) { | 1113 const GrProcessor& proc) { |
1075 const GrRRectBlurEffect& brre = proc.cast<GrRRectBlurEffect>(); | 1114 const GrRRectBlurEffect& brre = proc.cast<GrRRectBlurEffect>(); |
1076 SkRRect rrect = brre.getRRect(); | 1115 SkRRect rrect = brre.getRRect(); |
1077 | 1116 |
1078 float blurRadius = 3.f*SkScalarCeilToScalar(brre.getSigma()-1/6.0f); | 1117 float blurRadius = 3.f*SkScalarCeilToScalar(brre.getSigma()-1/6.0f); |
1079 pdman.set1f(fBlurRadiusUniform, blurRadius); | 1118 pdman.set1f(fBlurRadiusUniform, blurRadius); |
1080 | 1119 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1257 } else { | 1296 } else { |
1258 str->append("None"); | 1297 str->append("None"); |
1259 } | 1298 } |
1260 str->append("))"); | 1299 str->append("))"); |
1261 } | 1300 } |
1262 #endif | 1301 #endif |
1263 | 1302 |
1264 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1303 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
1265 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1304 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
1266 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1305 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |