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

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

Issue 1141953004: sk4px the rest of the easy xfermodes. (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: unify 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') | no next file » | 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 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/core/Sk4px.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698