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