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