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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 desc.fPos = fOrigPos; | 221 desc.fPos = fOrigPos; |
222 desc.fCount = fColorCount; | 222 desc.fCount = fColorCount; |
223 desc.fTileMode = fTileMode; | 223 desc.fTileMode = fTileMode; |
224 desc.fGradFlags = fGradFlags; | 224 desc.fGradFlags = fGradFlags; |
225 | 225 |
226 const SkMatrix& m = this->getLocalMatrix(); | 226 const SkMatrix& m = this->getLocalMatrix(); |
227 desc.fLocalMatrix = m.isIdentity() ? nullptr : &m; | 227 desc.fLocalMatrix = m.isIdentity() ? nullptr : &m; |
228 desc.flatten(buffer); | 228 desc.flatten(buffer); |
229 } | 229 } |
230 | 230 |
231 SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor
colors[3]) const { | |
232 if (fColorCount <= 3) { | |
233 memcpy(colors, fOrigColors, fColorCount * sizeof(SkColor)); | |
234 } | |
235 | |
236 if (SkShader::kClamp_TileMode == fTileMode) { | |
237 if (2 == fColorCount) { | |
238 return kTwo_GpuColorType; | |
239 } else if (3 == fColorCount && | |
240 (SkScalarAbs( | |
241 SkFixedToScalar(fRecs[1].fPos) - SK_ScalarHalf) < SK_Scalar1
/ 1000)) { | |
242 return kThree_GpuColorType; | |
243 } | |
244 } | |
245 return kTexture_GpuColorType; | |
246 } | |
247 | |
248 void SkGradientShaderBase::FlipGradientColors(SkColor* colorDst, Rec* recDst, | 231 void SkGradientShaderBase::FlipGradientColors(SkColor* colorDst, Rec* recDst, |
249 SkColor* colorSrc, Rec* recSrc, | 232 SkColor* colorSrc, Rec* recSrc, |
250 int count) { | 233 int count) { |
251 SkAutoSTArray<8, SkColor> colorsTemp(count); | 234 SkAutoSTArray<8, SkColor> colorsTemp(count); |
252 for (int i = 0; i < count; ++i) { | 235 for (int i = 0; i < count; ++i) { |
253 int offset = count - i - 1; | 236 int offset = count - i - 1; |
254 colorsTemp[i] = colorSrc[offset]; | 237 colorsTemp[i] = colorSrc[offset]; |
255 } | 238 } |
256 if (count > 2) { | 239 if (count > 2) { |
257 SkAutoSTArray<8, Rec> recsTemp(count); | 240 SkAutoSTArray<8, Rec> recsTemp(count); |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 | 887 |
905 #include "effects/GrTextureStripAtlas.h" | 888 #include "effects/GrTextureStripAtlas.h" |
906 #include "GrContext.h" | 889 #include "GrContext.h" |
907 #include "GrInvariantOutput.h" | 890 #include "GrInvariantOutput.h" |
908 #include "gl/GrGLContext.h" | 891 #include "gl/GrGLContext.h" |
909 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 892 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
910 #include "glsl/GrGLSLProgramDataManager.h" | 893 #include "glsl/GrGLSLProgramDataManager.h" |
911 #include "glsl/GrGLSLUniformHandler.h" | 894 #include "glsl/GrGLSLUniformHandler.h" |
912 #include "SkGr.h" | 895 #include "SkGr.h" |
913 | 896 |
914 GrGradientEffect::GLSLProcessor::GLSLProcessor() | 897 static inline bool close_to_one_half(const SkFixed& val) { |
915 : fCachedYCoord(SK_ScalarMax) { | 898 return SkScalarNearlyEqual(SkFixedToScalar(val), SK_ScalarHalf); |
| 899 } |
| 900 |
| 901 static inline int color_type_to_color_count(GrGradientEffect::ColorType colorTyp
e) { |
| 902 switch (colorType) { |
| 903 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
| 904 case GrGradientEffect::kHardStopCentered_ColorType: |
| 905 return 4; |
| 906 case GrGradientEffect::kHardStopLeftEdged_ColorType: |
| 907 case GrGradientEffect::kHardStopRightEdged_ColorType: |
| 908 return 3; |
| 909 #endif |
| 910 case GrGradientEffect::kTwo_ColorType: |
| 911 return 2; |
| 912 case GrGradientEffect::kThree_ColorType: |
| 913 return 3; |
| 914 case GrGradientEffect::kTexture_ColorType: |
| 915 return 0; |
| 916 } |
| 917 |
| 918 SkDEBUGFAIL("Unhandled ColorType in color_type_to_color_count()"); |
| 919 return -1; |
| 920 } |
| 921 |
| 922 GrGradientEffect::ColorType GrGradientEffect::determineColorType( |
| 923 const SkGradientShaderBase& shader) { |
| 924 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
| 925 if (shader.fOrigPos) { |
| 926 if (4 == shader.fColorCount) { |
| 927 if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) && |
| 928 SkScalarNearlyEqual(shader.fOrigPos[1], 0.5f) && |
| 929 SkScalarNearlyEqual(shader.fOrigPos[2], 0.5f) && |
| 930 SkScalarNearlyEqual(shader.fOrigPos[3], 1.0f)) { |
| 931 |
| 932 return kHardStopCentered_ColorType; |
| 933 } |
| 934 } else if (3 == shader.fColorCount) { |
| 935 if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) && |
| 936 SkScalarNearlyEqual(shader.fOrigPos[1], 0.0f) && |
| 937 SkScalarNearlyEqual(shader.fOrigPos[2], 1.0f)) { |
| 938 |
| 939 return kHardStopLeftEdged_ColorType; |
| 940 } else if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) && |
| 941 SkScalarNearlyEqual(shader.fOrigPos[1], 1.0f) && |
| 942 SkScalarNearlyEqual(shader.fOrigPos[2], 1.0f)) { |
| 943 |
| 944 return kHardStopRightEdged_ColorType; |
| 945 } |
| 946 } |
| 947 } |
| 948 #endif |
| 949 |
| 950 if (SkShader::kClamp_TileMode == shader.getTileMode()) { |
| 951 if (2 == shader.fColorCount) { |
| 952 return kTwo_ColorType; |
| 953 } else if (3 == shader.fColorCount && |
| 954 close_to_one_half(shader.getRecs()[1].fPos)) { |
| 955 return kThree_ColorType; |
| 956 } |
| 957 } |
| 958 |
| 959 return kTexture_ColorType; |
916 } | 960 } |
917 | 961 |
918 void GrGradientEffect::GLSLProcessor::emitUniforms(GrGLSLUniformHandler* uniform
Handler, | 962 void GrGradientEffect::GLSLProcessor::emitUniforms(GrGLSLUniformHandler* uniform
Handler, |
919 const GrGradientEffect& ge) { | 963 const GrGradientEffect& ge) { |
920 | 964 if (int colorCount = color_type_to_color_count(ge.getColorType())) { |
921 if (SkGradientShaderBase::kTwo_GpuColorType == ge.getColorType()) { // 2 Col
or case | 965 fColorsUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag, |
922 fColorStartUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 966 kVec4f_GrSLType, |
923 kVec4f_GrSLType, kDefault_Gr
SLPrecision, | 967 kDefault_GrSLPrecision, |
924 "GradientStartColor"); | 968 "Colors", |
925 fColorEndUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 969 colorCount); |
926 kVec4f_GrSLType, kDefault_GrSL
Precision, | 970 } else { |
927 "GradientEndColor"); | |
928 | |
929 } else if (SkGradientShaderBase::kThree_GpuColorType == ge.getColorType()) {
// 3 Color Case | |
930 fColorStartUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | |
931 kVec4f_GrSLType, kDefault_G
rSLPrecision, | |
932 "GradientStartColor"); | |
933 fColorMidUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | |
934 kVec4f_GrSLType, kDefault_GrSL
Precision, | |
935 "GradientMidColor"); | |
936 fColorEndUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | |
937 kVec4f_GrSLType, kDefault_GrSL
Precision, | |
938 "GradientEndColor"); | |
939 | |
940 } else { // if not a fast case | |
941 fFSYUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 971 fFSYUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
942 kFloat_GrSLType, kDefault_GrSLPreci
sion, | 972 kFloat_GrSLType, kDefault_GrSLPreci
sion, |
943 "GradientYCoordFS"); | 973 "GradientYCoordFS"); |
944 } | 974 } |
945 } | 975 } |
946 | 976 |
947 static inline void set_color_uni(const GrGLSLProgramDataManager& pdman, | 977 static inline void set_after_interp_color_uni_array(const GrGLSLProgramDataManag
er& pdman, |
948 const GrGLSLProgramDataManager::UniformHandle u
ni, | 978 const GrGLSLProgramDataManager::UniformHa
ndle uni, |
949 const SkColor* color) { | 979 const SkTDArray<SkColor>& colors) { |
950 pdman.set4f(uni, | 980 int count = colors.count(); |
951 SkColorGetR(*color) / 255.f, | 981 constexpr int kSmallCount = 10; |
952 SkColorGetG(*color) / 255.f, | 982 |
953 SkColorGetB(*color) / 255.f, | 983 SkAutoSTArray<4*kSmallCount, float> vals(4*count); |
954 SkColorGetA(*color) / 255.f); | 984 |
| 985 for (int i = 0; i < colors.count(); i++) { |
| 986 // RGBA |
| 987 vals[4*i + 0] = SkColorGetR(colors[i]) / 255.f; |
| 988 vals[4*i + 1] = SkColorGetG(colors[i]) / 255.f; |
| 989 vals[4*i + 2] = SkColorGetB(colors[i]) / 255.f; |
| 990 vals[4*i + 3] = SkColorGetA(colors[i]) / 255.f; |
| 991 } |
| 992 |
| 993 pdman.set4fv(uni, colors.count(), vals.get()); |
955 } | 994 } |
956 | 995 |
957 static inline void set_mul_color_uni(const GrGLSLProgramDataManager& pdman, | 996 static inline void set_before_interp_color_uni_array(const GrGLSLProgramDataMana
ger& pdman, |
958 const GrGLSLProgramDataManager::UniformHand
le uni, | 997 const GrGLSLProgramDataManager::Un
iformHandle uni, |
959 const SkColor* color){ | 998 const SkTDArray<SkColor>& colors)
{ |
960 float a = SkColorGetA(*color) / 255.f; | 999 int count = colors.count(); |
961 float aDiv255 = a / 255.f; | 1000 constexpr int kSmallCount = 10; |
962 pdman.set4f(uni, | 1001 |
963 SkColorGetR(*color) * aDiv255, | 1002 SkAutoSTArray<4*kSmallCount, float> vals(4*count); |
964 SkColorGetG(*color) * aDiv255, | 1003 |
965 SkColorGetB(*color) * aDiv255, | 1004 for (int i = 0; i < count; i++) { |
966 a); | 1005 float a = SkColorGetA(colors[i]) / 255.f; |
| 1006 float aDiv255 = a / 255.f; |
| 1007 |
| 1008 // RGBA |
| 1009 vals[4*i + 0] = SkColorGetR(colors[i]) * aDiv255; |
| 1010 vals[4*i + 1] = SkColorGetG(colors[i]) * aDiv255; |
| 1011 vals[4*i + 2] = SkColorGetB(colors[i]) * aDiv255; |
| 1012 vals[4*i + 3] = a; |
| 1013 } |
| 1014 |
| 1015 pdman.set4fv(uni, count, vals.get()); |
967 } | 1016 } |
968 | 1017 |
969 void GrGradientEffect::GLSLProcessor::onSetData(const GrGLSLProgramDataManager&
pdman, | 1018 void GrGradientEffect::GLSLProcessor::onSetData(const GrGLSLProgramDataManager&
pdman, |
970 const GrProcessor& processor) { | 1019 const GrProcessor& processor) { |
971 | |
972 const GrGradientEffect& e = processor.cast<GrGradientEffect>(); | 1020 const GrGradientEffect& e = processor.cast<GrGradientEffect>(); |
973 | 1021 |
| 1022 switch (e.getColorType()) { |
| 1023 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
| 1024 case GrGradientEffect::kHardStopCentered_ColorType: |
| 1025 case GrGradientEffect::kHardStopLeftEdged_ColorType: |
| 1026 case GrGradientEffect::kHardStopRightEdged_ColorType: |
| 1027 #endif |
| 1028 case GrGradientEffect::kTwo_ColorType: |
| 1029 case GrGradientEffect::kThree_ColorType: { |
| 1030 if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType())
{ |
| 1031 set_before_interp_color_uni_array(pdman, fColorsUni, e.fColors); |
| 1032 } else { |
| 1033 set_after_interp_color_uni_array(pdman, fColorsUni, e.fColors); |
| 1034 } |
974 | 1035 |
975 if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()){ | 1036 break; |
976 | |
977 if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { | |
978 set_mul_color_uni(pdman, fColorStartUni, e.getColors(0)); | |
979 set_mul_color_uni(pdman, fColorEndUni, e.getColors(1)); | |
980 } else { | |
981 set_color_uni(pdman, fColorStartUni, e.getColors(0)); | |
982 set_color_uni(pdman, fColorEndUni, e.getColors(1)); | |
983 } | 1037 } |
984 | 1038 |
985 } else if (SkGradientShaderBase::kThree_GpuColorType == e.getColorType()){ | 1039 case GrGradientEffect::kTexture_ColorType: { |
986 | 1040 SkScalar yCoord = e.getYCoord(); |
987 if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { | 1041 if (yCoord != fCachedYCoord) { |
988 set_mul_color_uni(pdman, fColorStartUni, e.getColors(0)); | 1042 pdman.set1f(fFSYUni, yCoord); |
989 set_mul_color_uni(pdman, fColorMidUni, e.getColors(1)); | 1043 fCachedYCoord = yCoord; |
990 set_mul_color_uni(pdman, fColorEndUni, e.getColors(2)); | 1044 } |
991 } else { | 1045 break; |
992 set_color_uni(pdman, fColorStartUni, e.getColors(0)); | |
993 set_color_uni(pdman, fColorMidUni, e.getColors(1)); | |
994 set_color_uni(pdman, fColorEndUni, e.getColors(2)); | |
995 } | |
996 } else { | |
997 | |
998 SkScalar yCoord = e.getYCoord(); | |
999 if (yCoord != fCachedYCoord) { | |
1000 pdman.set1f(fFSYUni, yCoord); | |
1001 fCachedYCoord = yCoord; | |
1002 } | 1046 } |
1003 } | 1047 } |
1004 } | 1048 } |
1005 | 1049 |
1006 | |
1007 uint32_t GrGradientEffect::GLSLProcessor::GenBaseGradientKey(const GrProcessor&
processor) { | 1050 uint32_t GrGradientEffect::GLSLProcessor::GenBaseGradientKey(const GrProcessor&
processor) { |
1008 const GrGradientEffect& e = processor.cast<GrGradientEffect>(); | 1051 const GrGradientEffect& e = processor.cast<GrGradientEffect>(); |
1009 | 1052 |
1010 uint32_t key = 0; | 1053 uint32_t key = 0; |
1011 | 1054 |
1012 if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()) { | |
1013 key |= kTwoColorKey; | |
1014 } else if (SkGradientShaderBase::kThree_GpuColorType == e.getColorType()) { | |
1015 key |= kThreeColorKey; | |
1016 } | |
1017 | |
1018 if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { | 1055 if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { |
1019 key |= kPremulBeforeInterpKey; | 1056 key |= kPremulBeforeInterpKey; |
1020 } | 1057 } |
1021 | 1058 |
| 1059 if (GrGradientEffect::kTwo_ColorType == e.getColorType()) { |
| 1060 key |= kTwoColorKey; |
| 1061 } else if (GrGradientEffect::kThree_ColorType == e.getColorType()) { |
| 1062 key |= kThreeColorKey; |
| 1063 } |
| 1064 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
| 1065 else if (GrGradientEffect::kHardStopCentered_ColorType == e.getColorType())
{ |
| 1066 key |= kHardStopCenteredKey; |
| 1067 } else if (GrGradientEffect::kHardStopLeftEdged_ColorType == e.getColorType(
)) { |
| 1068 key |= kHardStopZeroZeroOneKey; |
| 1069 } else if (GrGradientEffect::kHardStopRightEdged_ColorType == e.getColorType
()) { |
| 1070 key |= kHardStopZeroOneOneKey; |
| 1071 } |
| 1072 |
| 1073 if (SkShader::TileMode::kClamp_TileMode == e.fTileMode) { |
| 1074 key |= kClampTileMode; |
| 1075 } else if (SkShader::TileMode::kRepeat_TileMode == e.fTileMode) { |
| 1076 key |= kRepeatTileMode; |
| 1077 } else { |
| 1078 key |= kMirrorTileMode; |
| 1079 } |
| 1080 #endif |
| 1081 |
1022 return key; | 1082 return key; |
1023 } | 1083 } |
1024 | 1084 |
1025 void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui
lder, | 1085 void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui
lder, |
1026 GrGLSLUniformHandler* uniformHan
dler, | 1086 GrGLSLUniformHandler* uniformHan
dler, |
1027 const GrGLSLCaps* glslCaps, | 1087 const GrGLSLCaps* glslCaps, |
1028 const GrGradientEffect& ge, | 1088 const GrGradientEffect& ge, |
1029 const char* gradientTValue, | 1089 const char* gradientTValue, |
1030 const char* outputColor, | 1090 const char* outputColor, |
1031 const char* inputColor, | 1091 const char* inputColor, |
1032 const SamplerHandle* texSamplers
) { | 1092 const SamplerHandle* texSamplers
) { |
1033 if (SkGradientShaderBase::kTwo_GpuColorType == ge.getColorType()){ | 1093 switch (ge.getColorType()) { |
1034 fragBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0,
1.0));\n", | 1094 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
1035 uniformHandler->getUniformVariable(fColorStartU
ni).c_str(), | 1095 case kHardStopCentered_ColorType: { |
1036 uniformHandler->getUniformVariable(fColorEndUni
).c_str(), | 1096 const char* t = gradientTValue; |
1037 gradientTValue); | 1097 const char* colors = uniformHandler->getUniformCStr(fColorsUni); |
1038 // Note that we could skip this step if both colors are known to be opaq
ue. Two | 1098 |
1039 // considerations: | 1099 fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t); |
1040 // The gradient SkShader reporting opaque is more restrictive than neces
sary in the two pt | 1100 |
1041 // case. Make sure the key reflects this optimization (and note that it
can use the same | 1101 // Account for tile mode |
1042 // shader as thekBeforeIterp case). This same optimization applies to th
e 3 color case | 1102 if (SkShader::kRepeat_TileMode == ge.fTileMode) { |
1043 // below. | 1103 fragBuilder->codeAppendf("clamp_t = fract(%s);", t); |
1044 if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) { | 1104 } else if (SkShader::kMirror_TileMode == ge.fTileMode) { |
1045 fragBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n"); | 1105 fragBuilder->codeAppendf("if (%s < 0.0 || %s > 1.0) {", t, t); |
| 1106 fragBuilder->codeAppendf(" if (mod(floor(%s), 2.0) == 0.0) {"
, t); |
| 1107 fragBuilder->codeAppendf(" clamp_t = fract(%s);", t); |
| 1108 fragBuilder->codeAppendf(" } else {"); |
| 1109 fragBuilder->codeAppendf(" clamp_t = 1.0 - fract(%s);", t
); |
| 1110 fragBuilder->codeAppendf(" }"); |
| 1111 fragBuilder->codeAppendf("}"); |
| 1112 } |
| 1113 |
| 1114 // Calculate color |
| 1115 fragBuilder->codeAppendf("float relative_t = fract(2.0 * clamp_t);")
; |
| 1116 if (SkShader::kClamp_TileMode == ge.fTileMode) { |
| 1117 fragBuilder->codeAppendf("relative_t += step(1.0, %s);", t); |
| 1118 } |
| 1119 fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[0], %s[1], relativ
e_t);", colors, |
| 1120 colors); |
| 1121 fragBuilder->codeAppendf("if (clamp_t >= 0.5) {"); |
| 1122 fragBuilder->codeAppendf(" colorTemp = mix(%s[2], %s[3], relative
_t);", colors, |
| 1123 colors); |
| 1124 fragBuilder->codeAppendf("}"); |
| 1125 |
| 1126 if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType())
{ |
| 1127 fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;"); |
| 1128 } |
| 1129 fragBuilder->codeAppendf("%s = %s;", outputColor, |
| 1130 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("col
orTemp")).c_str()); |
| 1131 |
| 1132 break; |
1046 } | 1133 } |
1047 | 1134 |
1048 fragBuilder->codeAppendf("\t%s = %s;\n", outputColor, | 1135 case kHardStopLeftEdged_ColorType: { |
1049 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTe
mp")).c_str()); | 1136 const char* t = gradientTValue; |
1050 } else if (SkGradientShaderBase::kThree_GpuColorType == ge.getColorType()) { | 1137 const char* colors = uniformHandler->getUniformCStr(fColorsUni); |
1051 fragBuilder->codeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n", | 1138 |
1052 gradientTValue); | 1139 fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t); |
1053 fragBuilder->codeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0)
* %s;\n", | 1140 |
1054 uniformHandler->getUniformVariable(fColorStartU
ni).c_str()); | 1141 // Account for tile mode |
1055 if (!glslCaps->canUseMinAndAbsTogether()) { | 1142 if (SkShader::kRepeat_TileMode == ge.fTileMode) { |
1056 // The Tegra3 compiler will sometimes never return if we have | 1143 fragBuilder->codeAppendf("clamp_t = fract(%s);", t); |
1057 // min(abs(oneMinus2t), 1.0), or do the abs first in a separate expr
ession. | 1144 } else if (SkShader::kMirror_TileMode == ge.fTileMode) { |
1058 fragBuilder->codeAppend("\tfloat minAbs = abs(oneMinus2t);\n"); | 1145 fragBuilder->codeAppendf("if (%s < 0.0 || %s > 1.0) {", t, t); |
1059 fragBuilder->codeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n")
; | 1146 fragBuilder->codeAppendf(" if (mod(floor(%s), 2.0) == 0.0) {"
, t); |
1060 fragBuilder->codeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n", | 1147 fragBuilder->codeAppendf(" clamp_t = fract(%s);", t); |
1061 uniformHandler->getUniformVariable(fColorMi
dUni).c_str()); | 1148 fragBuilder->codeAppendf(" } else {"); |
1062 } else { | 1149 fragBuilder->codeAppendf(" clamp_t = 1.0 - fract(%s);", t
); |
1063 fragBuilder->codeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t),
1.0)) * %s;\n", | 1150 fragBuilder->codeAppendf(" }"); |
1064 uniformHandler->getUniformVariable(fColorMi
dUni).c_str()); | 1151 fragBuilder->codeAppendf("}"); |
1065 } | 1152 } |
1066 fragBuilder->codeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) *
%s;\n", | 1153 |
1067 uniformHandler->getUniformVariable(fColorEndUni
).c_str()); | 1154 fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[1], %s[2], clamp_t
);", colors, |
1068 if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) { | 1155 colors); |
1069 fragBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n"); | 1156 if (SkShader::kClamp_TileMode == ge.fTileMode) { |
| 1157 fragBuilder->codeAppendf("if (%s < 0.0) {", t); |
| 1158 fragBuilder->codeAppendf(" colorTemp = %s[0];", colors); |
| 1159 fragBuilder->codeAppendf("}"); |
| 1160 } |
| 1161 |
| 1162 if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType())
{ |
| 1163 fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;"); |
| 1164 } |
| 1165 fragBuilder->codeAppendf("%s = %s;", outputColor, |
| 1166 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("col
orTemp")).c_str()); |
| 1167 |
| 1168 break; |
1070 } | 1169 } |
1071 | 1170 |
1072 fragBuilder->codeAppendf("\t%s = %s;\n", outputColor, | 1171 case kHardStopRightEdged_ColorType: { |
1073 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTe
mp")).c_str()); | 1172 const char* t = gradientTValue; |
1074 } else { | 1173 const char* colors = uniformHandler->getUniformCStr(fColorsUni); |
1075 fragBuilder->codeAppendf("\tvec2 coord = vec2(%s, %s);\n", | 1174 |
1076 gradientTValue, | 1175 fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t); |
1077 uniformHandler->getUniformVariable(fFSYUni).c_s
tr()); | 1176 |
1078 fragBuilder->codeAppendf("\t%s = ", outputColor); | 1177 // Account for tile mode |
1079 fragBuilder->appendTextureLookupAndModulate(inputColor, | 1178 if (SkShader::kRepeat_TileMode == ge.fTileMode) { |
1080 texSamplers[0], | 1179 fragBuilder->codeAppendf("clamp_t = fract(%s);", t); |
1081 "coord"); | 1180 } else if (SkShader::kMirror_TileMode == ge.fTileMode) { |
1082 fragBuilder->codeAppend(";\n"); | 1181 fragBuilder->codeAppendf("if (%s < 0.0 || %s > 1.0) {", t, t); |
| 1182 fragBuilder->codeAppendf(" if (mod(floor(%s), 2.0) == 0.0) {"
, t); |
| 1183 fragBuilder->codeAppendf(" clamp_t = fract(%s);", t); |
| 1184 fragBuilder->codeAppendf(" } else {"); |
| 1185 fragBuilder->codeAppendf(" clamp_t = 1.0 - fract(%s);", t
); |
| 1186 fragBuilder->codeAppendf(" }"); |
| 1187 fragBuilder->codeAppendf("}"); |
| 1188 } |
| 1189 |
| 1190 fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[0], %s[1], clamp_t
);", colors, |
| 1191 colors); |
| 1192 if (SkShader::kClamp_TileMode == ge.fTileMode) { |
| 1193 fragBuilder->codeAppendf("if (%s > 1.0) {", t); |
| 1194 fragBuilder->codeAppendf(" colorTemp = %s[2];", colors); |
| 1195 fragBuilder->codeAppendf("}"); |
| 1196 } |
| 1197 |
| 1198 if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType())
{ |
| 1199 fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;"); |
| 1200 } |
| 1201 fragBuilder->codeAppendf("%s = %s;", outputColor, |
| 1202 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("col
orTemp")).c_str()); |
| 1203 |
| 1204 break; |
| 1205 } |
| 1206 #endif |
| 1207 |
| 1208 case kTwo_ColorType: { |
| 1209 const char* t = gradientTValue; |
| 1210 const char* colors = uniformHandler->getUniformCStr(fColorsUni); |
| 1211 |
| 1212 fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[0], %s[1], clamp(%
s, 0.0, 1.0));", |
| 1213 colors, colors, t); |
| 1214 |
| 1215 // We could skip this step if both colors are known to be opaque. Tw
o |
| 1216 // considerations: |
| 1217 // The gradient SkShader reporting opaque is more restrictive than n
ecessary in the two |
| 1218 // pt case. Make sure the key reflects this optimization (and note t
hat it can use the |
| 1219 // same shader as thekBeforeIterp case). This same optimization appl
ies to the 3 color |
| 1220 // case below. |
| 1221 if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType())
{ |
| 1222 fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;"); |
| 1223 } |
| 1224 |
| 1225 fragBuilder->codeAppendf("%s = %s;", outputColor, |
| 1226 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("col
orTemp")).c_str()); |
| 1227 |
| 1228 break; |
| 1229 } |
| 1230 |
| 1231 case kThree_ColorType: { |
| 1232 const char* t = gradientTValue; |
| 1233 const char* colors = uniformHandler->getUniformCStr(fColorsUni); |
| 1234 |
| 1235 fragBuilder->codeAppendf("float oneMinus2t = 1.0 - (2.0 * %s);", t); |
| 1236 fragBuilder->codeAppendf("vec4 colorTemp = clamp(oneMinus2t, 0.0, 1.
0) * %s[0];", |
| 1237 colors); |
| 1238 if (!glslCaps->canUseMinAndAbsTogether()) { |
| 1239 // The Tegra3 compiler will sometimes never return if we have |
| 1240 // min(abs(oneMinus2t), 1.0), or do the abs first in a separate
expression. |
| 1241 fragBuilder->codeAppendf("float minAbs = abs(oneMinus2t);"); |
| 1242 fragBuilder->codeAppendf("minAbs = minAbs > 1.0 ? 1.0 : minAbs;"
); |
| 1243 fragBuilder->codeAppendf("colorTemp += (1.0 - minAbs) * %s[1];",
colors); |
| 1244 } else { |
| 1245 fragBuilder->codeAppendf("colorTemp += (1.0 - min(abs(oneMinus2t
), 1.0)) * %s[1];", |
| 1246 colors); |
| 1247 } |
| 1248 fragBuilder->codeAppendf("colorTemp += clamp(-oneMinus2t, 0.0, 1.0)
* %s[2];", colors); |
| 1249 |
| 1250 if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType())
{ |
| 1251 fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;"); |
| 1252 } |
| 1253 |
| 1254 fragBuilder->codeAppendf("%s = %s;", outputColor, |
| 1255 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("col
orTemp")).c_str()); |
| 1256 |
| 1257 break; |
| 1258 } |
| 1259 |
| 1260 case kTexture_ColorType: { |
| 1261 const char* fsyuni = uniformHandler->getUniformCStr(fFSYUni); |
| 1262 |
| 1263 fragBuilder->codeAppendf("vec2 coord = vec2(%s, %s);", gradientTValu
e, fsyuni); |
| 1264 fragBuilder->codeAppendf("%s = ", outputColor); |
| 1265 fragBuilder->appendTextureLookupAndModulate(inputColor, texSamplers[
0], "coord"); |
| 1266 fragBuilder->codeAppend(";"); |
| 1267 |
| 1268 break; |
| 1269 } |
1083 } | 1270 } |
1084 } | 1271 } |
1085 | 1272 |
1086 ///////////////////////////////////////////////////////////////////// | 1273 ///////////////////////////////////////////////////////////////////// |
1087 | 1274 |
1088 GrGradientEffect::GrGradientEffect(GrContext* ctx, | 1275 GrGradientEffect::GrGradientEffect(GrContext* ctx, |
1089 const SkGradientShaderBase& shader, | 1276 const SkGradientShaderBase& shader, |
1090 const SkMatrix& matrix, | 1277 const SkMatrix& matrix, |
1091 SkShader::TileMode tileMode) { | 1278 SkShader::TileMode tileMode) { |
1092 | 1279 |
1093 fIsOpaque = shader.isOpaque(); | 1280 fIsOpaque = shader.isOpaque(); |
1094 | 1281 |
1095 fColorType = shader.getGpuColorType(&fColors[0]); | 1282 fColorType = this->determineColorType(shader); |
1096 | 1283 |
1097 // The two and three color specializations do not currently support tiling. | 1284 if (kTexture_ColorType != fColorType) { |
1098 if (SkGradientShaderBase::kTwo_GpuColorType == fColorType || | 1285 if (shader.fOrigColors) { |
1099 SkGradientShaderBase::kThree_GpuColorType == fColorType) { | 1286 fColors = SkTDArray<SkColor>(shader.fOrigColors, shader.fColorCount)
; |
1100 fRow = -1; | 1287 } |
1101 | 1288 |
1102 if (SkGradientShader::kInterpolateColorsInPremul_Flag & shader.getGradFl
ags()) { | 1289 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
| 1290 if (shader.fOrigPos) { |
| 1291 fPositions = SkTDArray<SkScalar>(shader.fOrigPos, shader.fColorCount
); |
| 1292 } |
| 1293 #endif |
| 1294 } |
| 1295 |
| 1296 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
| 1297 fTileMode = tileMode; |
| 1298 #endif |
| 1299 |
| 1300 switch (fColorType) { |
| 1301 // The two and three color specializations do not currently support tili
ng. |
| 1302 case kTwo_ColorType: |
| 1303 case kThree_ColorType: |
| 1304 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
| 1305 case kHardStopLeftEdged_ColorType: |
| 1306 case kHardStopRightEdged_ColorType: |
| 1307 case kHardStopCentered_ColorType: |
| 1308 #endif |
| 1309 fRow = -1; |
| 1310 |
| 1311 if (SkGradientShader::kInterpolateColorsInPremul_Flag & shader.getGr
adFlags()) { |
| 1312 fPremulType = kBeforeInterp_PremulType; |
| 1313 } else { |
| 1314 fPremulType = kAfterInterp_PremulType; |
| 1315 } |
| 1316 |
| 1317 fCoordTransform.reset(kCoordSet, matrix); |
| 1318 |
| 1319 break; |
| 1320 case kTexture_ColorType: |
| 1321 // doesn't matter how this is set, just be consistent because it is
part of the |
| 1322 // effect key. |
1103 fPremulType = kBeforeInterp_PremulType; | 1323 fPremulType = kBeforeInterp_PremulType; |
1104 } else { | |
1105 fPremulType = kAfterInterp_PremulType; | |
1106 } | |
1107 fCoordTransform.reset(kCoordSet, matrix); | |
1108 } else { | |
1109 // doesn't matter how this is set, just be consistent because it is part
of the effect key. | |
1110 fPremulType = kBeforeInterp_PremulType; | |
1111 SkBitmap bitmap; | |
1112 shader.getGradientTableBitmap(&bitmap); | |
1113 | 1324 |
1114 GrTextureStripAtlas::Desc desc; | 1325 SkBitmap bitmap; |
1115 desc.fWidth = bitmap.width(); | 1326 shader.getGradientTableBitmap(&bitmap); |
1116 desc.fHeight = 32; | |
1117 desc.fRowHeight = bitmap.height(); | |
1118 desc.fContext = ctx; | |
1119 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *ctx->caps()); | |
1120 fAtlas = GrTextureStripAtlas::GetAtlas(desc); | |
1121 SkASSERT(fAtlas); | |
1122 | 1327 |
1123 // We always filter the gradient table. Each table is one row of a textu
re, always y-clamp. | 1328 GrTextureStripAtlas::Desc desc; |
1124 GrTextureParams params; | 1329 desc.fWidth = bitmap.width(); |
1125 params.setFilterMode(GrTextureParams::kBilerp_FilterMode); | 1330 desc.fHeight = 32; |
1126 params.setTileModeX(tileMode); | 1331 desc.fRowHeight = bitmap.height(); |
| 1332 desc.fContext = ctx; |
| 1333 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *ctx->caps()
); |
| 1334 fAtlas = GrTextureStripAtlas::GetAtlas(desc); |
| 1335 SkASSERT(fAtlas); |
1127 | 1336 |
1128 fRow = fAtlas->lockRow(bitmap); | 1337 // We always filter the gradient table. Each table is one row of a t
exture, always |
1129 if (-1 != fRow) { | 1338 // y-clamp. |
1130 fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf * fAtlas->getNorm
alizedTexelHeight(); | 1339 GrTextureParams params; |
1131 fCoordTransform.reset(kCoordSet, matrix, fAtlas->getTexture(), param
s.filterMode()); | 1340 params.setFilterMode(GrTextureParams::kBilerp_FilterMode); |
1132 fTextureAccess.reset(fAtlas->getTexture(), params); | 1341 params.setTileModeX(tileMode); |
1133 } else { | 1342 |
1134 SkAutoTUnref<GrTexture> texture( | 1343 fRow = fAtlas->lockRow(bitmap); |
1135 GrRefCachedBitmapTexture(ctx, bitmap, params, SkSourceGammaTreat
ment::kRespect)); | 1344 if (-1 != fRow) { |
1136 if (!texture) { | 1345 fYCoord = fAtlas->getYOffset(fRow)+SK_ScalarHalf*fAtlas->getNorm
alizedTexelHeight(); |
1137 return; | 1346 fCoordTransform.reset(kCoordSet, matrix, fAtlas->getTexture(), p
arams.filterMode()); |
| 1347 fTextureAccess.reset(fAtlas->getTexture(), params); |
| 1348 } else { |
| 1349 SkAutoTUnref<GrTexture> texture( |
| 1350 GrRefCachedBitmapTexture(ctx, bitmap, params, |
| 1351 SkSourceGammaTreatment::kRespect)); |
| 1352 if (!texture) { |
| 1353 return; |
| 1354 } |
| 1355 fCoordTransform.reset(kCoordSet, matrix, texture, params.filterM
ode()); |
| 1356 fTextureAccess.reset(texture, params); |
| 1357 fYCoord = SK_ScalarHalf; |
1138 } | 1358 } |
1139 fCoordTransform.reset(kCoordSet, matrix, texture, params.filterMode(
)); | 1359 |
1140 fTextureAccess.reset(texture, params); | 1360 this->addTextureAccess(&fTextureAccess); |
1141 fYCoord = SK_ScalarHalf; | 1361 |
1142 } | 1362 break; |
1143 this->addTextureAccess(&fTextureAccess); | |
1144 } | 1363 } |
| 1364 |
1145 this->addCoordTransform(&fCoordTransform); | 1365 this->addCoordTransform(&fCoordTransform); |
1146 } | 1366 } |
1147 | 1367 |
1148 GrGradientEffect::~GrGradientEffect() { | 1368 GrGradientEffect::~GrGradientEffect() { |
1149 if (this->useAtlas()) { | 1369 if (this->useAtlas()) { |
1150 fAtlas->unlockRow(fRow); | 1370 fAtlas->unlockRow(fRow); |
1151 } | 1371 } |
1152 } | 1372 } |
1153 | 1373 |
1154 bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const { | 1374 bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const { |
1155 const GrGradientEffect& s = processor.cast<GrGradientEffect>(); | 1375 const GrGradientEffect& ge = processor.cast<GrGradientEffect>(); |
1156 | 1376 |
1157 if (this->fColorType == s.getColorType()){ | 1377 if (this->fColorType == ge.getColorType()) { |
1158 | 1378 if (kTexture_ColorType == fColorType) { |
1159 if (SkGradientShaderBase::kTwo_GpuColorType == fColorType) { | 1379 if (fYCoord != ge.getYCoord()) { |
1160 if (this->getPremulType() != s.getPremulType() || | |
1161 *this->getColors(0) != *s.getColors(0) || | |
1162 *this->getColors(1) != *s.getColors(1)) { | |
1163 return false; | |
1164 } | |
1165 } else if (SkGradientShaderBase::kThree_GpuColorType == fColorType) { | |
1166 if (this->getPremulType() != s.getPremulType() || | |
1167 *this->getColors(0) != *s.getColors(0) || | |
1168 *this->getColors(1) != *s.getColors(1) || | |
1169 *this->getColors(2) != *s.getColors(2)) { | |
1170 return false; | 1380 return false; |
1171 } | 1381 } |
1172 } else { | 1382 } else { |
1173 if (fYCoord != s.getYCoord()) { | 1383 if (this->getPremulType() != ge.getPremulType() || |
| 1384 this->fColors.count() != ge.fColors.count()) { |
1174 return false; | 1385 return false; |
1175 } | 1386 } |
| 1387 |
| 1388 for (int i = 0; i < this->fColors.count(); i++) { |
| 1389 if (*this->getColors(i) != *ge.getColors(i)) { |
| 1390 return false; |
| 1391 } |
| 1392 } |
1176 } | 1393 } |
1177 | 1394 |
1178 SkASSERT(this->useAtlas() == s.useAtlas()); | 1395 SkASSERT(this->useAtlas() == ge.useAtlas()); |
1179 return true; | 1396 return true; |
1180 } | 1397 } |
1181 | 1398 |
1182 return false; | 1399 return false; |
1183 } | 1400 } |
1184 | 1401 |
1185 void GrGradientEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ | 1402 void GrGradientEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const
{ |
1186 if (fIsOpaque) { | 1403 if (fIsOpaque) { |
1187 inout->mulByUnknownOpaqueFourComponents(); | 1404 inout->mulByUnknownOpaqueFourComponents(); |
1188 } else { | 1405 } else { |
(...skipping 19 matching lines...) Expand all Loading... |
1208 (*stops)[i] = stop; | 1425 (*stops)[i] = stop; |
1209 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st
op) : 1.f; | 1426 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st
op) : 1.f; |
1210 } | 1427 } |
1211 } | 1428 } |
1212 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM
odeCount)); | 1429 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM
odeCount)); |
1213 | 1430 |
1214 return outColors; | 1431 return outColors; |
1215 } | 1432 } |
1216 | 1433 |
1217 #endif | 1434 #endif |
OLD | NEW |