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 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 #endif | 1231 #endif |
1232 return pm; | 1232 return pm; |
1233 } | 1233 } |
1234 | 1234 |
1235 // kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] | 1235 // kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] |
1236 struct SrcATop4f { | 1236 struct SrcATop4f { |
1237 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1237 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1238 const Sk4f inv255(gInv255); | 1238 const Sk4f inv255(gInv255); |
1239 return check_as_pmfloat(dst + (src * Sk4f(dst.a()) - dst * Sk4f(src.a())
) * inv255); | 1239 return check_as_pmfloat(dst + (src * Sk4f(dst.a()) - dst * Sk4f(src.a())
) * inv255); |
1240 } | 1240 } |
| 1241 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
| 1242 return Sk4px::Wide(src.mulWiden(dst.alphas()) + dst.mulWiden(src.alphas(
).inv())) |
| 1243 .div255RoundNarrow(); |
| 1244 } |
1241 static const bool kFoldCoverageIntoSrcAlpha = true; | 1245 static const bool kFoldCoverageIntoSrcAlpha = true; |
1242 static const SkXfermode::Mode kMode = SkXfermode::kSrcATop_Mode; | 1246 static const SkXfermode::Mode kMode = SkXfermode::kSrcATop_Mode; |
1243 }; | 1247 }; |
1244 | 1248 |
1245 // kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] | 1249 // kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] |
1246 struct DstATop4f { | 1250 struct DstATop4f { |
1247 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1251 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1248 const Sk4f inv255(gInv255); | 1252 return SrcATop4f::Xfer(dst, src); |
1249 return check_as_pmfloat(src + (dst * Sk4f(src.a()) - src * Sk4f(dst.a())
) * inv255); | 1253 } |
| 1254 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
| 1255 return SrcATop4f::Xfer(dst, src); |
1250 } | 1256 } |
1251 static const bool kFoldCoverageIntoSrcAlpha = false; | 1257 static const bool kFoldCoverageIntoSrcAlpha = false; |
1252 static const SkXfermode::Mode kMode = SkXfermode::kDstATop_Mode; | 1258 static const SkXfermode::Mode kMode = SkXfermode::kDstATop_Mode; |
1253 }; | 1259 }; |
1254 | 1260 |
1255 // kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] | 1261 // kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] |
1256 struct Xor4f { | 1262 struct Xor4f { |
1257 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1263 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1258 const Sk4f inv255(gInv255); | 1264 const Sk4f inv255(gInv255); |
1259 return check_as_pmfloat(src + dst - (src * Sk4f(dst.a()) + dst * Sk4f(sr
c.a())) * inv255); | 1265 return check_as_pmfloat(src + dst - (src * Sk4f(dst.a()) + dst * Sk4f(sr
c.a())) * inv255); |
1260 } | 1266 } |
| 1267 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
| 1268 return Sk4px::Wide(src.mulWiden(dst.alphas().inv()) + dst.mulWiden(src.a
lphas().inv())) |
| 1269 .div255RoundNarrow(); |
| 1270 } |
1261 static const bool kFoldCoverageIntoSrcAlpha = true; | 1271 static const bool kFoldCoverageIntoSrcAlpha = true; |
1262 static const SkXfermode::Mode kMode = SkXfermode::kXor_Mode; | 1272 static const SkXfermode::Mode kMode = SkXfermode::kXor_Mode; |
1263 }; | 1273 }; |
1264 | 1274 |
1265 // kPlus_Mode [Sa + Da, Sc + Dc] | 1275 // kPlus_Mode [Sa + Da, Sc + Dc] |
1266 struct Plus4f { | 1276 struct Plus4f { |
1267 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1277 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1268 return check_as_pmfloat(clamp_255(src + dst)); | 1278 return check_as_pmfloat(clamp_255(src + dst)); |
1269 } | 1279 } |
1270 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { | 1280 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
(...skipping 17 matching lines...) Expand all Loading... |
1288 }; | 1298 }; |
1289 | 1299 |
1290 // kScreen_Mode [S + D - S * D] | 1300 // kScreen_Mode [S + D - S * D] |
1291 struct Screen4f { | 1301 struct Screen4f { |
1292 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1302 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1293 const Sk4f inv255(gInv255); | 1303 const Sk4f inv255(gInv255); |
1294 return check_as_pmfloat(src + dst - src * dst * inv255); | 1304 return check_as_pmfloat(src + dst - src * dst * inv255); |
1295 } | 1305 } |
1296 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { | 1306 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
1297 // Doing the math as S + (1-S)*D or S + (D - S*D) means the add and subt
ract can be done | 1307 // Doing the math as S + (1-S)*D or S + (D - S*D) means the add and subt
ract can be done |
1298 // in 8-bit space without overflow. S + (1-S)*D is a touch faster becau
se 255-x is an xor. | 1308 // in 8-bit space without overflow. S + (1-S)*D is a touch faster becau
se inv() is cheap. |
1299 // TODO: do we need to explicitly implement / call Sk16b(255) ^ src ? | 1309 return src + src.inv().mulWiden(dst).div255RoundNarrow(); |
1300 return src + Sk4px(Sk16b(255) - src).mulWiden(dst).div255RoundNarrow(); | |
1301 } | 1310 } |
1302 static const bool kFoldCoverageIntoSrcAlpha = true; | 1311 static const bool kFoldCoverageIntoSrcAlpha = true; |
1303 static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode; | 1312 static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode; |
1304 }; | 1313 }; |
1305 | 1314 |
1306 struct Multiply4f { | 1315 struct Multiply4f { |
1307 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1316 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1308 const Sk4f inv255(gInv255); | 1317 const Sk4f inv255(gInv255); |
1309 Sk4f sa = Sk4f(src.a()); | 1318 Sk4f sa = Sk4f(src.a()); |
1310 Sk4f da = Sk4f(dst.a()); | 1319 Sk4f da = Sk4f(dst.a()); |
1311 Sk4f sc = src; | 1320 Sk4f sc = src; |
1312 Sk4f dc = dst; | 1321 Sk4f dc = dst; |
1313 Sk4f rc = sc + dc + (sc * (dc - da) - dc * sa) * inv255; | 1322 Sk4f rc = sc + dc + (sc * (dc - da) - dc * sa) * inv255; |
1314 // ra = srcover(sa, da), but the calc for rc happens to accomplish this
for us | 1323 // ra = srcover(sa, da), but the calc for rc happens to accomplish this
for us |
1315 return check_as_pmfloat(clamp_0_255(rc)); | 1324 return check_as_pmfloat(clamp_0_255(rc)); |
1316 } | 1325 } |
| 1326 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
| 1327 return Sk4px::Wide(src.mulWiden(dst.alphas().inv()) + |
| 1328 dst.mulWiden(src.alphas().inv()) + |
| 1329 src.mulWiden(dst)) |
| 1330 .div255RoundNarrow(); |
| 1331 } |
1317 static const bool kFoldCoverageIntoSrcAlpha = false; | 1332 static const bool kFoldCoverageIntoSrcAlpha = false; |
1318 static const SkXfermode::Mode kMode = SkXfermode::kMultiply_Mode; | 1333 static const SkXfermode::Mode kMode = SkXfermode::kMultiply_Mode; |
1319 }; | 1334 }; |
1320 | 1335 |
1321 struct Difference4f { | 1336 struct Difference4f { |
1322 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1337 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1323 const Sk4f inv255(gInv255); | 1338 const Sk4f inv255(gInv255); |
1324 Sk4f sa = Sk4f(src.a()); | 1339 Sk4f sa = Sk4f(src.a()); |
1325 Sk4f da = Sk4f(dst.a()); | 1340 Sk4f da = Sk4f(dst.a()); |
1326 Sk4f sc = src; | 1341 Sk4f sc = src; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; | 1480 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; |
1466 | 1481 |
1467 ProcCoeff rec = gProcCoeffs[mode]; | 1482 ProcCoeff rec = gProcCoeffs[mode]; |
1468 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); | 1483 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); |
1469 if (pp != NULL) { | 1484 if (pp != NULL) { |
1470 rec.fProc = pp; | 1485 rec.fProc = pp; |
1471 } | 1486 } |
1472 | 1487 |
1473 #if defined(SK_4PX_XFERMODES_ARE_FAST) && !defined(SK_PREFER_LEGACY_FLOAT_XFERMO
DES) | 1488 #if defined(SK_4PX_XFERMODES_ARE_FAST) && !defined(SK_PREFER_LEGACY_FLOAT_XFERMO
DES) |
1474 switch (mode) { | 1489 switch (mode) { |
| 1490 case SkXfermode::kSrcATop_Mode: return SkT4pxXfermode<SrcATop4f>::Creat
e(rec); |
| 1491 case SkXfermode::kDstATop_Mode: return SkT4pxXfermode<DstATop4f>::Creat
e(rec); |
| 1492 case SkXfermode::kXor_Mode: return SkT4pxXfermode<Xor4f>::Create(re
c); |
1475 case SkXfermode::kPlus_Mode: return SkT4pxXfermode<Plus4f>::Create(r
ec); | 1493 case SkXfermode::kPlus_Mode: return SkT4pxXfermode<Plus4f>::Create(r
ec); |
1476 case SkXfermode::kModulate_Mode: return SkT4pxXfermode<Modulate4f>::Crea
te(rec); | 1494 case SkXfermode::kModulate_Mode: return SkT4pxXfermode<Modulate4f>::Crea
te(rec); |
1477 case SkXfermode::kScreen_Mode: return SkT4pxXfermode<Screen4f>::Create
(rec); | 1495 case SkXfermode::kScreen_Mode: return SkT4pxXfermode<Screen4f>::Create
(rec); |
| 1496 case SkXfermode::kMultiply_Mode: return SkT4pxXfermode<Multiply4f>::Crea
te(rec); |
1478 default: break; | 1497 default: break; |
1479 } | 1498 } |
1480 #endif | 1499 #endif |
1481 | 1500 |
1482 #if defined(SK_4F_XFERMODES_ARE_FAST) | 1501 #if defined(SK_4F_XFERMODES_ARE_FAST) |
1483 switch (mode) { | 1502 switch (mode) { |
1484 case SkXfermode::kSrcATop_Mode: return SkT4fXfermode<SrcATop4f>::Crea
te(rec); | 1503 case SkXfermode::kSrcATop_Mode: return SkT4fXfermode<SrcATop4f>::Crea
te(rec); |
1485 case SkXfermode::kDstATop_Mode: return SkT4fXfermode<DstATop4f>::Crea
te(rec); | 1504 case SkXfermode::kDstATop_Mode: return SkT4fXfermode<DstATop4f>::Crea
te(rec); |
1486 case SkXfermode::kXor_Mode: return SkT4fXfermode<Xor4f>::Create(r
ec); | 1505 case SkXfermode::kXor_Mode: return SkT4fXfermode<Xor4f>::Create(r
ec); |
1487 case SkXfermode::kPlus_Mode: return SkT4fXfermode<Plus4f>::Create(
rec); | 1506 case SkXfermode::kPlus_Mode: return SkT4fXfermode<Plus4f>::Create(
rec); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1787 } else { | 1806 } else { |
1788 proc16 = rec.fProc16_General; | 1807 proc16 = rec.fProc16_General; |
1789 } | 1808 } |
1790 } | 1809 } |
1791 return proc16; | 1810 return proc16; |
1792 } | 1811 } |
1793 | 1812 |
1794 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1813 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
1795 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1814 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
1796 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1815 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |