| 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 #include "SkXfermode.h" | 9 #include "SkXfermode.h" |
| 10 #include "SkXfermode_proccoeff.h" | 10 #include "SkXfermode_proccoeff.h" |
| (...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 | 989 |
| 990 str->append(" dst: "); | 990 str->append(" dst: "); |
| 991 if (CANNOT_USE_COEFF == fDstCoeff) { | 991 if (CANNOT_USE_COEFF == fDstCoeff) { |
| 992 str->append("can't use"); | 992 str->append("can't use"); |
| 993 } else { | 993 } else { |
| 994 str->append(gCoeffStrings[fDstCoeff]); | 994 str->append(gCoeffStrings[fDstCoeff]); |
| 995 } | 995 } |
| 996 } | 996 } |
| 997 #endif | 997 #endif |
| 998 | 998 |
| 999 /////////////////////////////////////////////////////////////////////////////// | |
| 1000 | |
| 1001 class SkClearXfermode : public SkProcCoeffXfermode { | |
| 1002 public: | |
| 1003 static SkClearXfermode* Create(const ProcCoeff& rec) { | |
| 1004 return SkNEW_ARGS(SkClearXfermode, (rec)); | |
| 1005 } | |
| 1006 | |
| 1007 void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const overrid
e; | |
| 1008 void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const override; | |
| 1009 | |
| 1010 SK_TO_STRING_OVERRIDE() | |
| 1011 | |
| 1012 private: | |
| 1013 SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode
) {} | |
| 1014 | |
| 1015 typedef SkProcCoeffXfermode INHERITED; | |
| 1016 }; | |
| 1017 | |
| 1018 void SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst, | |
| 1019 const SkPMColor* SK_RESTRICT, int count, | |
| 1020 const SkAlpha* SK_RESTRICT aa) const { | |
| 1021 SkASSERT(dst && count >= 0); | |
| 1022 | |
| 1023 if (NULL == aa) { | |
| 1024 memset(dst, 0, count << 2); | |
| 1025 } else { | |
| 1026 for (int i = count - 1; i >= 0; --i) { | |
| 1027 unsigned a = aa[i]; | |
| 1028 if (0xFF == a) { | |
| 1029 dst[i] = 0; | |
| 1030 } else if (a != 0) { | |
| 1031 dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a)); | |
| 1032 } | |
| 1033 } | |
| 1034 } | |
| 1035 } | |
| 1036 void SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst, | |
| 1037 const SkPMColor* SK_RESTRICT, int count, | |
| 1038 const SkAlpha* SK_RESTRICT aa) const { | |
| 1039 SkASSERT(dst && count >= 0); | |
| 1040 | |
| 1041 if (NULL == aa) { | |
| 1042 memset(dst, 0, count); | |
| 1043 } else { | |
| 1044 for (int i = count - 1; i >= 0; --i) { | |
| 1045 unsigned a = aa[i]; | |
| 1046 if (0xFF == a) { | |
| 1047 dst[i] = 0; | |
| 1048 } else if (0 != a) { | |
| 1049 dst[i] = SkAlphaMulAlpha(dst[i], 255 - a); | |
| 1050 } | |
| 1051 } | |
| 1052 } | |
| 1053 } | |
| 1054 | |
| 1055 #ifndef SK_IGNORE_TO_STRING | |
| 1056 void SkClearXfermode::toString(SkString* str) const { | |
| 1057 this->INHERITED::toString(str); | |
| 1058 } | |
| 1059 #endif | |
| 1060 | |
| 1061 /////////////////////////////////////////////////////////////////////////////// | |
| 1062 | |
| 1063 class SkSrcXfermode : public SkProcCoeffXfermode { | |
| 1064 public: | |
| 1065 static SkSrcXfermode* Create(const ProcCoeff& rec) { | |
| 1066 return SkNEW_ARGS(SkSrcXfermode, (rec)); | |
| 1067 } | |
| 1068 | |
| 1069 void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const overrid
e; | |
| 1070 void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const override; | |
| 1071 | |
| 1072 SK_TO_STRING_OVERRIDE() | |
| 1073 | |
| 1074 private: | |
| 1075 SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {} | |
| 1076 typedef SkProcCoeffXfermode INHERITED; | |
| 1077 }; | |
| 1078 | |
| 1079 void SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, | |
| 1080 const SkPMColor* SK_RESTRICT src, int count, | |
| 1081 const SkAlpha* SK_RESTRICT aa) const { | |
| 1082 SkASSERT(dst && src && count >= 0); | |
| 1083 | |
| 1084 if (NULL == aa) { | |
| 1085 memcpy(dst, src, count << 2); | |
| 1086 } else { | |
| 1087 for (int i = count - 1; i >= 0; --i) { | |
| 1088 unsigned a = aa[i]; | |
| 1089 if (a == 0xFF) { | |
| 1090 dst[i] = src[i]; | |
| 1091 } else if (a != 0) { | |
| 1092 dst[i] = SkFourByteInterp(src[i], dst[i], a); | |
| 1093 } | |
| 1094 } | |
| 1095 } | |
| 1096 } | |
| 1097 | |
| 1098 void SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, | |
| 1099 const SkPMColor* SK_RESTRICT src, int count, | |
| 1100 const SkAlpha* SK_RESTRICT aa) const { | |
| 1101 SkASSERT(dst && src && count >= 0); | |
| 1102 | |
| 1103 if (NULL == aa) { | |
| 1104 for (int i = count - 1; i >= 0; --i) { | |
| 1105 dst[i] = SkToU8(SkGetPackedA32(src[i])); | |
| 1106 } | |
| 1107 } else { | |
| 1108 for (int i = count - 1; i >= 0; --i) { | |
| 1109 unsigned a = aa[i]; | |
| 1110 if (0 != a) { | |
| 1111 unsigned srcA = SkGetPackedA32(src[i]); | |
| 1112 if (a == 0xFF) { | |
| 1113 dst[i] = SkToU8(srcA); | |
| 1114 } else { | |
| 1115 dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a)); | |
| 1116 } | |
| 1117 } | |
| 1118 } | |
| 1119 } | |
| 1120 } | |
| 1121 #ifndef SK_IGNORE_TO_STRING | |
| 1122 void SkSrcXfermode::toString(SkString* str) const { | |
| 1123 this->INHERITED::toString(str); | |
| 1124 } | |
| 1125 #endif | |
| 1126 | |
| 1127 /////////////////////////////////////////////////////////////////////////////// | |
| 1128 | |
| 1129 class SkDstInXfermode : public SkProcCoeffXfermode { | |
| 1130 public: | |
| 1131 static SkDstInXfermode* Create(const ProcCoeff& rec) { | |
| 1132 return SkNEW_ARGS(SkDstInXfermode, (rec)); | |
| 1133 } | |
| 1134 | |
| 1135 void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const overrid
e; | |
| 1136 | |
| 1137 SK_TO_STRING_OVERRIDE() | |
| 1138 | |
| 1139 private: | |
| 1140 SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode
) {} | |
| 1141 | |
| 1142 typedef SkProcCoeffXfermode INHERITED; | |
| 1143 }; | |
| 1144 | |
| 1145 void SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst, | |
| 1146 const SkPMColor* SK_RESTRICT src, int count, | |
| 1147 const SkAlpha* SK_RESTRICT aa) const { | |
| 1148 SkASSERT(dst && src); | |
| 1149 | |
| 1150 if (count <= 0) { | |
| 1151 return; | |
| 1152 } | |
| 1153 if (aa) { | |
| 1154 return this->INHERITED::xfer32(dst, src, count, aa); | |
| 1155 } | |
| 1156 | |
| 1157 do { | |
| 1158 unsigned a = SkGetPackedA32(*src); | |
| 1159 *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a)); | |
| 1160 dst++; | |
| 1161 src++; | |
| 1162 } while (--count != 0); | |
| 1163 } | |
| 1164 | |
| 1165 #ifndef SK_IGNORE_TO_STRING | |
| 1166 void SkDstInXfermode::toString(SkString* str) const { | |
| 1167 this->INHERITED::toString(str); | |
| 1168 } | |
| 1169 #endif | |
| 1170 | |
| 1171 /////////////////////////////////////////////////////////////////////////////// | |
| 1172 | |
| 1173 /////////////////////////////////////////////////////////////////////////////// | |
| 1174 | |
| 1175 class SkDstOutXfermode : public SkProcCoeffXfermode { | |
| 1176 public: | |
| 1177 static SkDstOutXfermode* Create(const ProcCoeff& rec) { | |
| 1178 return SkNEW_ARGS(SkDstOutXfermode, (rec)); | |
| 1179 } | |
| 1180 | |
| 1181 void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const overrid
e; | |
| 1182 | |
| 1183 SK_TO_STRING_OVERRIDE() | |
| 1184 | |
| 1185 private: | |
| 1186 SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mo
de) {} | |
| 1187 | |
| 1188 typedef SkProcCoeffXfermode INHERITED; | |
| 1189 }; | |
| 1190 | |
| 1191 void SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst, | |
| 1192 const SkPMColor* SK_RESTRICT src, int count, | |
| 1193 const SkAlpha* SK_RESTRICT aa) const { | |
| 1194 SkASSERT(dst && src); | |
| 1195 | |
| 1196 if (count <= 0) { | |
| 1197 return; | |
| 1198 } | |
| 1199 if (aa) { | |
| 1200 return this->INHERITED::xfer32(dst, src, count, aa); | |
| 1201 } | |
| 1202 | |
| 1203 do { | |
| 1204 unsigned a = SkGetPackedA32(*src); | |
| 1205 *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a)); | |
| 1206 dst++; | |
| 1207 src++; | |
| 1208 } while (--count != 0); | |
| 1209 } | |
| 1210 | |
| 1211 #ifndef SK_IGNORE_TO_STRING | |
| 1212 void SkDstOutXfermode::toString(SkString* str) const { | |
| 1213 this->INHERITED::toString(str); | |
| 1214 } | |
| 1215 #endif | |
| 1216 | |
| 1217 /////////////////////////////////////////////////////////////////////////////// | |
| 1218 | 999 |
| 1219 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, SkXf
ermode::Mode mode); | 1000 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, SkXf
ermode::Mode mode); |
| 1220 extern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode); | 1001 extern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode); |
| 1221 | 1002 |
| 1222 // Technically, can't be static and passed as a template parameter. So we use a
nonymous namespace. | 1003 // Technically, can't be static and passed as a template parameter. So we use a
nonymous namespace. |
| 1223 namespace { | 1004 namespace { |
| 1224 SkXfermode* create_mode(int iMode) { | 1005 SkXfermode* create_mode(int iMode) { |
| 1225 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; | 1006 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; |
| 1226 | 1007 |
| 1227 ProcCoeff rec = gProcCoeffs[mode]; | 1008 ProcCoeff rec = gProcCoeffs[mode]; |
| 1228 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); | 1009 if (auto proc = SkPlatformXfermodeProcFactory(mode)) { |
| 1229 if (pp != NULL) { | 1010 rec.fProc = proc; |
| 1230 rec.fProc = pp; | |
| 1231 } | 1011 } |
| 1232 | 1012 |
| 1013 // Check for compile-time SIMD xfermode. |
| 1233 if (auto xfermode = SkCreate4pxXfermode(rec, mode)) { | 1014 if (auto xfermode = SkCreate4pxXfermode(rec, mode)) { |
| 1234 return xfermode; | 1015 return xfermode; |
| 1235 } | 1016 } |
| 1236 | 1017 |
| 1237 SkXfermode* xfer = NULL; | 1018 // Check for runtime-detected SIMD xfermode. |
| 1019 if (auto xfermode = SkPlatformXfermodeFactory(rec, mode)) { |
| 1020 return xfermode; |
| 1021 } |
| 1238 | 1022 |
| 1239 // check if we have a platform optim for that | 1023 // Serial fallback. |
| 1240 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); | 1024 return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); |
| 1241 if (xfm != NULL) { | |
| 1242 xfer = xfm; | |
| 1243 } else { | |
| 1244 // All modes can in theory be represented by the ProcCoeff rec, since | |
| 1245 // it contains function ptrs. However, a few modes are both simple and | |
| 1246 // commonly used, so we call those out for their own subclasses here. | |
| 1247 switch (mode) { | |
| 1248 case SkXfermode::kClear_Mode: | |
| 1249 xfer = SkClearXfermode::Create(rec); | |
| 1250 break; | |
| 1251 case SkXfermode::kSrc_Mode: | |
| 1252 xfer = SkSrcXfermode::Create(rec); | |
| 1253 break; | |
| 1254 case SkXfermode::kSrcOver_Mode: | |
| 1255 SkASSERT(false); // should not land here | |
| 1256 break; | |
| 1257 case SkXfermode::kDstIn_Mode: | |
| 1258 xfer = SkDstInXfermode::Create(rec); | |
| 1259 break; | |
| 1260 case SkXfermode::kDstOut_Mode: | |
| 1261 xfer = SkDstOutXfermode::Create(rec); | |
| 1262 break; | |
| 1263 default: | |
| 1264 // no special-case, just rely in the rec and its function-ptrs | |
| 1265 xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); | |
| 1266 break; | |
| 1267 } | |
| 1268 } | |
| 1269 return xfer; | |
| 1270 } | 1025 } |
| 1271 } // namespace | 1026 } // namespace |
| 1272 | 1027 |
| 1273 SK_DECLARE_STATIC_LAZY_PTR_ARRAY(SkXfermode, cached, SkXfermode::kLastMode + 1,
create_mode); | 1028 SK_DECLARE_STATIC_LAZY_PTR_ARRAY(SkXfermode, cached, SkXfermode::kLastMode + 1,
create_mode); |
| 1274 | 1029 |
| 1275 SkXfermode* SkXfermode::Create(Mode mode) { | 1030 SkXfermode* SkXfermode::Create(Mode mode) { |
| 1276 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); | 1031 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); |
| 1277 | 1032 |
| 1278 if ((unsigned)mode >= kModeCount) { | 1033 if ((unsigned)mode >= kModeCount) { |
| 1279 // report error | 1034 // report error |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1527 } else { | 1282 } else { |
| 1528 proc16 = rec.fProc16_General; | 1283 proc16 = rec.fProc16_General; |
| 1529 } | 1284 } |
| 1530 } | 1285 } |
| 1531 return proc16; | 1286 return proc16; |
| 1532 } | 1287 } |
| 1533 | 1288 |
| 1534 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1289 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
| 1535 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1290 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
| 1536 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1291 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |