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 "SkGradientShaderPriv.h" | 8 #include "SkGradientShaderPriv.h" |
9 #include "SkLinearGradient.h" | 9 #include "SkLinearGradient.h" |
10 #include "SkRadialGradient.h" | 10 #include "SkRadialGradient.h" |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 if (fColorCount > 2) { | 196 if (fColorCount > 2) { |
197 Rec* recs = fRecs; | 197 Rec* recs = fRecs; |
198 for (int i = 1; i < fColorCount; i++) { | 198 for (int i = 1; i < fColorCount; i++) { |
199 buffer.writeInt(recs[i].fPos); | 199 buffer.writeInt(recs[i].fPos); |
200 buffer.writeUInt(recs[i].fScale); | 200 buffer.writeUInt(recs[i].fScale); |
201 } | 201 } |
202 } | 202 } |
203 buffer.writeMatrix(fPtsToUnit); | 203 buffer.writeMatrix(fPtsToUnit); |
204 } | 204 } |
205 | 205 |
| 206 SkGradientShaderBase::ColorType SkGradientShaderBase::getGradientColorType(SkCol
or colors[3]) const { |
| 207 if (fColorCount <= 3) { |
| 208 memcpy(colors, fOrigColors, fColorCount * sizeof(SkColor)); |
| 209 } |
| 210 |
| 211 if (SkShader::kClamp_TileMode == fTileMode) { |
| 212 if (2 == fColorCount) { |
| 213 return kTwo_ColorType; |
| 214 } else if (3 == fColorCount && |
| 215 (SkScalarAbs( |
| 216 SkFixedToScalar(fRecs[1].fPos) - SK_ScalarHalf) < SK_Scalar1
/ 1000)) { |
| 217 return kThree_ColorType; |
| 218 } |
| 219 } |
| 220 return kTexture_ColorType; |
| 221 } |
| 222 |
206 bool SkGradientShaderBase::isOpaque() const { | 223 bool SkGradientShaderBase::isOpaque() const { |
207 return fColorsAreOpaque; | 224 return fColorsAreOpaque; |
208 } | 225 } |
209 | 226 |
210 SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext( | 227 SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext( |
211 const SkGradientShaderBase& shader, const SkBitmap& device, | 228 const SkGradientShaderBase& shader, const SkBitmap& device, |
212 const SkPaint& paint, const SkMatrix& matrix) | 229 const SkPaint& paint, const SkMatrix& matrix) |
213 : INHERITED(shader, device, paint, matrix) | 230 : INHERITED(shader, device, paint, matrix) |
214 , fCache(shader.refCache(getPaintAlpha())) | 231 , fCache(shader.refCache(getPaintAlpha())) |
215 { | 232 { |
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 | 851 |
835 GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory) | 852 GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory) |
836 : INHERITED(factory) | 853 : INHERITED(factory) |
837 , fCachedYCoord(SK_ScalarMax) { | 854 , fCachedYCoord(SK_ScalarMax) { |
838 } | 855 } |
839 | 856 |
840 GrGLGradientEffect::~GrGLGradientEffect() { } | 857 GrGLGradientEffect::~GrGLGradientEffect() { } |
841 | 858 |
842 void GrGLGradientEffect::emitUniforms(GrGLShaderBuilder* builder, EffectKey key)
{ | 859 void GrGLGradientEffect::emitUniforms(GrGLShaderBuilder* builder, EffectKey key)
{ |
843 | 860 |
844 if (GrGradientEffect::kTwo_ColorType == ColorTypeFromKey(key)) { // 2 Color
case | 861 if (SkGradientShaderBase::kTwo_ColorType == ColorTypeFromKey(key)) { // 2 Co
lor case |
845 fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibi
lity, | 862 fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibi
lity, |
846 kVec4f_GrSLType, "GradientStartColo
r"); | 863 kVec4f_GrSLType, "GradientStartColo
r"); |
847 fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibili
ty, | 864 fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibili
ty, |
848 kVec4f_GrSLType, "GradientEndColor"); | 865 kVec4f_GrSLType, "GradientEndColor"); |
849 | 866 |
850 } else if (GrGradientEffect::kThree_ColorType == ColorTypeFromKey(key)){ //
3 Color Case | 867 } else if (SkGradientShaderBase::kThree_ColorType == ColorTypeFromKey(key)){
// 3 Color Case |
851 fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibi
lity, | 868 fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibi
lity, |
852 kVec4f_GrSLType, "GradientStartColo
r"); | 869 kVec4f_GrSLType, "GradientStartColo
r"); |
853 fColorMidUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibili
ty, | 870 fColorMidUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibili
ty, |
854 kVec4f_GrSLType, "GradientMidColor"); | 871 kVec4f_GrSLType, "GradientMidColor"); |
855 fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibili
ty, | 872 fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibili
ty, |
856 kVec4f_GrSLType, "GradientEndColor"
); | 873 kVec4f_GrSLType, "GradientEndColor"
); |
857 | 874 |
858 } else { // if not a fast case | 875 } else { // if not a fast case |
859 fFSYUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | 876 fFSYUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
860 kFloat_GrSLType, "GradientYCoordFS"); | 877 kFloat_GrSLType, "GradientYCoordFS"); |
(...skipping 21 matching lines...) Expand all Loading... |
882 SkColorGetB(*color) * aDiv255, | 899 SkColorGetB(*color) * aDiv255, |
883 a); | 900 a); |
884 } | 901 } |
885 | 902 |
886 void GrGLGradientEffect::setData(const GrGLUniformManager& uman, | 903 void GrGLGradientEffect::setData(const GrGLUniformManager& uman, |
887 const GrDrawEffect& drawEffect) { | 904 const GrDrawEffect& drawEffect) { |
888 | 905 |
889 const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>(); | 906 const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>(); |
890 | 907 |
891 | 908 |
892 if (GrGradientEffect::kTwo_ColorType == e.getColorType()){ | 909 if (SkGradientShaderBase::kTwo_ColorType == e.getColorType()){ |
893 | 910 |
894 if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { | 911 if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { |
895 set_mul_color_uni(uman, fColorStartUni, e.getColors(0)); | 912 set_mul_color_uni(uman, fColorStartUni, e.getColors(0)); |
896 set_mul_color_uni(uman, fColorEndUni, e.getColors(1)); | 913 set_mul_color_uni(uman, fColorEndUni, e.getColors(1)); |
897 } else { | 914 } else { |
898 set_color_uni(uman, fColorStartUni, e.getColors(0)); | 915 set_color_uni(uman, fColorStartUni, e.getColors(0)); |
899 set_color_uni(uman, fColorEndUni, e.getColors(1)); | 916 set_color_uni(uman, fColorEndUni, e.getColors(1)); |
900 } | 917 } |
901 | 918 |
902 } else if (GrGradientEffect::kThree_ColorType == e.getColorType()){ | 919 } else if (SkGradientShaderBase::kThree_ColorType == e.getColorType()){ |
903 | 920 |
904 if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { | 921 if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { |
905 set_mul_color_uni(uman, fColorStartUni, e.getColors(0)); | 922 set_mul_color_uni(uman, fColorStartUni, e.getColors(0)); |
906 set_mul_color_uni(uman, fColorMidUni, e.getColors(1)); | 923 set_mul_color_uni(uman, fColorMidUni, e.getColors(1)); |
907 set_mul_color_uni(uman, fColorEndUni, e.getColors(2)); | 924 set_mul_color_uni(uman, fColorEndUni, e.getColors(2)); |
908 } else { | 925 } else { |
909 set_color_uni(uman, fColorStartUni, e.getColors(0)); | 926 set_color_uni(uman, fColorStartUni, e.getColors(0)); |
910 set_color_uni(uman, fColorMidUni, e.getColors(1)); | 927 set_color_uni(uman, fColorMidUni, e.getColors(1)); |
911 set_color_uni(uman, fColorEndUni, e.getColors(2)); | 928 set_color_uni(uman, fColorEndUni, e.getColors(2)); |
912 } | 929 } |
913 } else { | 930 } else { |
914 | 931 |
915 SkScalar yCoord = e.getYCoord(); | 932 SkScalar yCoord = e.getYCoord(); |
916 if (yCoord != fCachedYCoord) { | 933 if (yCoord != fCachedYCoord) { |
917 uman.set1f(fFSYUni, yCoord); | 934 uman.set1f(fFSYUni, yCoord); |
918 fCachedYCoord = yCoord; | 935 fCachedYCoord = yCoord; |
919 } | 936 } |
920 } | 937 } |
921 } | 938 } |
922 | 939 |
923 | 940 |
924 GrGLEffect::EffectKey GrGLGradientEffect::GenBaseGradientKey(const GrDrawEffect&
drawEffect) { | 941 GrGLEffect::EffectKey GrGLGradientEffect::GenBaseGradientKey(const GrDrawEffect&
drawEffect) { |
925 const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>(); | 942 const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>(); |
926 | 943 |
927 EffectKey key = 0; | 944 EffectKey key = 0; |
928 | 945 |
929 if (GrGradientEffect::kTwo_ColorType == e.getColorType()) { | 946 if (SkGradientShaderBase::kTwo_ColorType == e.getColorType()) { |
930 key |= kTwoColorKey; | 947 key |= kTwoColorKey; |
931 } else if (GrGradientEffect::kThree_ColorType == e.getColorType()){ | 948 } else if (SkGradientShaderBase::kThree_ColorType == e.getColorType()){ |
932 key |= kThreeColorKey; | 949 key |= kThreeColorKey; |
933 } | 950 } |
934 | 951 |
935 if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { | 952 if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { |
936 key |= kPremulBeforeInterpKey; | 953 key |= kPremulBeforeInterpKey; |
937 } | 954 } |
938 | 955 |
939 return key; | 956 return key; |
940 } | 957 } |
941 | 958 |
942 void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder, | 959 void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder, |
943 const char* gradientTValue, | 960 const char* gradientTValue, |
944 EffectKey key, | 961 EffectKey key, |
945 const char* outputColor, | 962 const char* outputColor, |
946 const char* inputColor, | 963 const char* inputColor, |
947 const TextureSamplerArray& samplers) { | 964 const TextureSamplerArray& samplers) { |
948 if (GrGradientEffect::kTwo_ColorType == ColorTypeFromKey(key)){ | 965 if (SkGradientShaderBase::kTwo_ColorType == ColorTypeFromKey(key)){ |
949 builder->fsCodeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.
0));\n", | 966 builder->fsCodeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.
0));\n", |
950 builder->getUniformVariable(fColorStartUni).c_str
(), | 967 builder->getUniformVariable(fColorStartUni).c_str
(), |
951 builder->getUniformVariable(fColorEndUni).c_str()
, | 968 builder->getUniformVariable(fColorEndUni).c_str()
, |
952 gradientTValue); | 969 gradientTValue); |
953 // Note that we could skip this step if both colors are known to be opaq
ue. Two | 970 // Note that we could skip this step if both colors are known to be opaq
ue. Two |
954 // considerations: | 971 // considerations: |
955 // The gradient SkShader reporting opaque is more restrictive than neces
sary in the two pt | 972 // The gradient SkShader reporting opaque is more restrictive than neces
sary in the two pt |
956 // case. Make sure the key reflects this optimization (and note that it
can use the same | 973 // case. Make sure the key reflects this optimization (and note that it
can use the same |
957 // shader as thekBeforeIterp case). This same optimization applies to th
e 3 color case below. | 974 // shader as thekBeforeIterp case). This same optimization applies to th
e 3 color case below. |
958 if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(key))
{ | 975 if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(key))
{ |
959 builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n"); | 976 builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n"); |
960 } | 977 } |
961 | 978 |
962 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, | 979 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, |
963 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp
")).c_str()); | 980 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp
")).c_str()); |
964 } else if (GrGradientEffect::kThree_ColorType == ColorTypeFromKey(key)){ | 981 } else if (SkGradientShaderBase::kThree_ColorType == ColorTypeFromKey(key)){ |
965 builder->fsCodeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n", | 982 builder->fsCodeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n", |
966 gradientTValue); | 983 gradientTValue); |
967 builder->fsCodeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) *
%s;\n", | 984 builder->fsCodeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) *
%s;\n", |
968 builder->getUniformVariable(fColorStartUni).c_str
()); | 985 builder->getUniformVariable(fColorStartUni).c_str
()); |
969 if (kTegra3_GrGLRenderer == builder->ctxInfo().renderer()) { | 986 if (kTegra3_GrGLRenderer == builder->ctxInfo().renderer()) { |
970 // The Tegra3 compiler will sometimes never return if we have | 987 // The Tegra3 compiler will sometimes never return if we have |
971 // min(abs(oneMinus2t), 1.0), or do the abs first in a separate expr
ession. | 988 // min(abs(oneMinus2t), 1.0), or do the abs first in a separate expr
ession. |
972 builder->fsCodeAppend("\tfloat minAbs = abs(oneMinus2t);\n"); | 989 builder->fsCodeAppend("\tfloat minAbs = abs(oneMinus2t);\n"); |
973 builder->fsCodeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n"); | 990 builder->fsCodeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n"); |
974 builder->fsCodeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n", | 991 builder->fsCodeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n", |
(...skipping 24 matching lines...) Expand all Loading... |
999 | 1016 |
1000 ///////////////////////////////////////////////////////////////////// | 1017 ///////////////////////////////////////////////////////////////////// |
1001 | 1018 |
1002 GrGradientEffect::GrGradientEffect(GrContext* ctx, | 1019 GrGradientEffect::GrGradientEffect(GrContext* ctx, |
1003 const SkGradientShaderBase& shader, | 1020 const SkGradientShaderBase& shader, |
1004 const SkMatrix& matrix, | 1021 const SkMatrix& matrix, |
1005 SkShader::TileMode tileMode) { | 1022 SkShader::TileMode tileMode) { |
1006 | 1023 |
1007 fIsOpaque = shader.isOpaque(); | 1024 fIsOpaque = shader.isOpaque(); |
1008 | 1025 |
1009 SkShader::GradientInfo info; | 1026 fColorType = shader.getGradientColorType(&fColors[0]); |
1010 SkScalar pos[3] = {0}; | |
1011 | |
1012 info.fColorCount = 3; | |
1013 info.fColors = &fColors[0]; | |
1014 info.fColorOffsets = &pos[0]; | |
1015 shader.asAGradient(&info); | |
1016 | 1027 |
1017 // The two and three color specializations do not currently support tiling. | 1028 // The two and three color specializations do not currently support tiling. |
1018 bool foundSpecialCase = false; | 1029 if (SkGradientShaderBase::kTwo_ColorType == fColorType || |
1019 if (SkShader::kClamp_TileMode == info.fTileMode) { | 1030 SkGradientShaderBase::kThree_ColorType == fColorType) { |
1020 if (2 == info.fColorCount) { | 1031 fRow = -1; |
1021 fRow = -1; // flag for no atlas | 1032 |
1022 fColorType = kTwo_ColorType; | 1033 if (SkGradientShader::kInterpolateColorsInPremul_Flag & shader.getGradie
ntFlags()) { |
1023 foundSpecialCase = true; | |
1024 } else if (3 == info.fColorCount && | |
1025 (SkScalarAbs(pos[1] - SK_ScalarHalf) < SK_Scalar1 / 1000)) {
// 3 color symmetric | |
1026 fRow = -1; // flag for no atlas | |
1027 fColorType = kThree_ColorType; | |
1028 foundSpecialCase = true; | |
1029 } | |
1030 } | |
1031 if (foundSpecialCase) { | |
1032 if (SkGradientShader::kInterpolateColorsInPremul_Flag & info.fGradientFl
ags) { | |
1033 fPremulType = kBeforeInterp_PremulType; | 1034 fPremulType = kBeforeInterp_PremulType; |
1034 } else { | 1035 } else { |
1035 fPremulType = kAfterInterp_PremulType; | 1036 fPremulType = kAfterInterp_PremulType; |
1036 } | 1037 } |
1037 fCoordTransform.reset(kCoordSet, matrix); | 1038 fCoordTransform.reset(kCoordSet, matrix); |
1038 } else { | 1039 } else { |
1039 // doesn't matter how this is set, just be consistent because it is part
of the effect key. | 1040 // doesn't matter how this is set, just be consistent because it is part
of the effect key. |
1040 fPremulType = kBeforeInterp_PremulType; | 1041 fPremulType = kBeforeInterp_PremulType; |
1041 SkBitmap bitmap; | 1042 SkBitmap bitmap; |
1042 shader.getGradientTableBitmap(&bitmap); | 1043 shader.getGradientTableBitmap(&bitmap); |
1043 fColorType = kTexture_ColorType; | |
1044 | 1044 |
1045 GrTextureStripAtlas::Desc desc; | 1045 GrTextureStripAtlas::Desc desc; |
1046 desc.fWidth = bitmap.width(); | 1046 desc.fWidth = bitmap.width(); |
1047 desc.fHeight = 32; | 1047 desc.fHeight = 32; |
1048 desc.fRowHeight = bitmap.height(); | 1048 desc.fRowHeight = bitmap.height(); |
1049 desc.fContext = ctx; | 1049 desc.fContext = ctx; |
1050 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.colorType(), bitmap.alph
aType()); | 1050 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.colorType(), bitmap.alph
aType()); |
1051 fAtlas = GrTextureStripAtlas::GetAtlas(desc); | 1051 fAtlas = GrTextureStripAtlas::GetAtlas(desc); |
1052 SkASSERT(NULL != fAtlas); | 1052 SkASSERT(NULL != fAtlas); |
1053 | 1053 |
(...skipping 28 matching lines...) Expand all Loading... |
1082 if (this->useAtlas()) { | 1082 if (this->useAtlas()) { |
1083 fAtlas->unlockRow(fRow); | 1083 fAtlas->unlockRow(fRow); |
1084 } | 1084 } |
1085 } | 1085 } |
1086 | 1086 |
1087 bool GrGradientEffect::onIsEqual(const GrEffect& effect) const { | 1087 bool GrGradientEffect::onIsEqual(const GrEffect& effect) const { |
1088 const GrGradientEffect& s = CastEffect<GrGradientEffect>(effect); | 1088 const GrGradientEffect& s = CastEffect<GrGradientEffect>(effect); |
1089 | 1089 |
1090 if (this->fColorType == s.getColorType()){ | 1090 if (this->fColorType == s.getColorType()){ |
1091 | 1091 |
1092 if (kTwo_ColorType == fColorType) { | 1092 if (SkGradientShaderBase::kTwo_ColorType == fColorType) { |
1093 if (*this->getColors(0) != *s.getColors(0) || | 1093 if (*this->getColors(0) != *s.getColors(0) || |
1094 *this->getColors(1) != *s.getColors(1)) { | 1094 *this->getColors(1) != *s.getColors(1)) { |
1095 return false; | 1095 return false; |
1096 } | 1096 } |
1097 } else if (kThree_ColorType == fColorType) { | 1097 } else if (SkGradientShaderBase::kThree_ColorType == fColorType) { |
1098 if (*this->getColors(0) != *s.getColors(0) || | 1098 if (*this->getColors(0) != *s.getColors(0) || |
1099 *this->getColors(1) != *s.getColors(1) || | 1099 *this->getColors(1) != *s.getColors(1) || |
1100 *this->getColors(2) != *s.getColors(2)) { | 1100 *this->getColors(2) != *s.getColors(2)) { |
1101 return false; | 1101 return false; |
1102 } | 1102 } |
1103 } else { | 1103 } else { |
1104 if (fYCoord != s.getYCoord()) { | 1104 if (fYCoord != s.getYCoord()) { |
1105 return false; | 1105 return false; |
1106 } | 1106 } |
1107 } | 1107 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 (*stops)[i] = stop; | 1142 (*stops)[i] = stop; |
1143 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st
op) : 1.f; | 1143 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st
op) : 1.f; |
1144 } | 1144 } |
1145 } | 1145 } |
1146 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM
odeCount)); | 1146 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM
odeCount)); |
1147 | 1147 |
1148 return outColors; | 1148 return outColors; |
1149 } | 1149 } |
1150 | 1150 |
1151 #endif | 1151 #endif |
OLD | NEW |