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 1176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1187 */ | 1187 */ |
1188 | 1188 |
1189 #ifndef SK_SUPPORT_LEGACY_SCALAR_XFERMODES | 1189 #ifndef SK_SUPPORT_LEGACY_SCALAR_XFERMODES |
1190 static const float gInv255 = 0.0039215683f; // (1.0f / 255) - ULP == SkBits2Flo
at(0x3B808080) | 1190 static const float gInv255 = 0.0039215683f; // (1.0f / 255) - ULP == SkBits2Flo
at(0x3B808080) |
1191 | 1191 |
1192 static Sk4f ramp(const Sk4f& v0, const Sk4f& v1, const Sk4f& t) { | 1192 static Sk4f ramp(const Sk4f& v0, const Sk4f& v1, const Sk4f& t) { |
1193 return v0 + (v1 - v0) * t; | 1193 return v0 + (v1 - v0) * t; |
1194 } | 1194 } |
1195 | 1195 |
1196 static Sk4f clamp_255(const Sk4f& value) { | 1196 static Sk4f clamp_255(const Sk4f& value) { |
1197 return Sk4f::Min(value, Sk4f(255)); | 1197 return Sk4f::Min(Sk4f(255), value); |
| 1198 } |
| 1199 |
| 1200 static Sk4f clamp_0_255(const Sk4f& value) { |
| 1201 return Sk4f::Max(Sk4f(0), Sk4f::Min(Sk4f(255), value)); |
1198 } | 1202 } |
1199 | 1203 |
1200 /** | 1204 /** |
1201 * Some modes can, due to very slight numerical error, generate "invalid" pmcol
ors... | 1205 * Some modes can, due to very slight numerical error, generate "invalid" pmcol
ors... |
1202 * | 1206 * |
1203 * e.g. | 1207 * e.g. |
1204 * alpha = 100.9999 | 1208 * alpha = 100.9999 |
1205 * red = 101 | 1209 * red = 101 |
1206 * | 1210 * |
1207 * or | 1211 * or |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 static const bool kFoldCoverageIntoSrcAlpha = false; | 1283 static const bool kFoldCoverageIntoSrcAlpha = false; |
1280 static const SkXfermode::Mode kMode = SkXfermode::kModulate_Mode; | 1284 static const SkXfermode::Mode kMode = SkXfermode::kModulate_Mode; |
1281 }; | 1285 }; |
1282 | 1286 |
1283 // kScreen_Mode [S + D - S * D] | 1287 // kScreen_Mode [S + D - S * D] |
1284 struct Screen4f { | 1288 struct Screen4f { |
1285 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1289 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1286 const Sk4f inv255(gInv255); | 1290 const Sk4f inv255(gInv255); |
1287 Sk4f s4 = src; | 1291 Sk4f s4 = src; |
1288 Sk4f d4 = dst; | 1292 Sk4f d4 = dst; |
1289 return check_as_pmfloat(check_as_pmfloat(s4 + d4 - s4 * d4 * inv255)); | 1293 return check_as_pmfloat(s4 + d4 - s4 * d4 * inv255); |
1290 } | 1294 } |
1291 static const bool kFoldCoverageIntoSrcAlpha = true; | 1295 static const bool kFoldCoverageIntoSrcAlpha = true; |
1292 static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode; | 1296 static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode; |
1293 }; | 1297 }; |
1294 | 1298 |
| 1299 struct Multiply4f { |
| 1300 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
| 1301 const Sk4f inv255(gInv255); |
| 1302 Sk4f sa = Sk4f(src.a()); |
| 1303 Sk4f da = Sk4f(dst.a()); |
| 1304 Sk4f sc = src; |
| 1305 Sk4f dc = dst; |
| 1306 Sk4f rc = sc + dc + (sc * (dc - da) - dc * sa) * inv255; |
| 1307 // ra = srcover(sa, da), but the calc for rc happens to accomplish this
for us |
| 1308 return check_as_pmfloat(clamp_0_255(rc)); |
| 1309 } |
| 1310 static const bool kFoldCoverageIntoSrcAlpha = false; |
| 1311 static const SkXfermode::Mode kMode = SkXfermode::kMultiply_Mode; |
| 1312 }; |
| 1313 |
1295 template <typename ProcType> | 1314 template <typename ProcType> |
1296 class SkT4fXfermode : public SkProcCoeffXfermode { | 1315 class SkT4fXfermode : public SkProcCoeffXfermode { |
1297 public: | 1316 public: |
1298 static SkXfermode* Create(const ProcCoeff& rec) { | 1317 static SkXfermode* Create(const ProcCoeff& rec) { |
1299 return SkNEW_ARGS(SkT4fXfermode, (rec)); | 1318 return SkNEW_ARGS(SkT4fXfermode, (rec)); |
1300 } | 1319 } |
1301 | 1320 |
1302 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[
]) const override { | 1321 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[
]) const override { |
1303 if (NULL == aa) { | 1322 if (NULL == aa) { |
1304 while (n & 3) { | 1323 while (n & 3) { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 break; | 1435 break; |
1417 case SkXfermode::kPlus_Mode: | 1436 case SkXfermode::kPlus_Mode: |
1418 xfer = SkT4fXfermode<Plus4f>::Create(rec); | 1437 xfer = SkT4fXfermode<Plus4f>::Create(rec); |
1419 break; | 1438 break; |
1420 case SkXfermode::kModulate_Mode: | 1439 case SkXfermode::kModulate_Mode: |
1421 xfer = SkT4fXfermode<Modulate4f>::Create(rec); | 1440 xfer = SkT4fXfermode<Modulate4f>::Create(rec); |
1422 break; | 1441 break; |
1423 case SkXfermode::kScreen_Mode: | 1442 case SkXfermode::kScreen_Mode: |
1424 xfer = SkT4fXfermode<Screen4f>::Create(rec); | 1443 xfer = SkT4fXfermode<Screen4f>::Create(rec); |
1425 break; | 1444 break; |
| 1445 case SkXfermode::kMultiply_Mode: |
| 1446 xfer = SkT4fXfermode<Multiply4f>::Create(rec); |
| 1447 break; |
1426 default: | 1448 default: |
1427 break; | 1449 break; |
1428 } | 1450 } |
1429 if (xfer) { | 1451 if (xfer) { |
1430 return xfer; | 1452 return xfer; |
1431 } | 1453 } |
1432 #endif | 1454 #endif |
1433 | 1455 |
1434 // check if we have a platform optim for that | 1456 // check if we have a platform optim for that |
1435 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); | 1457 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1722 } else { | 1744 } else { |
1723 proc16 = rec.fProc16_General; | 1745 proc16 = rec.fProc16_General; |
1724 } | 1746 } |
1725 } | 1747 } |
1726 return proc16; | 1748 return proc16; |
1727 } | 1749 } |
1728 | 1750 |
1729 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1751 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
1730 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1752 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
1731 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1753 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |