Chromium Code Reviews| 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 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 943 ////////////////////////////////////////////////////////////////////////////// | 943 ////////////////////////////////////////////////////////////////////////////// |
| 944 | 944 |
| 945 #if SK_SUPPORT_GPU | 945 #if SK_SUPPORT_GPU |
| 946 | 946 |
| 947 #include "GrEffect.h" | 947 #include "GrEffect.h" |
| 948 #include "GrEffectUnitTest.h" | 948 #include "GrEffectUnitTest.h" |
| 949 #include "GrTBackendEffectFactory.h" | 949 #include "GrTBackendEffectFactory.h" |
| 950 #include "gl/GrGLEffect.h" | 950 #include "gl/GrGLEffect.h" |
| 951 | 951 |
| 952 /** | 952 /** |
| 953 * GrEffect that implements the kDarken_Mode Xfermode. It requires access to the dst pixel color | 953 * GrEffect that implements the all the separable xfer modes that cannot be expr essed as Coeffs. |
| 954 * in the shader. TODO: Make this work for all non-Coeff SkXfermode::Mode values . | |
| 955 */ | 954 */ |
| 956 class DarkenEffect : public GrEffect { | 955 class XferEffect : public GrEffect { |
| 957 public: | 956 public: |
| 958 static GrEffectRef* Create() { | 957 static bool IsSupportedMode(SkXfermode::Mode mode) { |
|
robertphillips
2013/04/19 14:16:32
return(!<expression>)?
bsalomon
2013/04/19 14:24:28
will do
| |
| 959 static AutoEffectUnref gEffect(SkNEW(DarkenEffect)); | 958 if (mode <= SkXfermode::kLastCoeffMode || mode > SkXfermode::kLastSepara bleMode) { |
| 960 return CreateEffectRef(gEffect); | 959 return false; |
| 960 } | |
| 961 return true; | |
| 962 } | |
| 963 | |
| 964 static GrEffectRef* Create(SkXfermode::Mode mode) { | |
| 965 if (!IsSupportedMode(mode)) { | |
| 966 return NULL; | |
| 967 } else { | |
| 968 AutoEffectUnref effect(SkNEW_ARGS(XferEffect, (mode))); | |
| 969 return CreateEffectRef(effect); | |
| 970 } | |
| 961 } | 971 } |
| 962 | 972 |
| 963 virtual void getConstantColorComponents(GrColor* color, | 973 virtual void getConstantColorComponents(GrColor* color, |
| 964 uint32_t* validFlags) const SK_OVERR IDE { | 974 uint32_t* validFlags) const SK_OVERR IDE { |
| 965 *validFlags = 0; | 975 *validFlags = 0; |
| 966 } | 976 } |
| 967 | 977 |
| 968 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | 978 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { |
| 969 return GrTBackendEffectFactory<DarkenEffect>::getInstance(); | 979 return GrTBackendEffectFactory<XferEffect>::getInstance(); |
| 970 } | 980 } |
| 971 | 981 |
| 972 static const char* Name() { return "XfermodeDarken"; } | 982 static const char* Name() { return "XferEffect"; } |
| 983 | |
| 984 SkXfermode::Mode mode() const { return fMode; } | |
| 973 | 985 |
| 974 class GLEffect : public GrGLEffect { | 986 class GLEffect : public GrGLEffect { |
| 975 public: | 987 public: |
| 976 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | 988 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) |
| 977 : GrGLEffect(factory ) { | 989 : GrGLEffect(factory ) { |
| 978 } | 990 } |
| 979 virtual void emitCode(GrGLShaderBuilder* builder, | 991 virtual void emitCode(GrGLShaderBuilder* builder, |
| 980 const GrDrawEffect& drawEffect, | 992 const GrDrawEffect& drawEffect, |
| 981 EffectKey key, | 993 EffectKey key, |
| 982 const char* outputColor, | 994 const char* outputColor, |
| 983 const char* inputColor, | 995 const char* inputColor, |
| 984 const TextureSamplerArray& samplers) SK_OVERRIDE { | 996 const TextureSamplerArray& samplers) SK_OVERRIDE { |
| 985 const char* dstColorName = builder->dstColor(); | 997 const char* dstColor = builder->dstColor(); |
| 986 GrAssert(NULL != dstColorName); | 998 GrAssert(NULL != dstColor); |
| 999 | |
| 1000 // We don't try to optimize for this case at all | |
| 987 if (NULL == inputColor) { | 1001 if (NULL == inputColor) { |
| 988 // the input color is solid white | 1002 builder->fsCodeAppendf("\tconst vec4 ones = %s;\n", GrGLSLOnesVe cf(4)); |
| 989 builder->fsCodeAppendf("\t\t%s.a = 1.0;\n", outputColor); | 1003 inputColor = "ones"; |
| 990 builder->fsCodeAppendf("\t\t%s.rgb = vec3(1.0, 1.0, 1.0) - %s.aa a + %s.rgb;\n", | 1004 } |
| 991 outputColor, dstColorName, dstColorName); | 1005 |
| 992 } else { | 1006 // These all perform src-over on the alpha channel. |
| 993 builder->fsCodeAppendf("\t\t%s.a = 1.0 - (1.0 - %s.a) * (1.0 - % s.a);\n", | 1007 builder->fsCodeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n", |
| 994 outputColor, dstColorName, inputColor); | 1008 outputColor, inputColor, inputColor, dstColo r); |
| 995 builder->fsCodeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.rgb + %s.rgb," | 1009 |
| 996 " (1.0 - %s.a) * %s.rgb + %s.rgb);\n", | 1010 switch (drawEffect.castEffect<XferEffect>().mode()) { |
| 997 outputColor, | 1011 case SkXfermode::kOverlay_Mode: |
| 998 inputColor, dstColorName, inputColor, | 1012 // Overlay is Hard-Light with the src and dst reversed |
| 999 dstColorName, inputColor, dstColorName); | 1013 HardLight(builder, outputColor, dstColor, inputColor); |
| 1014 break; | |
| 1015 case SkXfermode::kDarken_Mode: | |
| 1016 builder->fsCodeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.r gb + %s.rgb, " | |
| 1017 "(1.0 - %s.a) * %s.r gb + %s.rgb);\n", | |
| 1018 outputColor, | |
| 1019 inputColor, dstColor, inputColor, | |
| 1020 dstColor, inputColor, dstColor); | |
| 1021 break; | |
| 1022 case SkXfermode::kLighten_Mode: | |
| 1023 builder->fsCodeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.r gb + %s.rgb, " | |
| 1024 "(1.0 - %s.a) * %s.r gb + %s.rgb);\n", | |
| 1025 outputColor, | |
| 1026 inputColor, dstColor, inputColor, | |
| 1027 dstColor, inputColor, dstColor); | |
| 1028 break; | |
| 1029 case SkXfermode::kColorDodge_Mode: | |
| 1030 ColorDodgeComponent(builder, outputColor, inputColor, dstCol or, 'r'); | |
|
jvanverth1
2013/04/19 14:16:15
Is there a reason these (and following) are separa
bsalomon
2013/04/19 14:24:28
Just that they couldn't be easily be done vectored
| |
| 1031 ColorDodgeComponent(builder, outputColor, inputColor, dstCol or, 'g'); | |
| 1032 ColorDodgeComponent(builder, outputColor, inputColor, dstCol or, 'b'); | |
| 1033 break; | |
| 1034 case SkXfermode::kColorBurn_Mode: | |
| 1035 ColorBurnComponent(builder, outputColor, inputColor, dstColo r, 'r'); | |
| 1036 ColorBurnComponent(builder, outputColor, inputColor, dstColo r, 'g'); | |
| 1037 ColorBurnComponent(builder, outputColor, inputColor, dstColo r, 'b'); | |
| 1038 break; | |
| 1039 case SkXfermode::kHardLight_Mode: | |
| 1040 HardLight(builder, outputColor, inputColor, dstColor); | |
| 1041 break; | |
| 1042 case SkXfermode::kSoftLight_Mode: | |
| 1043 builder->fsCodeAppendf("\t\tif (0.0 == %s.a) {\n", dstColor) ; | |
| 1044 builder->fsCodeAppendf("\t\t\t%s.rgba = %s;\n", outputColor, inputColor); | |
| 1045 builder->fsCodeAppendf("\t\t} else {\n"); | |
| 1046 SoftLightComponentPosDstAlpha(builder, outputColor, inputCol or, dstColor, 'r'); | |
| 1047 SoftLightComponentPosDstAlpha(builder, outputColor, inputCol or, dstColor, 'g'); | |
| 1048 SoftLightComponentPosDstAlpha(builder, outputColor, inputCol or, dstColor, 'b'); | |
| 1049 builder->fsCodeAppendf("\t\t}\n"); | |
| 1050 break; | |
| 1051 case SkXfermode::kDifference_Mode: | |
| 1052 builder->fsCodeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb -" | |
| 1053 "2.0 * min(%s.rgb * %s.a, %s.rgb * %s.a);\n", | |
| 1054 outputColor, inputColor, dstColor, in putColor, dstColor, | |
| 1055 dstColor, inputColor); | |
| 1056 break; | |
| 1057 case SkXfermode::kExclusion_Mode: | |
| 1058 builder->fsCodeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb - " | |
| 1059 "2.0 * %s.rgb * %s.rgb;\ n", | |
| 1060 outputColor, dstColor, inputColor, ds tColor, inputColor); | |
| 1061 break; | |
| 1062 case SkXfermode::kMultiply_Mode: | |
| 1063 builder->fsCodeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + " | |
| 1064 "(1.0 - %s.a) * %s.rgb + " | |
| 1065 "%s.rgb * %s.rgb;\n", | |
| 1066 outputColor, inputColor, dstColor, ds tColor, inputColor, | |
| 1067 inputColor, dstColor); | |
| 1068 break; | |
| 1069 case SkXfermode::kHue_Mode: | |
| 1070 case SkXfermode::kSaturation_Mode: | |
| 1071 case SkXfermode::kColor_Mode: | |
| 1072 case SkXfermode::kLuminosity_Mode: | |
| 1073 GrCrash("Unimplemented XferEffect mode."); | |
| 1074 break; | |
| 1075 default: | |
| 1076 GrCrash("Unknown XferEffect mode."); | |
| 1077 break; | |
| 1000 } | 1078 } |
| 1001 } | 1079 } |
| 1002 | 1080 |
| 1003 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { r eturn 0; } | 1081 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) { |
| 1082 return drawEffect.castEffect<XferEffect>().mode(); | |
| 1083 } | |
| 1004 | 1084 |
| 1005 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_ OVERRIDE {} | 1085 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_ OVERRIDE {} |
| 1006 | 1086 |
| 1007 private: | 1087 private: |
| 1088 static void HardLight(GrGLShaderBuilder* builder, const char* final, con st char* src, const char* dst) { | |
| 1089 builder->fsCodeAppendf("\t\t%s.a = 1.0 - (1.0 - %s.a) * (1.0 - %s.a) ;\n", final, dst, src); | |
|
bsalomon
2013/04/19 13:59:21
I can wrap these, but I'm not sure that it helps a
jvanverth1
2013/04/19 14:16:15
It'd probably help to put the varargs on the follo
bsalomon
2013/04/19 14:24:28
will do
| |
| 1090 builder->fsCodeAppendf("\t\t%s.rgb = mix(2.0 * %s.rgb * %s.rgb, ", f inal, src, dst); | |
| 1091 builder->fsCodeAppendf("%s.aaa * %s.aaa - 2.0 * (%s.aaa - %s.rgb) * (%s.aaa - %s.rgb),", src, dst, dst, dst, src, src); | |
| 1092 builder->fsCodeAppendf("vec3(greaterThan(2.0 * %s.rgb, %s.aaa)));\n" , src, src); | |
| 1093 builder->fsCodeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb * (1.0 - %s.a);\n", final, src, dst, dst, src); | |
| 1094 } | |
| 1095 | |
| 1096 // Does one component of color-dodge | |
| 1097 static void ColorDodgeComponent(GrGLShaderBuilder* builder, const char* final, const char* src, const char* dst, const char component) { | |
|
jvanverth1
2013/04/19 14:16:15
Wrap function decls at least?
bsalomon
2013/04/19 14:24:28
will do
| |
| 1098 builder->fsCodeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component); | |
| 1099 builder->fsCodeAppendf("\t\t\t%s.%c = %s.%c * (1 - %s.a);\n", final, component, src, component, dst); | |
| 1100 builder->fsCodeAppend("\t\t} else {\n"); | |
| 1101 builder->fsCodeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src, component); | |
| 1102 builder->fsCodeAppend("\t\t\tif (0 == d) {\n"); | |
| 1103 builder->fsCodeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n", final, component, src, dst, src, component, d st, dst, component, src); | |
| 1104 builder->fsCodeAppend("\t\t\t} else {\n"); | |
| 1105 builder->fsCodeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n", dst, dst, component, src); | |
| 1106 builder->fsCodeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s .a) + %s.%c * (1.0 - %s.a);\n", final, component, src, src, component, dst, dst, component, src); | |
| 1107 builder->fsCodeAppend("\t\t\t}\n"); | |
| 1108 builder->fsCodeAppend("\t\t}\n"); | |
| 1109 } | |
| 1110 | |
| 1111 // Does one component of color-burn | |
| 1112 static void ColorBurnComponent(GrGLShaderBuilder* builder, const char* f inal, const char* src, const char* dst, const char component) { | |
| 1113 builder->fsCodeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, compo nent); | |
| 1114 builder->fsCodeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - % s.a) + %s.%c * (1.0 - %s.a);\n", final, component, src, dst, src, component, dst , dst, component, src); | |
| 1115 builder->fsCodeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, comp onent); | |
| 1116 builder->fsCodeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n", fina l, component, dst, component, src); | |
| 1117 builder->fsCodeAppend("\t\t} else {\n"); | |
| 1118 builder->fsCodeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.% c) * %s.a / %s.%c);\n", dst, dst, dst, component, src, src, component); | |
| 1119 builder->fsCodeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a ) + %s.%c * (1.0 - %s.a);\n", final, component, src, src, component, dst, dst, c omponent, src); | |
| 1120 builder->fsCodeAppend("\t\t}\n"); | |
| 1121 } | |
| 1122 | |
| 1123 // Does one component of soft-light. Caller should have already checked that dst alpha > 0. | |
| 1124 static void SoftLightComponentPosDstAlpha(GrGLShaderBuilder* builder, co nst char* final, const char* src, const char* dst, const char component) { | |
| 1125 // if (2S < Sa) | |
| 1126 builder->fsCodeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, co mponent, src); | |
| 1127 // (D^2 (Sa-2 S))/Da+(1-Da) S+D (-Sa+2 S+1) | |
| 1128 builder->fsCodeAppendf("\t\t\t\t%s.%c = (%s.%c*%s.%c*(%s.a - 2*%s.%c )) / %s.a + (1 - %s.a) * %s.%c + %s.%c*(-%s.a + 2*%s.%c + 1);\n", final, compone nt, dst, component, dst, component, src, src, component, dst, dst, src, componen t, dst, component, src, src, component); | |
| 1129 // else if (4D < Da) | |
| 1130 builder->fsCodeAppendf("\t\t\t} else if (4.0 * %s.%c <= %s.a) {\n", dst, component, dst); | |
| 1131 builder->fsCodeAppendf("\t\t\t\tfloat DSqd = %s.%c * %s.%c;\n", dst, component, dst, component); | |
| 1132 builder->fsCodeAppendf("\t\t\t\tfloat DCub = DSqd * %s.%c;\n", dst, component); | |
| 1133 builder->fsCodeAppendf("\t\t\t\tfloat DaSqd = %s.a * %s.a;\n", dst, dst); | |
| 1134 builder->fsCodeAppendf("\t\t\t\tfloat DaCub = DaSqd * %s.a;\n", dst) ; | |
| 1135 // (Da^3 (-S)+Da^2 (S-D (3 Sa-6 S-1))+12 Da D^2 (Sa-2 S)-16 D^3 (Sa- 2 S))/Da^2 | |
| 1136 builder->fsCodeAppendf("\t\t\t\t%s.%c = (-DaCub*%s.%c + DaSqd*(%s.%c - %s.%c * (3*%s.a - 6*%s.%c - 1)) + 12*%s.a*DSqd*(%s.a - 2*%s.%c) - 16*DCub * ( %s.a - 2*%s.%c)) / DaSqd;\n", final, component, src, component, src, component, dst, component, src, src, component, dst, src, src, component, src, src, compone nt); | |
| 1137 builder->fsCodeAppendf("\t\t\t} else {\n"); | |
| 1138 // -sqrt(Da * D) (Sa-2 S)-Da S+D (Sa-2 S+1)+S | |
| 1139 builder->fsCodeAppendf("\t\t\t\t%s.%c = -sqrt(%s.a*%s.%c)*(%s.a - 2* %s.%c) - %s.a*%s.%c + %s.%c*(%s.a - 2*%s.%c + 1) + %s.%c;\n", final, component, dst, dst, component, src, src, component, dst, src, component, dst, component, s rc, src, component, src, component); | |
| 1140 builder->fsCodeAppendf("\t\t\t}\n"); | |
| 1141 } | |
| 1142 | |
| 1008 typedef GrGLEffect INHERITED; | 1143 typedef GrGLEffect INHERITED; |
| 1009 }; | 1144 }; |
| 1010 | 1145 |
| 1011 GR_DECLARE_EFFECT_TEST; | 1146 GR_DECLARE_EFFECT_TEST; |
| 1012 | 1147 |
| 1013 private: | 1148 private: |
| 1014 DarkenEffect() { this->setWillReadDst(); } | 1149 XferEffect(SkXfermode::Mode mode) : fMode(mode) { this->setWillReadDst(); } |
| 1015 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { return tru e; } | 1150 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { return tru e; } |
| 1151 | |
| 1152 SkXfermode::Mode fMode; | |
| 1016 | 1153 |
| 1017 typedef GrEffect INHERITED; | 1154 typedef GrEffect INHERITED; |
| 1018 }; | 1155 }; |
| 1019 | 1156 |
| 1020 GR_DEFINE_EFFECT_TEST(DarkenEffect); | 1157 GR_DEFINE_EFFECT_TEST(XferEffect); |
| 1021 GrEffectRef* DarkenEffect::TestCreate(SkMWCRandom*, | 1158 GrEffectRef* XferEffect::TestCreate(SkMWCRandom* rand, |
| 1022 GrContext*, | 1159 GrContext*, |
| 1023 const GrDrawTargetCaps&, | 1160 const GrDrawTargetCaps&, |
| 1024 GrTexture*[]) { | 1161 GrTexture*[]) { |
| 1025 static AutoEffectUnref gEffect(SkNEW(DarkenEffect)); | 1162 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas tSeparableMode); |
| 1163 static AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermod e::Mode>(mode)))); | |
| 1026 return CreateEffectRef(gEffect); | 1164 return CreateEffectRef(gEffect); |
| 1027 } | 1165 } |
| 1028 | 1166 |
| 1029 #endif | 1167 #endif |
| 1030 | 1168 |
| 1031 /////////////////////////////////////////////////////////////////////////////// | 1169 /////////////////////////////////////////////////////////////////////////////// |
| 1032 /////////////////////////////////////////////////////////////////////////////// | 1170 /////////////////////////////////////////////////////////////////////////////// |
| 1033 | 1171 |
| 1034 class SkProcCoeffXfermode : public SkProcXfermode { | 1172 class SkProcCoeffXfermode : public SkProcXfermode { |
| 1035 public: | 1173 public: |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 1063 } | 1201 } |
| 1064 | 1202 |
| 1065 #if SK_SUPPORT_GPU | 1203 #if SK_SUPPORT_GPU |
| 1066 virtual bool asNewEffectOrCoeff(GrContext*, | 1204 virtual bool asNewEffectOrCoeff(GrContext*, |
| 1067 GrEffectRef** effect, | 1205 GrEffectRef** effect, |
| 1068 Coeff* src, | 1206 Coeff* src, |
| 1069 Coeff* dst) const SK_OVERRIDE { | 1207 Coeff* dst) const SK_OVERRIDE { |
| 1070 if (this->asCoeff(src, dst)) { | 1208 if (this->asCoeff(src, dst)) { |
| 1071 return true; | 1209 return true; |
| 1072 } | 1210 } |
| 1073 if (kDarken_Mode == fMode) { | 1211 if (XferEffect::IsSupportedMode(fMode)) { |
| 1074 if (NULL != effect) { | 1212 if (NULL != effect) { |
| 1075 *effect = DarkenEffect::Create(); | 1213 *effect = XferEffect::Create(fMode); |
| 1214 SkASSERT(NULL != *effect); | |
| 1076 } | 1215 } |
| 1077 return true; | 1216 return true; |
| 1078 } | 1217 } |
| 1079 return false; | 1218 return false; |
| 1080 } | 1219 } |
| 1081 #endif | 1220 #endif |
| 1082 | 1221 |
| 1083 SK_DEVELOPER_TO_STRING() | 1222 SK_DEVELOPER_TO_STRING() |
| 1084 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) | 1223 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) |
| 1085 | 1224 |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1618 return proc16; | 1757 return proc16; |
| 1619 } | 1758 } |
| 1620 | 1759 |
| 1621 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1760 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
| 1622 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1761 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
| 1623 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) | 1762 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) |
| 1624 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) | 1763 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) |
| 1625 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) | 1764 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) |
| 1626 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) | 1765 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) |
| 1627 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1766 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |