Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: src/effects/gradients/SkGradientShader.cpp

Issue 2223203003: Exact Ganesh Gradients for Special Cases (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Remove calls to setReserve() Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/effects/gradients/SkGradientShaderPriv.h » ('j') | src/effects/gradients/SkGradientShaderPriv.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698