Chromium Code Reviews| 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 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 748 SkASSERT(colorCount > 1); | 748 SkASSERT(colorCount > 1); |
| 749 | 749 |
| 750 desc->fColors = colors; | 750 desc->fColors = colors; |
| 751 desc->fPos = pos; | 751 desc->fPos = pos; |
| 752 desc->fCount = colorCount; | 752 desc->fCount = colorCount; |
| 753 desc->fTileMode = mode; | 753 desc->fTileMode = mode; |
| 754 desc->fGradFlags = flags; | 754 desc->fGradFlags = flags; |
| 755 desc->fLocalMatrix = localMatrix; | 755 desc->fLocalMatrix = localMatrix; |
| 756 } | 756 } |
| 757 | 757 |
| 758 static int simplify(SkScalar* pos, SkColor* colors, int colorCount, SkShader::Ti leMode mode) { | |
| 759 if (pos) { | |
| 760 if (3 == colorCount) { | |
| 761 // Left-edged hard stop gradients (0, 0, 1) can be simplified | |
| 762 // to a 2-color gradient if first two colors are the same | |
| 763 if (SkScalarNearlyEqual(pos[0], 0.0f) && | |
| 764 SkScalarNearlyEqual(pos[1], 0.0f) && | |
| 765 SkScalarNearlyEqual(pos[2], 1.0f)) { | |
| 766 | |
| 767 // If the tile mode is repeat or mirror, first color | |
| 768 // doesn't matter | |
| 769 if (SkShader::kRepeat_TileMode == mode || | |
| 770 SkShader::kMirror_TileMode == mode || | |
| 771 colors[0] == colors[1]) { | |
| 772 | |
| 773 pos[0] = 0.0f; | |
| 774 pos[1] = 1.0f; | |
| 775 | |
| 776 colors[0] = colors[1]; | |
| 777 colors[1] = colors[2]; | |
| 778 | |
| 779 colorCount = 2; | |
|
f(malita)
2016/08/18 22:54:17
If we fall through here, I think we'll also take t
| |
| 780 } | |
| 781 } | |
| 782 | |
| 783 // Right-edged hard stop gradients (0, 1, 1) can be simplified | |
| 784 // to a 2-color gradient if last two colors are the same | |
| 785 if (SkScalarNearlyEqual(pos[0], 0.0f) && | |
| 786 SkScalarNearlyEqual(pos[1], 1.0f) && | |
| 787 SkScalarNearlyEqual(pos[2], 1.0f)) { | |
| 788 | |
| 789 // If the tile mode is repeat or mirror, last color | |
| 790 // doesn't matter | |
| 791 if (SkShader::kRepeat_TileMode == mode || | |
| 792 SkShader::kMirror_TileMode == mode || | |
| 793 colors[1] == colors[2]) { | |
| 794 | |
| 795 colorCount = 2; | |
| 796 } | |
| 797 } | |
| 798 } | |
| 799 } | |
| 800 return colorCount; | |
| 801 } | |
| 802 | |
| 758 sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2], | 803 sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2], |
| 759 const SkColor colors[], | 804 const SkColor colors[], |
| 760 const SkScalar pos[], int colorCount, | 805 const SkScalar pos[], int colorCoun t, |
| 761 SkShader::TileMode mode, | 806 SkShader::TileMode mode, |
| 762 uint32_t flags, | 807 uint32_t flags, |
| 763 const SkMatrix* localMatrix) { | 808 const SkMatrix* localMatrix) { |
| 764 if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) { | 809 if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) { |
| 765 return nullptr; | 810 return nullptr; |
| 766 } | 811 } |
| 767 if (!valid_grad(colors, pos, colorCount, mode)) { | 812 if (!valid_grad(colors, pos, colorCount, mode)) { |
| 768 return nullptr; | 813 return nullptr; |
| 769 } | 814 } |
| 770 if (1 == colorCount) { | 815 if (1 == colorCount) { |
| 771 return SkShader::MakeColorShader(colors[0]); | 816 return SkShader::MakeColorShader(colors[0]); |
| 772 } | 817 } |
| 773 | 818 |
| 819 SkAutoTArray<SkScalar> simplifiedPos(colorCount); | |
| 820 SkAutoTArray<SkColor> simplifiedCol(colorCount); | |
| 821 for (int i = 0; i < colorCount; i++) { | |
| 822 simplifiedCol[i] = colors[i]; | |
| 823 } | |
| 824 if (pos) { | |
| 825 for (int i = 0; i < colorCount; i++) { | |
| 826 simplifiedPos[i] = pos[i]; | |
| 827 } | |
| 828 colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCou nt, mode); | |
| 829 } else { | |
| 830 simplifiedPos.reset(0); | |
| 831 } | |
|
f(malita)
2016/08/18 22:54:17
It would be nice to
a) avoid these allocations an
| |
| 832 | |
| 774 SkGradientShaderBase::Descriptor desc; | 833 SkGradientShaderBase::Descriptor desc; |
| 775 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 834 desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, mode, flags, localMatrix); |
| 776 return sk_make_sp<SkLinearGradient>(pts, desc); | 835 return sk_make_sp<SkLinearGradient>(pts, desc); |
| 777 } | 836 } |
| 778 | 837 |
| 779 sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad ius, | 838 sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad ius, |
| 780 const SkColor colors[], | 839 const SkColor colors[], |
| 781 const SkScalar pos[], int colorCount, | 840 const SkScalar pos[], int colorCount, |
| 782 SkShader::TileMode mode, | 841 SkShader::TileMode mode, |
| 783 uint32_t flags, | 842 uint32_t flags, |
| 784 const SkMatrix* localMatrix) { | 843 const SkMatrix* localMatrix) { |
| 785 if (radius <= 0) { | 844 if (radius <= 0) { |
| 786 return nullptr; | 845 return nullptr; |
| 787 } | 846 } |
| 788 if (!valid_grad(colors, pos, colorCount, mode)) { | 847 if (!valid_grad(colors, pos, colorCount, mode)) { |
| 789 return nullptr; | 848 return nullptr; |
| 790 } | 849 } |
| 791 if (1 == colorCount) { | 850 if (1 == colorCount) { |
| 792 return SkShader::MakeColorShader(colors[0]); | 851 return SkShader::MakeColorShader(colors[0]); |
| 793 } | 852 } |
| 794 | 853 |
| 854 SkAutoTArray<SkScalar> simplifiedPos(colorCount); | |
| 855 SkAutoTArray<SkColor> simplifiedCol(colorCount); | |
| 856 for (int i = 0; i < colorCount; i++) { | |
| 857 simplifiedCol[i] = colors[i]; | |
| 858 } | |
| 859 if (pos) { | |
| 860 for (int i = 0; i < colorCount; i++) { | |
| 861 simplifiedPos[i] = pos[i]; | |
| 862 } | |
| 863 colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCou nt, mode); | |
| 864 } else { | |
| 865 simplifiedPos.reset(0); | |
| 866 } | |
| 867 | |
| 795 SkGradientShaderBase::Descriptor desc; | 868 SkGradientShaderBase::Descriptor desc; |
| 796 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 869 desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, mode, flags, localMatrix); |
| 797 return sk_make_sp<SkRadialGradient>(center, radius, desc); | 870 return sk_make_sp<SkRadialGradient>(center, radius, desc); |
| 798 } | 871 } |
| 799 | 872 |
| 800 sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start, | 873 sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start, |
| 801 SkScalar startRadius, | 874 SkScalar startRadius, |
| 802 const SkPoint& end, | 875 const SkPoint& end, |
| 803 SkScalar endRadius, | 876 SkScalar endRadius, |
| 804 const SkColor colors[], | 877 const SkColor colors[], |
| 805 const SkScalar pos[], | 878 const SkScalar pos[], |
| 806 int colorCount, | 879 int colorCount, |
| 807 SkShader::TileMode mode, | 880 SkShader::TileMode mode, |
| 808 uint32_t flags, | 881 uint32_t flags, |
| 809 const SkMatrix* localMatrix) { | 882 const SkMatrix* localMatrix) { |
| 810 if (startRadius < 0 || endRadius < 0) { | 883 if (startRadius < 0 || endRadius < 0) { |
| 811 return nullptr; | 884 return nullptr; |
| 812 } | 885 } |
| 813 if (!valid_grad(colors, pos, colorCount, mode)) { | 886 if (!valid_grad(colors, pos, colorCount, mode)) { |
| 814 return nullptr; | 887 return nullptr; |
| 815 } | 888 } |
| 816 if (startRadius == endRadius) { | 889 if (startRadius == endRadius) { |
| 817 if (start == end || startRadius == 0) { | 890 if (start == end || startRadius == 0) { |
| 818 return SkShader::MakeEmptyShader(); | 891 return SkShader::MakeEmptyShader(); |
| 819 } | 892 } |
| 820 } | 893 } |
| 821 if (1 == colorCount) { | 894 if (1 == colorCount) { |
| 822 return SkShader::MakeColorShader(colors[0]); | 895 return SkShader::MakeColorShader(colors[0]); |
| 823 } | 896 } |
| 824 | 897 |
| 898 SkAutoTArray<SkScalar> simplifiedPos(colorCount); | |
| 899 SkAutoTArray<SkColor> simplifiedCol(colorCount); | |
| 900 for (int i = 0; i < colorCount; i++) { | |
| 901 simplifiedCol[i] = colors[i]; | |
| 902 } | |
| 903 if (pos) { | |
| 904 for (int i = 0; i < colorCount; i++) { | |
| 905 simplifiedPos[i] = pos[i]; | |
| 906 } | |
| 907 colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCou nt, mode); | |
| 908 } else { | |
| 909 simplifiedPos.reset(0); | |
| 910 } | |
| 911 | |
| 825 bool flipGradient = startRadius > endRadius; | 912 bool flipGradient = startRadius > endRadius; |
| 826 | 913 |
| 827 SkGradientShaderBase::Descriptor desc; | 914 SkGradientShaderBase::Descriptor desc; |
| 828 | 915 |
| 829 if (!flipGradient) { | 916 if (!flipGradient) { |
| 830 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 917 desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, m ode, flags, localMatrix); |
| 831 return sk_make_sp<SkTwoPointConicalGradient>(start, startRadius, end, en dRadius, | 918 return sk_make_sp<SkTwoPointConicalGradient>(start, startRadius, end, en dRadius, |
| 832 flipGradient, desc); | 919 flipGradient, desc); |
| 833 } else { | 920 } else { |
| 834 SkAutoSTArray<8, SkColor> colorsNew(colorCount); | 921 SkAutoSTArray<8, SkColor> colorsNew(colorCount); |
| 835 SkAutoSTArray<8, SkScalar> posNew(colorCount); | 922 SkAutoSTArray<8, SkScalar> posNew(colorCount); |
| 836 for (int i = 0; i < colorCount; ++i) { | 923 for (int i = 0; i < colorCount; ++i) { |
| 837 colorsNew[i] = colors[colorCount - i - 1]; | 924 colorsNew[i] = simplifiedCol[colorCount - i - 1]; |
| 838 } | 925 } |
| 839 | 926 |
| 840 if (pos) { | 927 if (pos) { |
| 841 for (int i = 0; i < colorCount; ++i) { | 928 for (int i = 0; i < colorCount; ++i) { |
| 842 posNew[i] = 1 - pos[colorCount - i - 1]; | 929 posNew[i] = 1 - simplifiedPos[colorCount - i - 1]; |
| 843 } | 930 } |
| 844 desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, fl ags, localMatrix); | 931 desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, fl ags, localMatrix); |
| 845 } else { | 932 } else { |
| 846 desc_init(&desc, colorsNew.get(), nullptr, colorCount, mode, flags, localMatrix); | 933 desc_init(&desc, colorsNew.get(), nullptr, colorCount, mode, flags, localMatrix); |
| 847 } | 934 } |
| 848 | 935 |
| 849 return sk_make_sp<SkTwoPointConicalGradient>(end, endRadius, start, star tRadius, | 936 return sk_make_sp<SkTwoPointConicalGradient>(end, endRadius, start, star tRadius, |
| 850 flipGradient, desc); | 937 flipGradient, desc); |
| 851 } | 938 } |
| 852 } | 939 } |
| 853 | 940 |
| 854 sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy, | 941 sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy, |
| 855 const SkColor colors[], | 942 const SkColor colors[], |
| 856 const SkScalar pos[], | 943 const SkScalar pos[], |
| 857 int colorCount, | 944 int colorCount, |
| 858 uint32_t flags, | 945 uint32_t flags, |
| 859 const SkMatrix* localMatrix) { | 946 const SkMatrix* localMatrix) { |
| 860 if (!valid_grad(colors, pos, colorCount, SkShader::kClamp_TileMode)) { | 947 if (!valid_grad(colors, pos, colorCount, SkShader::kClamp_TileMode)) { |
| 861 return nullptr; | 948 return nullptr; |
| 862 } | 949 } |
| 863 if (1 == colorCount) { | 950 if (1 == colorCount) { |
| 864 return SkShader::MakeColorShader(colors[0]); | 951 return SkShader::MakeColorShader(colors[0]); |
| 865 } | 952 } |
| 866 | 953 |
| 954 SkAutoTArray<SkScalar> simplifiedPos(colorCount); | |
| 955 SkAutoTArray<SkColor> simplifiedCol(colorCount); | |
| 956 for (int i = 0; i < colorCount; i++) { | |
| 957 simplifiedCol[i] = colors[i]; | |
| 958 } | |
| 959 auto mode = SkShader::kClamp_TileMode; // Bogus tilemode | |
| 960 if (pos) { | |
| 961 for (int i = 0; i < colorCount; i++) { | |
| 962 simplifiedPos[i] = pos[i]; | |
| 963 } | |
| 964 colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCou nt, mode); | |
| 965 } else { | |
| 966 simplifiedPos.reset(0); | |
| 967 } | |
| 968 | |
| 867 SkGradientShaderBase::Descriptor desc; | 969 SkGradientShaderBase::Descriptor desc; |
| 868 desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, flags, localMatrix); | 970 desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, mode, flags, localMatrix); |
| 869 return sk_make_sp<SkSweepGradient>(cx, cy, desc); | 971 return sk_make_sp<SkSweepGradient>(cx, cy, desc); |
| 870 } | 972 } |
| 871 | 973 |
| 872 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) | 974 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) |
| 873 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) | 975 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) |
| 874 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) | 976 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) |
| 875 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) | 977 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) |
| 876 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) | 978 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) |
| 877 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 979 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| 878 | 980 |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1422 (*stops)[i] = stop; | 1524 (*stops)[i] = stop; |
| 1423 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; | 1525 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; |
| 1424 } | 1526 } |
| 1425 } | 1527 } |
| 1426 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); | 1528 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); |
| 1427 | 1529 |
| 1428 return outColors; | 1530 return outColors; |
| 1429 } | 1531 } |
| 1430 | 1532 |
| 1431 #endif | 1533 #endif |
| OLD | NEW |