Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: src/effects/gradients/SkGradientShader.cpp

Issue 2256843004: Implement gradient simplification for 0,0,1 and 0,1,1 gradients (Closed) Base URL: https://skia.googlesource.com/skia.git@remove-expand-one-color-macro
Patch Set: Remove unnecessary include Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698