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 |