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_opts_SSE2.h" | 10 #include "SkXfermode_opts_SSE2.h" |
(...skipping 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1225 * SkPMFloat::isValid(), as that would fire sometimes, but not result in a bad
pixel. | 1225 * SkPMFloat::isValid(), as that would fire sometimes, but not result in a bad
pixel. |
1226 */ | 1226 */ |
1227 static inline SkPMFloat check_as_pmfloat(const Sk4f& value) { | 1227 static inline SkPMFloat check_as_pmfloat(const Sk4f& value) { |
1228 SkPMFloat pm = value; | 1228 SkPMFloat pm = value; |
1229 #ifdef SK_DEBUG | 1229 #ifdef SK_DEBUG |
1230 (void)pm.round(); | 1230 (void)pm.round(); |
1231 #endif | 1231 #endif |
1232 return pm; | 1232 return pm; |
1233 } | 1233 } |
1234 | 1234 |
| 1235 #define XFERMODE(Name) \ |
| 1236 struct Name { \ |
| 1237 static Sk4px Xfer(const Sk4px&, const Sk4px&); \ |
| 1238 static const SkXfermode::Mode kMode = SkXfermode::k##Name##_Mode; \ |
| 1239 }; \ |
| 1240 inline Sk4px Name::Xfer(const Sk4px& s, const Sk4px& d) |
| 1241 |
| 1242 XFERMODE(Clear) { return Sk4px((SkPMColor)0); } |
| 1243 XFERMODE(Src) { return s; } |
| 1244 XFERMODE(Dst) { return d; } |
| 1245 XFERMODE(SrcIn) { return s.fastMulDiv255Round(d.alphas() ); } |
| 1246 XFERMODE(SrcOut) { return s.fastMulDiv255Round(d.alphas().inv()); } |
| 1247 XFERMODE(SrcOver) { return s + d.fastMulDiv255Round(s.alphas().inv()); } |
| 1248 XFERMODE(DstIn) { return SrcIn ::Xfer(d,s); } |
| 1249 XFERMODE(DstOut) { return SrcOut ::Xfer(d,s); } |
| 1250 XFERMODE(DstOver) { return SrcOver::Xfer(d,s); } |
| 1251 |
| 1252 #undef XFERMODE |
| 1253 |
1235 // kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] | 1254 // kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] |
1236 struct SrcATop4f { | 1255 struct SrcATop4f { |
1237 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1256 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1238 const Sk4f inv255(gInv255); | 1257 const Sk4f inv255(gInv255); |
1239 return check_as_pmfloat(dst + (src * Sk4f(dst.a()) - dst * Sk4f(src.a())
) * inv255); | 1258 return check_as_pmfloat(dst + (src * Sk4f(dst.a()) - dst * Sk4f(src.a())
) * inv255); |
1240 } | 1259 } |
1241 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { | 1260 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
1242 return Sk4px::Wide(src.mulWiden(dst.alphas()) + dst.mulWiden(src.alphas(
).inv())) | 1261 return Sk4px::Wide(src.mulWiden(dst.alphas()) + dst.mulWiden(src.alphas(
).inv())) |
1243 .div255RoundNarrow(); | 1262 .div255RoundNarrow(); |
1244 } | 1263 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 static const SkXfermode::Mode kMode = SkXfermode::kPlus_Mode; | 1303 static const SkXfermode::Mode kMode = SkXfermode::kPlus_Mode; |
1285 }; | 1304 }; |
1286 | 1305 |
1287 // kModulate_Mode [Sa * Da, Sc * Dc] | 1306 // kModulate_Mode [Sa * Da, Sc * Dc] |
1288 struct Modulate4f { | 1307 struct Modulate4f { |
1289 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1308 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1290 const Sk4f inv255(gInv255); | 1309 const Sk4f inv255(gInv255); |
1291 return check_as_pmfloat(src * dst * inv255); | 1310 return check_as_pmfloat(src * dst * inv255); |
1292 } | 1311 } |
1293 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { | 1312 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
1294 return src.mulWiden(dst).div255RoundNarrow(); | 1313 return src.fastMulDiv255Round(dst); |
1295 } | 1314 } |
1296 static const bool kFoldCoverageIntoSrcAlpha = false; | 1315 static const bool kFoldCoverageIntoSrcAlpha = false; |
1297 static const SkXfermode::Mode kMode = SkXfermode::kModulate_Mode; | 1316 static const SkXfermode::Mode kMode = SkXfermode::kModulate_Mode; |
1298 }; | 1317 }; |
1299 | 1318 |
1300 // kScreen_Mode [S + D - S * D] | 1319 // kScreen_Mode [S + D - S * D] |
1301 struct Screen4f { | 1320 struct Screen4f { |
1302 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1321 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1303 const Sk4f inv255(gInv255); | 1322 const Sk4f inv255(gInv255); |
1304 return check_as_pmfloat(src + dst - src * dst * inv255); | 1323 return check_as_pmfloat(src + dst - src * dst * inv255); |
1305 } | 1324 } |
1306 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { | 1325 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
1307 // Doing the math as S + (1-S)*D or S + (D - S*D) means the add and subt
ract can be done | 1326 // Doing the math as S + (1-S)*D or S + (D - S*D) means the add and subt
ract can be done |
1308 // in 8-bit space without overflow. S + (1-S)*D is a touch faster becau
se inv() is cheap. | 1327 // in 8-bit space without overflow. S + (1-S)*D is a touch faster becau
se inv() is cheap. |
1309 return src + src.inv().mulWiden(dst).div255RoundNarrow(); | 1328 return src + dst.fastMulDiv255Round(src.inv()); |
1310 } | 1329 } |
1311 static const bool kFoldCoverageIntoSrcAlpha = true; | 1330 static const bool kFoldCoverageIntoSrcAlpha = true; |
1312 static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode; | 1331 static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode; |
1313 }; | 1332 }; |
1314 | 1333 |
1315 struct Multiply4f { | 1334 struct Multiply4f { |
1316 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1335 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1317 const Sk4f inv255(gInv255); | 1336 const Sk4f inv255(gInv255); |
1318 Sk4f sa = Sk4f(src.a()); | 1337 Sk4f sa = Sk4f(src.a()); |
1319 Sk4f da = Sk4f(dst.a()); | 1338 Sk4f da = Sk4f(dst.a()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1359 struct Exclusion4f { | 1378 struct Exclusion4f { |
1360 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1379 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1361 const Sk4f inv255(gInv255); | 1380 const Sk4f inv255(gInv255); |
1362 Sk4f sc = src; | 1381 Sk4f sc = src; |
1363 Sk4f dc = dst; | 1382 Sk4f dc = dst; |
1364 Sk4f prod = sc * dc * inv255; | 1383 Sk4f prod = sc * dc * inv255; |
1365 Sk4f ra = sc + dc - prod; | 1384 Sk4f ra = sc + dc - prod; |
1366 return check_as_pmfloat(ra - prod * SkPMFloat(0, 1, 1, 1)); | 1385 return check_as_pmfloat(ra - prod * SkPMFloat(0, 1, 1, 1)); |
1367 } | 1386 } |
1368 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { | 1387 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
1369 auto p = src.mulWiden(dst).div255RoundNarrow(); | 1388 auto p = src.fastMulDiv255Round(dst); |
1370 // There's no chance of underflow, and if we subtract p before adding sr
c+dst, no overflow. | 1389 // There's no chance of underflow, and if we subtract p before adding sr
c+dst, no overflow. |
1371 return (src - p) + (dst - p.zeroAlphas()); | 1390 return (src - p) + (dst - p.zeroAlphas()); |
1372 } | 1391 } |
1373 static const bool kFoldCoverageIntoSrcAlpha = false; | 1392 static const bool kFoldCoverageIntoSrcAlpha = false; |
1374 static const SkXfermode::Mode kMode = SkXfermode::kExclusion_Mode; | 1393 static const SkXfermode::Mode kMode = SkXfermode::kExclusion_Mode; |
1375 }; | 1394 }; |
1376 | 1395 |
1377 template <typename ProcType> | 1396 template <typename ProcType> |
1378 class SkT4fXfermode : public SkProcCoeffXfermode { | 1397 class SkT4fXfermode : public SkProcCoeffXfermode { |
1379 public: | 1398 public: |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1493 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; | 1512 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; |
1494 | 1513 |
1495 ProcCoeff rec = gProcCoeffs[mode]; | 1514 ProcCoeff rec = gProcCoeffs[mode]; |
1496 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); | 1515 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); |
1497 if (pp != NULL) { | 1516 if (pp != NULL) { |
1498 rec.fProc = pp; | 1517 rec.fProc = pp; |
1499 } | 1518 } |
1500 | 1519 |
1501 #if defined(SK_4PX_XFERMODES_ARE_FAST) && !defined(SK_PREFER_LEGACY_FLOAT_XFERMO
DES) | 1520 #if defined(SK_4PX_XFERMODES_ARE_FAST) && !defined(SK_PREFER_LEGACY_FLOAT_XFERMO
DES) |
1502 switch (mode) { | 1521 switch (mode) { |
| 1522 case SkXfermode::kClear_Mode: return SkT4pxXfermode<Clear>::Create(
rec); |
| 1523 case SkXfermode::kSrc_Mode: return SkT4pxXfermode<Src>::Create(re
c); |
| 1524 case SkXfermode::kDst_Mode: return SkT4pxXfermode<Dst>::Create(re
c); |
| 1525 case SkXfermode::kSrcOver_Mode: return SkT4pxXfermode<SrcOver>::Creat
e(rec); |
| 1526 case SkXfermode::kDstOver_Mode: return SkT4pxXfermode<DstOver>::Creat
e(rec); |
| 1527 case SkXfermode::kSrcIn_Mode: return SkT4pxXfermode<SrcIn>::Create(
rec); |
| 1528 case SkXfermode::kDstIn_Mode: return SkT4pxXfermode<DstIn>::Create(
rec); |
| 1529 case SkXfermode::kSrcOut_Mode: return SkT4pxXfermode<SrcOut>::Create
(rec); |
| 1530 case SkXfermode::kDstOut_Mode: return SkT4pxXfermode<DstOut>::Create
(rec); |
| 1531 |
1503 case SkXfermode::kSrcATop_Mode: return SkT4pxXfermode<SrcATop4f>::Cre
ate(rec); | 1532 case SkXfermode::kSrcATop_Mode: return SkT4pxXfermode<SrcATop4f>::Cre
ate(rec); |
1504 case SkXfermode::kDstATop_Mode: return SkT4pxXfermode<DstATop4f>::Cre
ate(rec); | 1533 case SkXfermode::kDstATop_Mode: return SkT4pxXfermode<DstATop4f>::Cre
ate(rec); |
1505 case SkXfermode::kXor_Mode: return SkT4pxXfermode<Xor4f>::Create(
rec); | 1534 case SkXfermode::kXor_Mode: return SkT4pxXfermode<Xor4f>::Create(
rec); |
1506 case SkXfermode::kPlus_Mode: return SkT4pxXfermode<Plus4f>::Create
(rec); | 1535 case SkXfermode::kPlus_Mode: return SkT4pxXfermode<Plus4f>::Create
(rec); |
1507 case SkXfermode::kModulate_Mode: return SkT4pxXfermode<Modulate4f>::Cr
eate(rec); | 1536 case SkXfermode::kModulate_Mode: return SkT4pxXfermode<Modulate4f>::Cr
eate(rec); |
1508 case SkXfermode::kScreen_Mode: return SkT4pxXfermode<Screen4f>::Crea
te(rec); | 1537 case SkXfermode::kScreen_Mode: return SkT4pxXfermode<Screen4f>::Crea
te(rec); |
1509 case SkXfermode::kMultiply_Mode: return SkT4pxXfermode<Multiply4f>::Cr
eate(rec); | 1538 case SkXfermode::kMultiply_Mode: return SkT4pxXfermode<Multiply4f>::Cr
eate(rec); |
1510 case SkXfermode::kDifference_Mode: return SkT4pxXfermode<Difference4f>::
Create(rec); | 1539 case SkXfermode::kDifference_Mode: return SkT4pxXfermode<Difference4f>::
Create(rec); |
1511 case SkXfermode::kExclusion_Mode: return SkT4pxXfermode<Exclusion4f>::C
reate(rec); | 1540 case SkXfermode::kExclusion_Mode: return SkT4pxXfermode<Exclusion4f>::C
reate(rec); |
1512 default: break; | 1541 default: break; |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1821 } else { | 1850 } else { |
1822 proc16 = rec.fProc16_General; | 1851 proc16 = rec.fProc16_General; |
1823 } | 1852 } |
1824 } | 1853 } |
1825 return proc16; | 1854 return proc16; |
1826 } | 1855 } |
1827 | 1856 |
1828 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1857 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
1829 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1858 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
1830 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1859 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |