OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkXfermode.h" | 10 #include "SkXfermode.h" |
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 static const char* Name() { return "XferEffect"; } | 806 static const char* Name() { return "XferEffect"; } |
807 | 807 |
808 SkXfermode::Mode mode() const { return fMode; } | 808 SkXfermode::Mode mode() const { return fMode; } |
809 const GrTextureAccess& backgroundAccess() const { return fBackgroundAccess;
} | 809 const GrTextureAccess& backgroundAccess() const { return fBackgroundAccess;
} |
810 | 810 |
811 class GLProcessor : public GrGLFragmentProcessor { | 811 class GLProcessor : public GrGLFragmentProcessor { |
812 public: | 812 public: |
813 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&
) | 813 GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&
) |
814 : INHERITED(factory) { | 814 : INHERITED(factory) { |
815 } | 815 } |
816 virtual void emitCode(GrGLProgramBuilder* builder, | 816 virtual void emitCode(GrGLFPBuilder* builder, |
817 const GrFragmentProcessor& fp, | 817 const GrFragmentProcessor& fp, |
818 const GrProcessorKey& key, | 818 const GrProcessorKey& key, |
819 const char* outputColor, | 819 const char* outputColor, |
820 const char* inputColor, | 820 const char* inputColor, |
821 const TransformedCoordsArray& coords, | 821 const TransformedCoordsArray& coords, |
822 const TextureSamplerArray& samplers) SK_OVERRIDE { | 822 const TextureSamplerArray& samplers) SK_OVERRIDE { |
823 SkXfermode::Mode mode = fp.cast<XferEffect>().mode(); | 823 SkXfermode::Mode mode = fp.cast<XferEffect>().mode(); |
824 const GrTexture* backgroundTex = | 824 const GrTexture* backgroundTex = |
825 fp.cast<XferEffect>().backgroundAccess().getTexture(); | 825 fp.cast<XferEffect>().backgroundAccess().getTexture(); |
826 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); | 826 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder
(); |
827 const char* dstColor; | 827 const char* dstColor; |
828 if (backgroundTex) { | 828 if (backgroundTex) { |
829 dstColor = "bgColor"; | 829 dstColor = "bgColor"; |
830 fsBuilder->codeAppendf("\t\tvec4 %s = ", dstColor); | 830 fsBuilder->codeAppendf("\t\tvec4 %s = ", dstColor); |
831 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), c
oords[0].getType()); | 831 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), c
oords[0].getType()); |
832 fsBuilder->codeAppendf(";\n"); | 832 fsBuilder->codeAppendf(";\n"); |
833 } else { | 833 } else { |
834 dstColor = fsBuilder->dstColor(); | 834 dstColor = fsBuilder->dstColor(); |
835 } | 835 } |
836 SkASSERT(dstColor); | 836 SkASSERT(dstColor); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 static inline void GenKey(const GrProcessor& proc, const GrGLCaps&, | 966 static inline void GenKey(const GrProcessor& proc, const GrGLCaps&, |
967 GrProcessorKeyBuilder* b) { | 967 GrProcessorKeyBuilder* b) { |
968 // The background may come from the dst or from a texture. | 968 // The background may come from the dst or from a texture. |
969 uint32_t key = proc.numTextures(); | 969 uint32_t key = proc.numTextures(); |
970 SkASSERT(key <= 1); | 970 SkASSERT(key <= 1); |
971 key |= proc.cast<XferEffect>().mode() << 1; | 971 key |= proc.cast<XferEffect>().mode() << 1; |
972 b->add32(key); | 972 b->add32(key); |
973 } | 973 } |
974 | 974 |
975 private: | 975 private: |
976 static void HardLight(GrGLFragmentShaderBuilder* fsBuilder, | 976 static void HardLight(GrGLFPFragmentBuilder* fsBuilder, |
977 const char* final, | 977 const char* final, |
978 const char* src, | 978 const char* src, |
979 const char* dst) { | 979 const char* dst) { |
980 static const char kComponents[] = {'r', 'g', 'b'}; | 980 static const char kComponents[] = {'r', 'g', 'b'}; |
981 for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) { | 981 for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) { |
982 char component = kComponents[i]; | 982 char component = kComponents[i]; |
983 fsBuilder->codeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src,
component, src); | 983 fsBuilder->codeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src,
component, src); |
984 fsBuilder->codeAppendf("\t\t\t%s.%c = 2.0 * %s.%c * %s.%c;\n", f
inal, component, src, component, dst, component); | 984 fsBuilder->codeAppendf("\t\t\t%s.%c = 2.0 * %s.%c * %s.%c;\n", f
inal, component, src, component, dst, component); |
985 fsBuilder->codeAppend("\t\t} else {\n"); | 985 fsBuilder->codeAppend("\t\t} else {\n"); |
986 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a - 2.0 * (%s.a
- %s.%c) * (%s.a - %s.%c);\n", | 986 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a - 2.0 * (%s.a
- %s.%c) * (%s.a - %s.%c);\n", |
987 final, component, src, dst, dst, dst, com
ponent, src, src, component); | 987 final, component, src, dst, dst, dst, com
ponent, src, src, component); |
988 fsBuilder->codeAppend("\t\t}\n"); | 988 fsBuilder->codeAppend("\t\t}\n"); |
989 } | 989 } |
990 fsBuilder->codeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb
* (1.0 - %s.a);\n", | 990 fsBuilder->codeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb
* (1.0 - %s.a);\n", |
991 final, src, dst, dst, src); | 991 final, src, dst, dst, src); |
992 } | 992 } |
993 | 993 |
994 // Does one component of color-dodge | 994 // Does one component of color-dodge |
995 static void ColorDodgeComponent(GrGLFragmentShaderBuilder* fsBuilder, | 995 static void ColorDodgeComponent(GrGLFPFragmentBuilder* fsBuilder, |
996 const char* final, | 996 const char* final, |
997 const char* src, | 997 const char* src, |
998 const char* dst, | 998 const char* dst, |
999 const char component) { | 999 const char component) { |
1000 fsBuilder->codeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component); | 1000 fsBuilder->codeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component); |
1001 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n", | 1001 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n", |
1002 final, component, src, component, dst); | 1002 final, component, src, component, dst); |
1003 fsBuilder->codeAppend("\t\t} else {\n"); | 1003 fsBuilder->codeAppend("\t\t} else {\n"); |
1004 fsBuilder->codeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src,
component); | 1004 fsBuilder->codeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src,
component); |
1005 fsBuilder->codeAppend("\t\t\tif (0.0 == d) {\n"); | 1005 fsBuilder->codeAppend("\t\t\tif (0.0 == d) {\n"); |
1006 fsBuilder->codeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 -
%s.a) + %s.%c * (1.0 - %s.a);\n", | 1006 fsBuilder->codeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 -
%s.a) + %s.%c * (1.0 - %s.a);\n", |
1007 final, component, src, dst, src, component, d
st, dst, component, | 1007 final, component, src, dst, src, component, d
st, dst, component, |
1008 src); | 1008 src); |
1009 fsBuilder->codeAppend("\t\t\t} else {\n"); | 1009 fsBuilder->codeAppend("\t\t\t} else {\n"); |
1010 fsBuilder->codeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n", | 1010 fsBuilder->codeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n", |
1011 dst, dst, component, src); | 1011 dst, dst, component, src); |
1012 fsBuilder->codeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s
.a) + %s.%c * (1.0 - %s.a);\n", | 1012 fsBuilder->codeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s
.a) + %s.%c * (1.0 - %s.a);\n", |
1013 final, component, src, src, component, dst, d
st, component, src); | 1013 final, component, src, src, component, dst, d
st, component, src); |
1014 fsBuilder->codeAppend("\t\t\t}\n"); | 1014 fsBuilder->codeAppend("\t\t\t}\n"); |
1015 fsBuilder->codeAppend("\t\t}\n"); | 1015 fsBuilder->codeAppend("\t\t}\n"); |
1016 } | 1016 } |
1017 | 1017 |
1018 // Does one component of color-burn | 1018 // Does one component of color-burn |
1019 static void ColorBurnComponent(GrGLFragmentShaderBuilder* fsBuilder, | 1019 static void ColorBurnComponent(GrGLFPFragmentBuilder* fsBuilder, |
1020 const char* final, | 1020 const char* final, |
1021 const char* src, | 1021 const char* src, |
1022 const char* dst, | 1022 const char* dst, |
1023 const char component) { | 1023 const char component) { |
1024 fsBuilder->codeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, compo
nent); | 1024 fsBuilder->codeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, compo
nent); |
1025 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %
s.a) + %s.%c * (1.0 - %s.a);\n", | 1025 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %
s.a) + %s.%c * (1.0 - %s.a);\n", |
1026 final, component, src, dst, src, component, d
st, dst, component, | 1026 final, component, src, dst, src, component, d
st, dst, component, |
1027 src); | 1027 src); |
1028 fsBuilder->codeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, comp
onent); | 1028 fsBuilder->codeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, comp
onent); |
1029 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n", | 1029 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n", |
1030 final, component, dst, component, src); | 1030 final, component, dst, component, src); |
1031 fsBuilder->codeAppend("\t\t} else {\n"); | 1031 fsBuilder->codeAppend("\t\t} else {\n"); |
1032 fsBuilder->codeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.%
c) * %s.a / %s.%c);\n", | 1032 fsBuilder->codeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.%
c) * %s.a / %s.%c);\n", |
1033 dst, dst, dst, component, src, src, component
); | 1033 dst, dst, dst, component, src, src, component
); |
1034 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a
) + %s.%c * (1.0 - %s.a);\n", | 1034 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a
) + %s.%c * (1.0 - %s.a);\n", |
1035 final, component, src, src, component, dst, d
st, component, src); | 1035 final, component, src, src, component, dst, d
st, component, src); |
1036 fsBuilder->codeAppend("\t\t}\n"); | 1036 fsBuilder->codeAppend("\t\t}\n"); |
1037 } | 1037 } |
1038 | 1038 |
1039 // Does one component of soft-light. Caller should have already checked
that dst alpha > 0. | 1039 // Does one component of soft-light. Caller should have already checked
that dst alpha > 0. |
1040 static void SoftLightComponentPosDstAlpha(GrGLFragmentShaderBuilder* fsB
uilder, | 1040 static void SoftLightComponentPosDstAlpha(GrGLFPFragmentBuilder* fsBuild
er, |
1041 const char* final, | 1041 const char* final, |
1042 const char* src, | 1042 const char* src, |
1043 const char* dst, | 1043 const char* dst, |
1044 const char component) { | 1044 const char component) { |
1045 // if (2S < Sa) | 1045 // if (2S < Sa) |
1046 fsBuilder->codeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, co
mponent, src); | 1046 fsBuilder->codeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, co
mponent, src); |
1047 // (D^2 (Sa-2 S))/Da+(1-Da) S+D (-Sa+2 S+1) | 1047 // (D^2 (Sa-2 S))/Da+(1-Da) S+D (-Sa+2 S+1) |
1048 fsBuilder->codeAppendf("\t\t\t\t%s.%c = (%s.%c*%s.%c*(%s.a - 2.0*%s.
%c)) / %s.a + (1.0 - %s.a) * %s.%c + %s.%c*(-%s.a + 2.0*%s.%c + 1.0);\n", | 1048 fsBuilder->codeAppendf("\t\t\t\t%s.%c = (%s.%c*%s.%c*(%s.a - 2.0*%s.
%c)) / %s.a + (1.0 - %s.a) * %s.%c + %s.%c*(-%s.a + 2.0*%s.%c + 1.0);\n", |
1049 final, component, dst, component, dst, compon
ent, src, src, | 1049 final, component, dst, component, dst, compon
ent, src, src, |
1050 component, dst, dst, src, component, dst, com
ponent, src, src, | 1050 component, dst, dst, src, component, dst, com
ponent, src, src, |
(...skipping 17 matching lines...) Expand all Loading... |
1068 final, component, dst, dst, component, src,
src, component, dst, | 1068 final, component, dst, dst, component, src,
src, component, dst, |
1069 src, component, dst, component, src, src, co
mponent, src, | 1069 src, component, dst, component, src, src, co
mponent, src, |
1070 component); | 1070 component); |
1071 fsBuilder->codeAppendf("\t\t\t}\n"); | 1071 fsBuilder->codeAppendf("\t\t\t}\n"); |
1072 } | 1072 } |
1073 | 1073 |
1074 // Adds a function that takes two colors and an alpha as input. It produ
ces a color with the | 1074 // Adds a function that takes two colors and an alpha as input. It produ
ces a color with the |
1075 // hue and saturation of the first color, the luminosity of the second c
olor, and the input | 1075 // hue and saturation of the first color, the luminosity of the second c
olor, and the input |
1076 // alpha. It has this signature: | 1076 // alpha. It has this signature: |
1077 // vec3 set_luminance(vec3 hueSatColor, float alpha, vec3 lumColor)
. | 1077 // vec3 set_luminance(vec3 hueSatColor, float alpha, vec3 lumColor)
. |
1078 static void AddLumFunction(GrGLFragmentShaderBuilder* fsBuilder, SkStrin
g* setLumFunction) { | 1078 static void AddLumFunction(GrGLFPFragmentBuilder* fsBuilder, SkString* s
etLumFunction) { |
1079 // Emit a helper that gets the luminance of a color. | 1079 // Emit a helper that gets the luminance of a color. |
1080 SkString getFunction; | 1080 SkString getFunction; |
1081 GrGLShaderVar getLumArgs[] = { | 1081 GrGLShaderVar getLumArgs[] = { |
1082 GrGLShaderVar("color", kVec3f_GrSLType), | 1082 GrGLShaderVar("color", kVec3f_GrSLType), |
1083 }; | 1083 }; |
1084 SkString getLumBody("\treturn dot(vec3(0.3, 0.59, 0.11), color);\n")
; | 1084 SkString getLumBody("\treturn dot(vec3(0.3, 0.59, 0.11), color);\n")
; |
1085 fsBuilder->emitFunction(kFloat_GrSLType, | 1085 fsBuilder->emitFunction(kFloat_GrSLType, |
1086 "luminance", | 1086 "luminance", |
1087 SK_ARRAY_COUNT(getLumArgs), getLumArgs, | 1087 SK_ARRAY_COUNT(getLumArgs), getLumArgs, |
1088 getLumBody.c_str(), | 1088 getLumBody.c_str(), |
(...skipping 21 matching lines...) Expand all Loading... |
1110 fsBuilder->emitFunction(kVec3f_GrSLType, | 1110 fsBuilder->emitFunction(kVec3f_GrSLType, |
1111 "set_luminance", | 1111 "set_luminance", |
1112 SK_ARRAY_COUNT(setLumArgs), setLumArgs, | 1112 SK_ARRAY_COUNT(setLumArgs), setLumArgs, |
1113 setLumBody.c_str(), | 1113 setLumBody.c_str(), |
1114 setLumFunction); | 1114 setLumFunction); |
1115 } | 1115 } |
1116 | 1116 |
1117 // Adds a function that creates a color with the hue and luminosity of o
ne input color and | 1117 // Adds a function that creates a color with the hue and luminosity of o
ne input color and |
1118 // the saturation of another color. It will have this signature: | 1118 // the saturation of another color. It will have this signature: |
1119 // float set_saturation(vec3 hueLumColor, vec3 satColor) | 1119 // float set_saturation(vec3 hueLumColor, vec3 satColor) |
1120 static void AddSatFunction(GrGLFragmentShaderBuilder* fsBuilder, SkStrin
g* setSatFunction) { | 1120 static void AddSatFunction(GrGLFPFragmentBuilder* fsBuilder, SkString* s
etSatFunction) { |
1121 // Emit a helper that gets the saturation of a color | 1121 // Emit a helper that gets the saturation of a color |
1122 SkString getFunction; | 1122 SkString getFunction; |
1123 GrGLShaderVar getSatArgs[] = { GrGLShaderVar("color", kVec3f_GrSLTyp
e) }; | 1123 GrGLShaderVar getSatArgs[] = { GrGLShaderVar("color", kVec3f_GrSLTyp
e) }; |
1124 SkString getSatBody; | 1124 SkString getSatBody; |
1125 getSatBody.printf("\treturn max(max(color.r, color.g), color.b) - " | 1125 getSatBody.printf("\treturn max(max(color.r, color.g), color.b) - " |
1126 "min(min(color.r, color.g), color.b);\n"); | 1126 "min(min(color.r, color.g), color.b);\n"); |
1127 fsBuilder->emitFunction(kFloat_GrSLType, | 1127 fsBuilder->emitFunction(kFloat_GrSLType, |
1128 "saturation", | 1128 "saturation", |
1129 SK_ARRAY_COUNT(getSatArgs), getSatArgs, | 1129 SK_ARRAY_COUNT(getSatArgs), getSatArgs, |
1130 getSatBody.c_str(), | 1130 getSatBody.c_str(), |
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1955 } else { | 1955 } else { |
1956 proc16 = rec.fProc16_General; | 1956 proc16 = rec.fProc16_General; |
1957 } | 1957 } |
1958 } | 1958 } |
1959 return proc16; | 1959 return proc16; |
1960 } | 1960 } |
1961 | 1961 |
1962 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1962 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
1963 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1963 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
1964 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1964 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |