OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "Sk4fLinearGradient.h" | 8 #include "Sk4fLinearGradient.h" |
9 #include "SkGradientShaderPriv.h" | 9 #include "SkGradientShaderPriv.h" |
10 #include "SkLinearGradient.h" | 10 #include "SkLinearGradient.h" |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 SkColor tmp[2]; \ | 760 SkColor tmp[2]; \ |
761 do { \ | 761 do { \ |
762 if (1 == count) { \ | 762 if (1 == count) { \ |
763 tmp[0] = tmp[1] = colors[0]; \ | 763 tmp[0] = tmp[1] = colors[0]; \ |
764 colors = tmp; \ | 764 colors = tmp; \ |
765 pos = nullptr; \ | 765 pos = nullptr; \ |
766 count = 2; \ | 766 count = 2; \ |
767 } \ | 767 } \ |
768 } while (0) | 768 } while (0) |
769 | 769 |
| 770 struct ColorStopOptimizer { |
| 771 ColorStopOptimizer(const SkColor* colors, const SkScalar* pos, |
| 772 int count, SkShader::TileMode mode) |
| 773 : fColors(colors) |
| 774 , fPos(pos) |
| 775 , fCount(count) { |
| 776 |
| 777 if (!pos || count != 3) { |
| 778 return; |
| 779 } |
| 780 |
| 781 if (SkScalarNearlyEqual(pos[0], 0.0f) && |
| 782 SkScalarNearlyEqual(pos[1], 0.0f) && |
| 783 SkScalarNearlyEqual(pos[2], 1.0f)) { |
| 784 |
| 785 if (SkShader::kRepeat_TileMode == mode || |
| 786 SkShader::kMirror_TileMode == mode || |
| 787 colors[0] == colors[1]) { |
| 788 |
| 789 fColorStorage[0] = colors[1]; |
| 790 fColorStorage[1] = colors[2]; |
| 791 fPosStorage[0] = 0.0f; |
| 792 fPosStorage[1] = 1.0f; |
| 793 |
| 794 fColors = fColorStorage; |
| 795 fPos = fPosStorage; |
| 796 fCount = 2; |
| 797 } |
| 798 } else if (SkScalarNearlyEqual(pos[0], 0.0f) && |
| 799 SkScalarNearlyEqual(pos[1], 1.0f) && |
| 800 SkScalarNearlyEqual(pos[2], 1.0f)) { |
| 801 |
| 802 if (SkShader::kRepeat_TileMode == mode || |
| 803 SkShader::kMirror_TileMode == mode || |
| 804 colors[1] == colors[2]) { |
| 805 |
| 806 fCount = 2; |
| 807 } |
| 808 } |
| 809 } |
| 810 |
| 811 const SkColor* fColors; |
| 812 const SkScalar* fPos; |
| 813 int fCount; |
| 814 |
| 815 SkColor fColorStorage[2]; |
| 816 SkScalar fPosStorage[2]; |
| 817 }; |
| 818 |
770 sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2], | 819 sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2], |
771 const SkColor colors[], | 820 const SkColor colors[], |
772 const SkScalar pos[], int colorCount, | 821 const SkScalar pos[], int colorCoun
t, |
773 SkShader::TileMode mode, | 822 SkShader::TileMode mode, |
774 uint32_t flags, | 823 uint32_t flags, |
775 const SkMatrix* localMatrix) { | 824 const SkMatrix* localMatrix) { |
776 if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) { | 825 if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) { |
777 return nullptr; | 826 return nullptr; |
778 } | 827 } |
779 if (!valid_grad(colors, pos, colorCount, mode)) { | 828 if (!valid_grad(colors, pos, colorCount, mode)) { |
780 return nullptr; | 829 return nullptr; |
781 } | 830 } |
782 if (1 == colorCount) { | 831 if (1 == colorCount) { |
783 return SkShader::MakeColorShader(colors[0]); | 832 return SkShader::MakeColorShader(colors[0]); |
784 } | 833 } |
785 | 834 |
| 835 ColorStopOptimizer opt(colors, pos, colorCount, mode); |
| 836 |
786 SkGradientShaderBase::Descriptor desc; | 837 SkGradientShaderBase::Descriptor desc; |
787 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 838 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMatrix
); |
788 return sk_make_sp<SkLinearGradient>(pts, desc); | 839 return sk_make_sp<SkLinearGradient>(pts, desc); |
789 } | 840 } |
790 | 841 |
791 sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad
ius, | 842 sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad
ius, |
792 const SkColor colors[], | 843 const SkColor colors[], |
793 const SkScalar pos[], int colorCount, | 844 const SkScalar pos[], int colorCount, |
794 SkShader::TileMode mode, | 845 SkShader::TileMode mode, |
795 uint32_t flags, | 846 uint32_t flags, |
796 const SkMatrix* localMatrix) { | 847 const SkMatrix* localMatrix) { |
797 if (radius <= 0) { | 848 if (radius <= 0) { |
798 return nullptr; | 849 return nullptr; |
799 } | 850 } |
800 if (!valid_grad(colors, pos, colorCount, mode)) { | 851 if (!valid_grad(colors, pos, colorCount, mode)) { |
801 return nullptr; | 852 return nullptr; |
802 } | 853 } |
803 if (1 == colorCount) { | 854 if (1 == colorCount) { |
804 return SkShader::MakeColorShader(colors[0]); | 855 return SkShader::MakeColorShader(colors[0]); |
805 } | 856 } |
806 | 857 |
| 858 ColorStopOptimizer opt(colors, pos, colorCount, mode); |
| 859 |
807 SkGradientShaderBase::Descriptor desc; | 860 SkGradientShaderBase::Descriptor desc; |
808 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 861 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMatrix
); |
809 return sk_make_sp<SkRadialGradient>(center, radius, desc); | 862 return sk_make_sp<SkRadialGradient>(center, radius, desc); |
810 } | 863 } |
811 | 864 |
812 sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start, | 865 sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start, |
813 SkScalar startRadius, | 866 SkScalar startRadius, |
814 const SkPoint& end, | 867 const SkPoint& end, |
815 SkScalar endRadius, | 868 SkScalar endRadius, |
816 const SkColor colors[], | 869 const SkColor colors[], |
817 const SkScalar pos[], | 870 const SkScalar pos[], |
818 int colorCount, | 871 int colorCount, |
819 SkShader::TileMode mode, | 872 SkShader::TileMode mode, |
820 uint32_t flags, | 873 uint32_t flags, |
821 const SkMatrix* localMatrix) { | 874 const SkMatrix* localMatrix) { |
822 if (startRadius < 0 || endRadius < 0) { | 875 if (startRadius < 0 || endRadius < 0) { |
823 return nullptr; | 876 return nullptr; |
824 } | 877 } |
825 if (!valid_grad(colors, pos, colorCount, mode)) { | 878 if (!valid_grad(colors, pos, colorCount, mode)) { |
826 return nullptr; | 879 return nullptr; |
827 } | 880 } |
828 if (startRadius == endRadius) { | 881 if (startRadius == endRadius) { |
829 if (start == end || startRadius == 0) { | 882 if (start == end || startRadius == 0) { |
830 return SkShader::MakeEmptyShader(); | 883 return SkShader::MakeEmptyShader(); |
831 } | 884 } |
832 } | 885 } |
833 EXPAND_1_COLOR(colorCount); | 886 EXPAND_1_COLOR(colorCount); |
834 | 887 |
| 888 ColorStopOptimizer opt(colors, pos, colorCount, mode); |
| 889 |
835 bool flipGradient = startRadius > endRadius; | 890 bool flipGradient = startRadius > endRadius; |
836 | 891 |
837 SkGradientShaderBase::Descriptor desc; | 892 SkGradientShaderBase::Descriptor desc; |
838 | 893 |
839 if (!flipGradient) { | 894 if (!flipGradient) { |
840 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 895 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMa
trix); |
841 return sk_make_sp<SkTwoPointConicalGradient>(start, startRadius, end, en
dRadius, | 896 return sk_make_sp<SkTwoPointConicalGradient>(start, startRadius, end, en
dRadius, |
842 flipGradient, desc); | 897 flipGradient, desc); |
843 } else { | 898 } else { |
844 SkAutoSTArray<8, SkColor> colorsNew(colorCount); | 899 SkAutoSTArray<8, SkColor> colorsNew(colorCount); |
845 SkAutoSTArray<8, SkScalar> posNew(colorCount); | 900 SkAutoSTArray<8, SkScalar> posNew(colorCount); |
846 for (int i = 0; i < colorCount; ++i) { | 901 for (int i = 0; i < colorCount; ++i) { |
847 colorsNew[i] = colors[colorCount - i - 1]; | 902 colorsNew[i] = opt.fColors[colorCount - i - 1]; |
848 } | 903 } |
849 | 904 |
850 if (pos) { | 905 if (pos) { |
851 for (int i = 0; i < colorCount; ++i) { | 906 for (int i = 0; i < colorCount; ++i) { |
852 posNew[i] = 1 - pos[colorCount - i - 1]; | 907 posNew[i] = 1 - opt.fPos[colorCount - i - 1]; |
853 } | 908 } |
854 desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, fl
ags, localMatrix); | 909 desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, fl
ags, localMatrix); |
855 } else { | 910 } else { |
856 desc_init(&desc, colorsNew.get(), nullptr, colorCount, mode, flags,
localMatrix); | 911 desc_init(&desc, colorsNew.get(), nullptr, colorCount, mode, flags,
localMatrix); |
857 } | 912 } |
858 | 913 |
859 return sk_make_sp<SkTwoPointConicalGradient>(end, endRadius, start, star
tRadius, | 914 return sk_make_sp<SkTwoPointConicalGradient>(end, endRadius, start, star
tRadius, |
860 flipGradient, desc); | 915 flipGradient, desc); |
861 } | 916 } |
862 } | 917 } |
863 | 918 |
864 sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy, | 919 sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy, |
865 const SkColor colors[], | 920 const SkColor colors[], |
866 const SkScalar pos[], | 921 const SkScalar pos[], |
867 int colorCount, | 922 int colorCount, |
868 uint32_t flags, | 923 uint32_t flags, |
869 const SkMatrix* localMatrix) { | 924 const SkMatrix* localMatrix) { |
870 if (!valid_grad(colors, pos, colorCount, SkShader::kClamp_TileMode)) { | 925 if (!valid_grad(colors, pos, colorCount, SkShader::kClamp_TileMode)) { |
871 return nullptr; | 926 return nullptr; |
872 } | 927 } |
873 if (1 == colorCount) { | 928 if (1 == colorCount) { |
874 return SkShader::MakeColorShader(colors[0]); | 929 return SkShader::MakeColorShader(colors[0]); |
875 } | 930 } |
876 | 931 |
| 932 auto mode = SkShader::kClamp_TileMode; |
| 933 |
| 934 ColorStopOptimizer opt(colors, pos, colorCount, mode); |
| 935 |
877 SkGradientShaderBase::Descriptor desc; | 936 SkGradientShaderBase::Descriptor desc; |
878 desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, flags,
localMatrix); | 937 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMatrix
); |
879 return sk_make_sp<SkSweepGradient>(cx, cy, desc); | 938 return sk_make_sp<SkSweepGradient>(cx, cy, desc); |
880 } | 939 } |
881 | 940 |
882 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) | 941 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) |
883 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) | 942 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) |
884 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) | 943 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) |
885 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) | 944 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) |
886 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) | 945 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) |
887 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 946 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
888 | 947 |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1432 (*stops)[i] = stop; | 1491 (*stops)[i] = stop; |
1433 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st
op) : 1.f; | 1492 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st
op) : 1.f; |
1434 } | 1493 } |
1435 } | 1494 } |
1436 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM
odeCount)); | 1495 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM
odeCount)); |
1437 | 1496 |
1438 return outColors; | 1497 return outColors; |
1439 } | 1498 } |
1440 | 1499 |
1441 #endif | 1500 #endif |
OLD | NEW |