Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: src/core/SkXfermode.cpp

Issue 1141213002: Sk4px: Difference and Exclusion (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: back to 8-bit Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/Sk4px.h ('k') | src/opts/Sk4px_NEON.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { 1326 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) {
1327 return Sk4px::Wide(src.mulWiden(dst.alphas().inv()) + 1327 return Sk4px::Wide(src.mulWiden(dst.alphas().inv()) +
1328 dst.mulWiden(src.alphas().inv()) + 1328 dst.mulWiden(src.alphas().inv()) +
1329 src.mulWiden(dst)) 1329 src.mulWiden(dst))
1330 .div255RoundNarrow(); 1330 .div255RoundNarrow();
1331 } 1331 }
1332 static const bool kFoldCoverageIntoSrcAlpha = false; 1332 static const bool kFoldCoverageIntoSrcAlpha = false;
1333 static const SkXfermode::Mode kMode = SkXfermode::kMultiply_Mode; 1333 static const SkXfermode::Mode kMode = SkXfermode::kMultiply_Mode;
1334 }; 1334 };
1335 1335
1336 // [ sa + da - sa*da, sc + dc - 2*min(sc*da, dc*sa) ] (And notice sa*da == min( sa*da, da*sa).)
1336 struct Difference4f { 1337 struct Difference4f {
1337 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 1338 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) {
1338 const Sk4f inv255(gInv255); 1339 const Sk4f inv255(gInv255);
1339 Sk4f sa = Sk4f(src.a()); 1340 Sk4f sa = Sk4f(src.a());
1340 Sk4f da = Sk4f(dst.a()); 1341 Sk4f da = Sk4f(dst.a());
1341 Sk4f sc = src; 1342 Sk4f sc = src;
1342 Sk4f dc = dst; 1343 Sk4f dc = dst;
1343 Sk4f min = Sk4f::Min(sc * da, dc * sa) * inv255; 1344 Sk4f min = Sk4f::Min(sc * da, dc * sa) * inv255;
1344 Sk4f ra = sc + dc - min; 1345 Sk4f ra = sc + dc - min;
1345 return check_as_pmfloat(ra - min * SkPMFloat(0, 1, 1, 1)); 1346 return check_as_pmfloat(ra - min * SkPMFloat(0, 1, 1, 1));
1346 } 1347 }
1348 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) {
1349 auto m = Sk4px::Wide(Sk16h::Min(src.mulWiden(dst.alphas()), dst.mulWiden (src.alphas())))
1350 .div255RoundNarrow();
1351 // There's no chance of underflow, and if we subtract m before adding sr c+dst, no overflow.
1352 return (src - m) + (dst - m.zeroAlphas());
1353 }
1347 static const bool kFoldCoverageIntoSrcAlpha = false; 1354 static const bool kFoldCoverageIntoSrcAlpha = false;
1348 static const SkXfermode::Mode kMode = SkXfermode::kDifference_Mode; 1355 static const SkXfermode::Mode kMode = SkXfermode::kDifference_Mode;
1349 }; 1356 };
1350 1357
1358 // [ sa + da - sa*da, sc + dc - 2*sc*dc ]
1351 struct Exclusion4f { 1359 struct Exclusion4f {
1352 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 1360 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) {
1353 const Sk4f inv255(gInv255); 1361 const Sk4f inv255(gInv255);
1354 Sk4f sc = src; 1362 Sk4f sc = src;
1355 Sk4f dc = dst; 1363 Sk4f dc = dst;
1356 Sk4f prod = sc * dc * inv255; 1364 Sk4f prod = sc * dc * inv255;
1357 Sk4f ra = sc + dc - prod; 1365 Sk4f ra = sc + dc - prod;
1358 return check_as_pmfloat(ra - prod * SkPMFloat(0, 1, 1, 1)); 1366 return check_as_pmfloat(ra - prod * SkPMFloat(0, 1, 1, 1));
1359 } 1367 }
1368 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) {
1369 auto p = src.mulWiden(dst).div255RoundNarrow();
1370 // 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());
1372 }
1360 static const bool kFoldCoverageIntoSrcAlpha = false; 1373 static const bool kFoldCoverageIntoSrcAlpha = false;
1361 static const SkXfermode::Mode kMode = SkXfermode::kExclusion_Mode; 1374 static const SkXfermode::Mode kMode = SkXfermode::kExclusion_Mode;
1362 }; 1375 };
1363 1376
1364 template <typename ProcType> 1377 template <typename ProcType>
1365 class SkT4fXfermode : public SkProcCoeffXfermode { 1378 class SkT4fXfermode : public SkProcCoeffXfermode {
1366 public: 1379 public:
1367 static SkXfermode* Create(const ProcCoeff& rec) { 1380 static SkXfermode* Create(const ProcCoeff& rec) {
1368 return SkNEW_ARGS(SkT4fXfermode, (rec)); 1381 return SkNEW_ARGS(SkT4fXfermode, (rec));
1369 } 1382 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[ ]) const override { 1419 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[ ]) const override {
1407 if (NULL == aa) { 1420 if (NULL == aa) {
1408 Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& sr c4) { 1421 Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& sr c4) {
1409 return ProcType::Xfer(src4, dst4); 1422 return ProcType::Xfer(src4, dst4);
1410 }); 1423 });
1411 } else { 1424 } else {
1412 Sk4px::MapDstSrcAlpha(n, dst, src, aa, 1425 Sk4px::MapDstSrcAlpha(n, dst, src, aa,
1413 [&](const Sk4px& dst4, const Sk4px& src4, const Sk16b& alpha ) { 1426 [&](const Sk4px& dst4, const Sk4px& src4, const Sk16b& alpha ) {
1414 // We can't exploit kFoldCoverageIntoSrcAlpha. That requires >=2 4-bit intermediates. 1427 // We can't exploit kFoldCoverageIntoSrcAlpha. That requires >=2 4-bit intermediates.
1415 Sk4px res4 = ProcType::Xfer(src4, dst4); 1428 Sk4px res4 = ProcType::Xfer(src4, dst4);
1416 return Sk4px::Wide(res4.mulWiden(alpha) + dst4.mulWiden(Sk16b(25 5)-alpha)) 1429 return Sk4px::Wide(res4.mulWiden(alpha) + dst4.mulWiden(Sk4px(al pha).inv()))
1417 .div255RoundNarrow(); 1430 .div255RoundNarrow();
1418 }); 1431 });
1419 } 1432 }
1420 } 1433 }
1421 1434
1422 private: 1435 private:
1423 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM ode) {} 1436 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM ode) {}
1424 1437
1425 typedef SkProcCoeffXfermode INHERITED; 1438 typedef SkProcCoeffXfermode INHERITED;
1426 }; 1439 };
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; 1493 SkXfermode::Mode mode = (SkXfermode::Mode)iMode;
1481 1494
1482 ProcCoeff rec = gProcCoeffs[mode]; 1495 ProcCoeff rec = gProcCoeffs[mode];
1483 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); 1496 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode);
1484 if (pp != NULL) { 1497 if (pp != NULL) {
1485 rec.fProc = pp; 1498 rec.fProc = pp;
1486 } 1499 }
1487 1500
1488 #if defined(SK_4PX_XFERMODES_ARE_FAST) && !defined(SK_PREFER_LEGACY_FLOAT_XFERMO DES) 1501 #if defined(SK_4PX_XFERMODES_ARE_FAST) && !defined(SK_PREFER_LEGACY_FLOAT_XFERMO DES)
1489 switch (mode) { 1502 switch (mode) {
1490 case SkXfermode::kSrcATop_Mode: return SkT4pxXfermode<SrcATop4f>::Creat e(rec); 1503 case SkXfermode::kSrcATop_Mode: return SkT4pxXfermode<SrcATop4f>::Cre ate(rec);
1491 case SkXfermode::kDstATop_Mode: return SkT4pxXfermode<DstATop4f>::Creat e(rec); 1504 case SkXfermode::kDstATop_Mode: return SkT4pxXfermode<DstATop4f>::Cre ate(rec);
1492 case SkXfermode::kXor_Mode: return SkT4pxXfermode<Xor4f>::Create(re c); 1505 case SkXfermode::kXor_Mode: return SkT4pxXfermode<Xor4f>::Create( rec);
1493 case SkXfermode::kPlus_Mode: return SkT4pxXfermode<Plus4f>::Create(r ec); 1506 case SkXfermode::kPlus_Mode: return SkT4pxXfermode<Plus4f>::Create (rec);
1494 case SkXfermode::kModulate_Mode: return SkT4pxXfermode<Modulate4f>::Crea te(rec); 1507 case SkXfermode::kModulate_Mode: return SkT4pxXfermode<Modulate4f>::Cr eate(rec);
1495 case SkXfermode::kScreen_Mode: return SkT4pxXfermode<Screen4f>::Create (rec); 1508 case SkXfermode::kScreen_Mode: return SkT4pxXfermode<Screen4f>::Crea te(rec);
1496 case SkXfermode::kMultiply_Mode: return SkT4pxXfermode<Multiply4f>::Crea te(rec); 1509 case SkXfermode::kMultiply_Mode: return SkT4pxXfermode<Multiply4f>::Cr eate(rec);
1510 case SkXfermode::kDifference_Mode: return SkT4pxXfermode<Difference4f>:: Create(rec);
1511 case SkXfermode::kExclusion_Mode: return SkT4pxXfermode<Exclusion4f>::C reate(rec);
1497 default: break; 1512 default: break;
1498 } 1513 }
1499 #endif 1514 #endif
1500 1515
1501 #if defined(SK_4F_XFERMODES_ARE_FAST) 1516 #if defined(SK_4F_XFERMODES_ARE_FAST)
1502 switch (mode) { 1517 switch (mode) {
1503 case SkXfermode::kSrcATop_Mode: return SkT4fXfermode<SrcATop4f>::Crea te(rec); 1518 case SkXfermode::kSrcATop_Mode: return SkT4fXfermode<SrcATop4f>::Crea te(rec);
1504 case SkXfermode::kDstATop_Mode: return SkT4fXfermode<DstATop4f>::Crea te(rec); 1519 case SkXfermode::kDstATop_Mode: return SkT4fXfermode<DstATop4f>::Crea te(rec);
1505 case SkXfermode::kXor_Mode: return SkT4fXfermode<Xor4f>::Create(r ec); 1520 case SkXfermode::kXor_Mode: return SkT4fXfermode<Xor4f>::Create(r ec);
1506 case SkXfermode::kPlus_Mode: return SkT4fXfermode<Plus4f>::Create( rec); 1521 case SkXfermode::kPlus_Mode: return SkT4fXfermode<Plus4f>::Create( rec);
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 } else { 1821 } else {
1807 proc16 = rec.fProc16_General; 1822 proc16 = rec.fProc16_General;
1808 } 1823 }
1809 } 1824 }
1810 return proc16; 1825 return proc16;
1811 } 1826 }
1812 1827
1813 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 1828 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode)
1814 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 1829 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode)
1815 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1830 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « src/core/Sk4px.h ('k') | src/opts/Sk4px_NEON.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698