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 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 GrTextureAccess fBlurProfileAccess; | 657 GrTextureAccess fBlurProfileAccess; |
658 | 658 |
659 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 659 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
660 | 660 |
661 typedef GrFragmentProcessor INHERITED; | 661 typedef GrFragmentProcessor INHERITED; |
662 }; | 662 }; |
663 | 663 |
664 class GrGLRectBlurEffect : public GrGLFragmentProcessor { | 664 class GrGLRectBlurEffect : public GrGLFragmentProcessor { |
665 public: | 665 public: |
666 GrGLRectBlurEffect(const GrProcessor&) {} | 666 GrGLRectBlurEffect(const GrProcessor&) {} |
667 virtual void emitCode(GrGLFPBuilder*, | 667 virtual void emitCode(EmitArgs&) override; |
668 const GrFragmentProcessor&, | |
669 const char* outputColor, | |
670 const char* inputColor, | |
671 const TransformedCoordsArray&, | |
672 const TextureSamplerArray&) override; | |
673 | 668 |
674 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 669 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; |
675 | 670 |
676 private: | 671 private: |
677 typedef GrGLProgramDataManager::UniformHandle UniformHandle; | 672 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
678 | 673 |
679 UniformHandle fProxyRectUniform; | 674 UniformHandle fProxyRectUniform; |
680 UniformHandle fProfileSizeUniform; | 675 UniformHandle fProfileSizeUniform; |
681 | 676 |
682 typedef GrGLFragmentProcessor INHERITED; | 677 typedef GrGLFragmentProcessor INHERITED; |
683 }; | 678 }; |
684 | 679 |
685 void OutputRectBlurProfileLookup(GrGLFragmentBuilder* fsBuilder, | 680 void OutputRectBlurProfileLookup(GrGLFragmentBuilder* fsBuilder, |
686 const GrGLShaderBuilder::TextureSampler& sample
r, | 681 const GrGLShaderBuilder::TextureSampler& sample
r, |
687 const char *output, | 682 const char *output, |
688 const char *profileSize, const char *loc, | 683 const char *profileSize, const char *loc, |
689 const char *blurred_width, | 684 const char *blurred_width, |
690 const char *sharp_width) { | 685 const char *sharp_width) { |
691 fsBuilder->codeAppendf("\tfloat %s;\n", output); | 686 fsBuilder->codeAppendf("\tfloat %s;\n", output); |
692 fsBuilder->codeAppendf("\t\t{\n"); | 687 fsBuilder->codeAppendf("\t\t{\n"); |
693 fsBuilder->codeAppendf("\t\t\tfloat coord = (0.5 * (abs(2.0*%s - %s) - %s))/
%s;\n", | 688 fsBuilder->codeAppendf("\t\t\tfloat coord = (0.5 * (abs(2.0*%s - %s) - %s))/
%s;\n", |
694 loc, blurred_width, sharp_width, profileSize); | 689 loc, blurred_width, sharp_width, profileSize); |
695 fsBuilder->codeAppendf("\t\t\t%s = ", output); | 690 fsBuilder->codeAppendf("\t\t\t%s = ", output); |
696 fsBuilder->appendTextureLookup(sampler, "vec2(coord,0.5)"); | 691 fsBuilder->appendTextureLookup(sampler, "vec2(coord,0.5)"); |
697 fsBuilder->codeAppend(".a;\n"); | 692 fsBuilder->codeAppend(".a;\n"); |
698 fsBuilder->codeAppendf("\t\t}\n"); | 693 fsBuilder->codeAppendf("\t\t}\n"); |
699 } | 694 } |
700 | 695 |
701 void GrGLRectBlurEffect::emitCode(GrGLFPBuilder* builder, | 696 void GrGLRectBlurEffect::emitCode(EmitArgs& args) { |
702 const GrFragmentProcessor&, | |
703 const char* outputColor, | |
704 const char* inputColor, | |
705 const TransformedCoordsArray& coords, | |
706 const TextureSamplerArray& samplers) { | |
707 | 697 |
708 const char *rectName; | 698 const char *rectName; |
709 const char *profileSizeName; | 699 const char *profileSizeName; |
710 | 700 |
711 fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 701 fProxyRectUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_
Visibility, |
712 kVec4f_GrSLType, | 702 kVec4f_GrSLType, |
713 kDefault_GrSLPrecision, | 703 kDefault_GrSLPrecision, |
714 "proxyRect", | 704 "proxyRect", |
715 &rectName); | 705 &rectName); |
716 fProfileSizeUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visi
bility, | 706 fProfileSizeUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragmen
t_Visibility, |
717 kFloat_GrSLType, | 707 kFloat_GrSLType, |
718 kDefault_GrSLPrecision, | 708 kDefault_GrSLPrecision, |
719 "profileSize", | 709 "profileSize", |
720 &profileSizeName); | 710 &profileSizeName); |
721 | 711 |
722 GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | 712 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
723 const char *fragmentPos = fsBuilder->fragmentPosition(); | 713 const char *fragmentPos = fsBuilder->fragmentPosition(); |
724 | 714 |
725 if (inputColor) { | 715 if (args.fInputColor) { |
726 fsBuilder->codeAppendf("\tvec4 src=%s;\n", inputColor); | 716 fsBuilder->codeAppendf("\tvec4 src=%s;\n", args.fInputColor); |
727 } else { | 717 } else { |
728 fsBuilder->codeAppendf("\tvec4 src=vec4(1)\n;"); | 718 fsBuilder->codeAppendf("\tvec4 src=vec4(1)\n;"); |
729 } | 719 } |
730 | 720 |
731 fsBuilder->codeAppendf("\tvec2 translatedPos = %s.xy - %s.xy;\n", fragmentPo
s, rectName ); | 721 fsBuilder->codeAppendf("\tvec2 translatedPos = %s.xy - %s.xy;\n", fragmentPo
s, rectName ); |
732 fsBuilder->codeAppendf("\tfloat width = %s.z - %s.x;\n", rectName, rectName)
; | 722 fsBuilder->codeAppendf("\tfloat width = %s.z - %s.x;\n", rectName, rectName)
; |
733 fsBuilder->codeAppendf("\tfloat height = %s.w - %s.y;\n", rectName, rectName
); | 723 fsBuilder->codeAppendf("\tfloat height = %s.w - %s.y;\n", rectName, rectName
); |
734 | 724 |
735 fsBuilder->codeAppendf("\tvec2 smallDims = vec2(width - %s, height-%s);\n",
profileSizeName, profileSizeName); | 725 fsBuilder->codeAppendf("\tvec2 smallDims = vec2(width - %s, height-%s);\n",
profileSizeName, profileSizeName); |
736 fsBuilder->codeAppendf("\tfloat center = 2.0 * floor(%s/2.0 + .25) - 1.0;\n"
, profileSizeName); | 726 fsBuilder->codeAppendf("\tfloat center = 2.0 * floor(%s/2.0 + .25) - 1.0;\n"
, profileSizeName); |
737 fsBuilder->codeAppendf("\tvec2 wh = smallDims - vec2(center,center);\n"); | 727 fsBuilder->codeAppendf("\tvec2 wh = smallDims - vec2(center,center);\n"); |
738 | 728 |
739 OutputRectBlurProfileLookup(fsBuilder, samplers[0], "horiz_lookup", profileS
izeName, "translatedPos.x", "width", "wh.x"); | 729 OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "horiz_lookup", pr
ofileSizeName, |
740 OutputRectBlurProfileLookup(fsBuilder, samplers[0], "vert_lookup", profileSi
zeName, "translatedPos.y", "height", "wh.y"); | 730 "translatedPos.x", "width", "wh.x"); |
| 731 OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "vert_lookup", pro
fileSizeName, |
| 732 "translatedPos.y", "height", "wh.y"); |
741 | 733 |
742 fsBuilder->codeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n"); | 734 fsBuilder->codeAppendf("\tfloat final = horiz_lookup * vert_lookup;\n"); |
743 fsBuilder->codeAppendf("\t%s = src * final;\n", outputColor ); | 735 fsBuilder->codeAppendf("\t%s = src * final;\n", args.fOutputColor ); |
744 } | 736 } |
745 | 737 |
746 void GrGLRectBlurEffect::setData(const GrGLProgramDataManager& pdman, | 738 void GrGLRectBlurEffect::setData(const GrGLProgramDataManager& pdman, |
747 const GrProcessor& proc) { | 739 const GrProcessor& proc) { |
748 const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>(); | 740 const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>(); |
749 SkRect rect = rbe.getRect(); | 741 SkRect rect = rbe.getRect(); |
750 | 742 |
751 pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBot
tom); | 743 pdman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBot
tom); |
752 pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma())); | 744 pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma())); |
753 } | 745 } |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); | 1004 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); |
1013 return GrRRectBlurEffect::Create(d->fContext->textureProvider(), sigma, rrec
t); | 1005 return GrRRectBlurEffect::Create(d->fContext->textureProvider(), sigma, rrec
t); |
1014 } | 1006 } |
1015 | 1007 |
1016 ////////////////////////////////////////////////////////////////////////////// | 1008 ////////////////////////////////////////////////////////////////////////////// |
1017 | 1009 |
1018 class GrGLRRectBlurEffect : public GrGLFragmentProcessor { | 1010 class GrGLRRectBlurEffect : public GrGLFragmentProcessor { |
1019 public: | 1011 public: |
1020 GrGLRRectBlurEffect(const GrProcessor&) {} | 1012 GrGLRRectBlurEffect(const GrProcessor&) {} |
1021 | 1013 |
1022 virtual void emitCode(GrGLFPBuilder*, | 1014 virtual void emitCode(EmitArgs&) override; |
1023 const GrFragmentProcessor&, | |
1024 const char* outputColor, | |
1025 const char* inputColor, | |
1026 const TransformedCoordsArray&, | |
1027 const TextureSamplerArray&) override; | |
1028 | 1015 |
1029 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; | 1016 void setData(const GrGLProgramDataManager&, const GrProcessor&) override; |
1030 | 1017 |
1031 private: | 1018 private: |
1032 GrGLProgramDataManager::UniformHandle fProxyRectUniform; | 1019 GrGLProgramDataManager::UniformHandle fProxyRectUniform; |
1033 GrGLProgramDataManager::UniformHandle fCornerRadiusUniform; | 1020 GrGLProgramDataManager::UniformHandle fCornerRadiusUniform; |
1034 GrGLProgramDataManager::UniformHandle fBlurRadiusUniform; | 1021 GrGLProgramDataManager::UniformHandle fBlurRadiusUniform; |
1035 typedef GrGLFragmentProcessor INHERITED; | 1022 typedef GrGLFragmentProcessor INHERITED; |
1036 }; | 1023 }; |
1037 | 1024 |
1038 void GrGLRRectBlurEffect::emitCode(GrGLFPBuilder* builder, | 1025 void GrGLRRectBlurEffect::emitCode(EmitArgs& args) { |
1039 const GrFragmentProcessor&, | |
1040 const char* outputColor, | |
1041 const char* inputColor, | |
1042 const TransformedCoordsArray&, | |
1043 const TextureSamplerArray& samplers) { | |
1044 const char *rectName; | 1026 const char *rectName; |
1045 const char *cornerRadiusName; | 1027 const char *cornerRadiusName; |
1046 const char *blurRadiusName; | 1028 const char *blurRadiusName; |
1047 | 1029 |
1048 // The proxy rect has left, top, right, and bottom edges correspond to | 1030 // The proxy rect has left, top, right, and bottom edges correspond to |
1049 // components x, y, z, and w, respectively. | 1031 // components x, y, z, and w, respectively. |
1050 | 1032 |
1051 fProxyRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 1033 fProxyRectUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_
Visibility, |
1052 kVec4f_GrSLType, | 1034 kVec4f_GrSLType, |
1053 kDefault_GrSLPrecision, | 1035 kDefault_GrSLPrecision, |
1054 "proxyRect", | 1036 "proxyRect", |
1055 &rectName); | 1037 &rectName); |
1056 fCornerRadiusUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, | 1038 fCornerRadiusUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragme
nt_Visibility, |
1057 kFloat_GrSLType, | 1039 kFloat_GrSLType, |
1058 kDefault_GrSLPrecision, | 1040 kDefault_GrSLPrecision, |
1059 "cornerRadius", | 1041 "cornerRadius", |
1060 &cornerRadiusName); | 1042 &cornerRadiusName); |
1061 fBlurRadiusUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visib
ility, | 1043 fBlurRadiusUniform = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment
_Visibility, |
1062 kFloat_GrSLType, | 1044 kFloat_GrSLType, |
1063 kDefault_GrSLPrecision, | 1045 kDefault_GrSLPrecision, |
1064 "blurRadius", | 1046 "blurRadius", |
1065 &blurRadiusName); | 1047 &blurRadiusName); |
1066 | 1048 |
1067 GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | 1049 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
1068 const char* fragmentPos = fsBuilder->fragmentPosition(); | 1050 const char* fragmentPos = fsBuilder->fragmentPosition(); |
1069 | 1051 |
1070 // warp the fragment position to the appropriate part of the 9patch blur tex
ture | 1052 // warp the fragment position to the appropriate part of the 9patch blur tex
ture |
1071 | 1053 |
1072 fsBuilder->codeAppendf("\t\tvec2 rectCenter = (%s.xy + %s.zw)/2.0;\n", rectN
ame, rectName); | 1054 fsBuilder->codeAppendf("\t\tvec2 rectCenter = (%s.xy + %s.zw)/2.0;\n", rectN
ame, rectName); |
1073 fsBuilder->codeAppendf("\t\tvec2 translatedFragPos = %s.xy - %s.xy;\n", frag
mentPos, rectName); | 1055 fsBuilder->codeAppendf("\t\tvec2 translatedFragPos = %s.xy - %s.xy;\n", frag
mentPos, rectName); |
1074 fsBuilder->codeAppendf("\t\tfloat threshold = %s + 2.0*%s;\n", cornerRadiusN
ame, blurRadiusName ); | 1056 fsBuilder->codeAppendf("\t\tfloat threshold = %s + 2.0*%s;\n", cornerRadiusN
ame, blurRadiusName ); |
1075 fsBuilder->codeAppendf("\t\tvec2 middle = %s.zw - %s.xy - 2.0*threshold;\n",
rectName, rectName ); | 1057 fsBuilder->codeAppendf("\t\tvec2 middle = %s.zw - %s.xy - 2.0*threshold;\n",
rectName, rectName ); |
1076 | 1058 |
1077 fsBuilder->codeAppendf("\t\tif (translatedFragPos.x >= threshold && translat
edFragPos.x < (middle.x+threshold)) {\n" ); | 1059 fsBuilder->codeAppendf("\t\tif (translatedFragPos.x >= threshold && translat
edFragPos.x < (middle.x+threshold)) {\n" ); |
1078 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x = threshold;\n"); | 1060 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x = threshold;\n"); |
1079 fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.x >= (middle.x + th
reshold)) {\n"); | 1061 fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.x >= (middle.x + th
reshold)) {\n"); |
1080 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x -= middle.x - 1.0;\n"); | 1062 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.x -= middle.x - 1.0;\n"); |
1081 fsBuilder->codeAppendf("\t\t}\n"); | 1063 fsBuilder->codeAppendf("\t\t}\n"); |
1082 | 1064 |
1083 fsBuilder->codeAppendf("\t\tif (translatedFragPos.y > threshold && translate
dFragPos.y < (middle.y+threshold)) {\n" ); | 1065 fsBuilder->codeAppendf("\t\tif (translatedFragPos.y > threshold && translate
dFragPos.y < (middle.y+threshold)) {\n" ); |
1084 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y = threshold;\n"); | 1066 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y = threshold;\n"); |
1085 fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.y >= (middle.y + th
reshold)) {\n"); | 1067 fsBuilder->codeAppendf("\t\t} else if (translatedFragPos.y >= (middle.y + th
reshold)) {\n"); |
1086 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y -= middle.y - 1.0;\n"); | 1068 fsBuilder->codeAppendf("\t\t\ttranslatedFragPos.y -= middle.y - 1.0;\n"); |
1087 fsBuilder->codeAppendf("\t\t}\n"); | 1069 fsBuilder->codeAppendf("\t\t}\n"); |
1088 | 1070 |
1089 fsBuilder->codeAppendf("\t\tvec2 proxyDims = vec2(2.0*threshold+1.0);\n"); | 1071 fsBuilder->codeAppendf("\t\tvec2 proxyDims = vec2(2.0*threshold+1.0);\n"); |
1090 fsBuilder->codeAppendf("\t\tvec2 texCoord = translatedFragPos / proxyDims;\n
"); | 1072 fsBuilder->codeAppendf("\t\tvec2 texCoord = translatedFragPos / proxyDims;\n
"); |
1091 | 1073 |
1092 fsBuilder->codeAppendf("\t%s = ", outputColor); | 1074 fsBuilder->codeAppendf("\t%s = ", args.fOutputColor); |
1093 fsBuilder->appendTextureLookupAndModulate(inputColor, samplers[0], "texCoord
"); | 1075 fsBuilder->appendTextureLookupAndModulate(args.fInputColor, args.fSamplers[0
], "texCoord"); |
1094 fsBuilder->codeAppend(";\n"); | 1076 fsBuilder->codeAppend(";\n"); |
1095 } | 1077 } |
1096 | 1078 |
1097 void GrGLRRectBlurEffect::setData(const GrGLProgramDataManager& pdman, | 1079 void GrGLRRectBlurEffect::setData(const GrGLProgramDataManager& pdman, |
1098 const GrProcessor& proc) { | 1080 const GrProcessor& proc) { |
1099 const GrRRectBlurEffect& brre = proc.cast<GrRRectBlurEffect>(); | 1081 const GrRRectBlurEffect& brre = proc.cast<GrRRectBlurEffect>(); |
1100 SkRRect rrect = brre.getRRect(); | 1082 SkRRect rrect = brre.getRRect(); |
1101 | 1083 |
1102 float blurRadius = 3.f*SkScalarCeilToScalar(brre.getSigma()-1/6.0f); | 1084 float blurRadius = 3.f*SkScalarCeilToScalar(brre.getSigma()-1/6.0f); |
1103 pdman.set1f(fBlurRadiusUniform, blurRadius); | 1085 pdman.set1f(fBlurRadiusUniform, blurRadius); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 } else { | 1263 } else { |
1282 str->append("None"); | 1264 str->append("None"); |
1283 } | 1265 } |
1284 str->append("))"); | 1266 str->append("))"); |
1285 } | 1267 } |
1286 #endif | 1268 #endif |
1287 | 1269 |
1288 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1270 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
1289 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1271 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
1290 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1272 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |