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

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

Issue 1138893002: Plus xfermode using Sk4px. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: guard 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/SkNx.h ('k') | src/opts/SkNx_sse.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"
11 #include "SkXfermode_proccoeff.h" 11 #include "SkXfermode_proccoeff.h"
12 #include "Sk4px.h"
12 #include "SkColorPriv.h" 13 #include "SkColorPriv.h"
13 #include "SkLazyPtr.h" 14 #include "SkLazyPtr.h"
14 #include "SkMathPriv.h" 15 #include "SkMathPriv.h"
15 #include "SkPMFloat.h" 16 #include "SkPMFloat.h"
16 #include "SkReadBuffer.h" 17 #include "SkReadBuffer.h"
17 #include "SkString.h" 18 #include "SkString.h"
18 #include "SkUtilsArm.h" 19 #include "SkUtilsArm.h"
19 #include "SkWriteBuffer.h" 20 #include "SkWriteBuffer.h"
20 21
21 #ifndef SK_SUPPORT_LEGACY_SCALAR_XFERMODES 22 #ifndef SK_SUPPORT_LEGACY_SCALAR_XFERMODES
(...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 } 1263 }
1263 static const bool kFoldCoverageIntoSrcAlpha = true; 1264 static const bool kFoldCoverageIntoSrcAlpha = true;
1264 static const SkXfermode::Mode kMode = SkXfermode::kXor_Mode; 1265 static const SkXfermode::Mode kMode = SkXfermode::kXor_Mode;
1265 }; 1266 };
1266 1267
1267 // kPlus_Mode [Sa + Da, Sc + Dc] 1268 // kPlus_Mode [Sa + Da, Sc + Dc]
1268 struct Plus4f { 1269 struct Plus4f {
1269 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 1270 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) {
1270 return check_as_pmfloat(clamp_255(src + dst)); 1271 return check_as_pmfloat(clamp_255(src + dst));
1271 } 1272 }
1272 static const bool kFoldCoverageIntoSrcAlpha = true; 1273 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) {
1274 return src.saturatedAdd(dst);
1275 }
1276 static const bool kFoldCoverageIntoSrcAlpha = false;
1273 static const SkXfermode::Mode kMode = SkXfermode::kPlus_Mode; 1277 static const SkXfermode::Mode kMode = SkXfermode::kPlus_Mode;
1274 }; 1278 };
1275 1279
1276 // kModulate_Mode [Sa * Da, Sc * Dc] 1280 // kModulate_Mode [Sa * Da, Sc * Dc]
1277 struct Modulate4f { 1281 struct Modulate4f {
1278 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 1282 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) {
1279 const Sk4f inv255(gInv255); 1283 const Sk4f inv255(gInv255);
1280 return check_as_pmfloat(src * dst * inv255); 1284 return check_as_pmfloat(src * dst * inv255);
1281 } 1285 }
1286 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) {
1287 return src.mulWiden(dst).div255RoundNarrow();
1288 }
1282 static const bool kFoldCoverageIntoSrcAlpha = false; 1289 static const bool kFoldCoverageIntoSrcAlpha = false;
1283 static const SkXfermode::Mode kMode = SkXfermode::kModulate_Mode; 1290 static const SkXfermode::Mode kMode = SkXfermode::kModulate_Mode;
1284 }; 1291 };
1285 1292
1286 // kScreen_Mode [S + D - S * D] 1293 // kScreen_Mode [S + D - S * D]
1287 struct Screen4f { 1294 struct Screen4f {
1288 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 1295 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) {
1289 const Sk4f inv255(gInv255); 1296 const Sk4f inv255(gInv255);
1290 return check_as_pmfloat(src + dst - src * dst * inv255); 1297 return check_as_pmfloat(src + dst - src * dst * inv255);
1291 } 1298 }
1299 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) {
1300 // Doing the math as S + (1-S)*D or S + (D - S*D) means the add and subt ract can be done
1301 // in 8-bit space without overflow. S + (1-S)*D is a touch faster becau se 255-x is an xor.
1302 // TODO: do we need to explicitly implement / call Sk16b(255) ^ src ?
1303 return src + Sk4px(Sk16b(255) - src).mulWiden(dst).div255RoundNarrow();
1304 }
1292 static const bool kFoldCoverageIntoSrcAlpha = true; 1305 static const bool kFoldCoverageIntoSrcAlpha = true;
1293 static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode; 1306 static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode;
1294 }; 1307 };
1295 1308
1296 struct Multiply4f { 1309 struct Multiply4f {
1297 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { 1310 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) {
1298 const Sk4f inv255(gInv255); 1311 const Sk4f inv255(gInv255);
1299 Sk4f sa = Sk4f(src.a()); 1312 Sk4f sa = Sk4f(src.a());
1300 Sk4f da = Sk4f(dst.a()); 1313 Sk4f da = Sk4f(dst.a());
1301 Sk4f sc = src; 1314 Sk4f sc = src;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 dst[i] = SkPMFloat(res).round(); 1376 dst[i] = SkPMFloat(res).round();
1364 } 1377 }
1365 } 1378 }
1366 } 1379 }
1367 1380
1368 private: 1381 private:
1369 SkT4fXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kMo de) {} 1382 SkT4fXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kMo de) {}
1370 1383
1371 typedef SkProcCoeffXfermode INHERITED; 1384 typedef SkProcCoeffXfermode INHERITED;
1372 }; 1385 };
1386
1387 template <typename ProcType>
1388 class SkT4pxXfermode : public SkProcCoeffXfermode {
1389 public:
1390 static SkXfermode* Create(const ProcCoeff& rec) {
1391 return SkNEW_ARGS(SkT4pxXfermode, (rec));
1392 }
1393
1394 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[ ]) const override {
1395 if (NULL == aa) {
1396 Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& sr c4) {
1397 return ProcType::Xfer(src4, dst4);
1398 });
1399 } else {
1400 Sk4px::MapDstSrcAlpha(n, dst, src, aa,
1401 [&](const Sk4px& dst4, const Sk4px& src4, const Sk16b& alpha ) {
1402 // We can't exploit kFoldCoverageIntoSrcAlpha. That requires >=2 4-bit intermediates.
1403 Sk4px res4 = ProcType::Xfer(src4, dst4);
1404 return Sk4px::Wide(res4.mulWiden(alpha) + dst4.mulWiden(Sk16b(25 5)-alpha))
1405 .div255RoundNarrow();
1406 });
1407 }
1408 }
1409
1410 private:
1411 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM ode) {}
1412
1413 typedef SkProcCoeffXfermode INHERITED;
1414 };
1373 #endif 1415 #endif
1374 1416
1375 /////////////////////////////////////////////////////////////////////////////// 1417 ///////////////////////////////////////////////////////////////////////////////
1376 1418
1377 class SkDstOutXfermode : public SkProcCoeffXfermode { 1419 class SkDstOutXfermode : public SkProcCoeffXfermode {
1378 public: 1420 public:
1379 static SkDstOutXfermode* Create(const ProcCoeff& rec) { 1421 static SkDstOutXfermode* Create(const ProcCoeff& rec) {
1380 return SkNEW_ARGS(SkDstOutXfermode, (rec)); 1422 return SkNEW_ARGS(SkDstOutXfermode, (rec));
1381 } 1423 }
1382 1424
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 switch (mode) { 1480 switch (mode) {
1439 case SkXfermode::kSrcATop_Mode: 1481 case SkXfermode::kSrcATop_Mode:
1440 xfer = SkT4fXfermode<SrcATop4f>::Create(rec); 1482 xfer = SkT4fXfermode<SrcATop4f>::Create(rec);
1441 break; 1483 break;
1442 case SkXfermode::kDstATop_Mode: 1484 case SkXfermode::kDstATop_Mode:
1443 xfer = SkT4fXfermode<DstATop4f>::Create(rec); 1485 xfer = SkT4fXfermode<DstATop4f>::Create(rec);
1444 break; 1486 break;
1445 case SkXfermode::kXor_Mode: 1487 case SkXfermode::kXor_Mode:
1446 xfer = SkT4fXfermode<Xor4f>::Create(rec); 1488 xfer = SkT4fXfermode<Xor4f>::Create(rec);
1447 break; 1489 break;
1490 #ifdef SK_PREFER_LEGACY_FLOAT_XFERMODES
1448 case SkXfermode::kPlus_Mode: 1491 case SkXfermode::kPlus_Mode:
1449 xfer = SkT4fXfermode<Plus4f>::Create(rec); 1492 xfer = SkT4fXfermode<Plus4f>::Create(rec);
1450 break; 1493 break;
1451 case SkXfermode::kModulate_Mode: 1494 case SkXfermode::kModulate_Mode:
1452 xfer = SkT4fXfermode<Modulate4f>::Create(rec); 1495 xfer = SkT4fXfermode<Modulate4f>::Create(rec);
1453 break; 1496 break;
1454 case SkXfermode::kScreen_Mode: 1497 case SkXfermode::kScreen_Mode:
1455 xfer = SkT4fXfermode<Screen4f>::Create(rec); 1498 xfer = SkT4fXfermode<Screen4f>::Create(rec);
1456 break; 1499 break;
1500 #else
1501 case SkXfermode::kPlus_Mode:
1502 xfer = SkT4pxXfermode<Plus4f>::Create(rec);
1503 break;
1504 case SkXfermode::kModulate_Mode:
1505 xfer = SkT4pxXfermode<Modulate4f>::Create(rec);
1506 break;
1507 case SkXfermode::kScreen_Mode:
1508 xfer = SkT4pxXfermode<Screen4f>::Create(rec);
1509 break;
1510 #endif
1457 case SkXfermode::kMultiply_Mode: 1511 case SkXfermode::kMultiply_Mode:
1458 xfer = SkT4fXfermode<Multiply4f>::Create(rec); 1512 xfer = SkT4fXfermode<Multiply4f>::Create(rec);
1459 break; 1513 break;
1460 case SkXfermode::kDifference_Mode: 1514 case SkXfermode::kDifference_Mode:
1461 xfer = SkT4fXfermode<Difference4f>::Create(rec); 1515 xfer = SkT4fXfermode<Difference4f>::Create(rec);
1462 break; 1516 break;
1463 case SkXfermode::kExclusion_Mode: 1517 case SkXfermode::kExclusion_Mode:
1464 xfer = SkT4fXfermode<Exclusion4f>::Create(rec); 1518 xfer = SkT4fXfermode<Exclusion4f>::Create(rec);
1465 break; 1519 break;
1466 default: 1520 default:
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1762 } else { 1816 } else {
1763 proc16 = rec.fProc16_General; 1817 proc16 = rec.fProc16_General;
1764 } 1818 }
1765 } 1819 }
1766 return proc16; 1820 return proc16;
1767 } 1821 }
1768 1822
1769 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 1823 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode)
1770 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 1824 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode)
1771 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1825 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « src/core/SkNx.h ('k') | src/opts/SkNx_sse.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698