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