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

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

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

Powered by Google App Engine
This is Rietveld 408576698