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 | 9 |
10 #include "SkXfermode.h" | 10 #include "SkXfermode.h" |
11 #include "SkColorPriv.h" | 11 #include "SkColorPriv.h" |
12 #include "SkFlattenableBuffers.h" | 12 #include "SkFlattenableBuffers.h" |
13 #include "SkMathPriv.h" | 13 #include "SkMathPriv.h" |
14 #include "SkString.h" | 14 #include "SkString.h" |
| 15 #include "SkXfermode_proccoeff.h" |
15 | 16 |
16 SK_DEFINE_INST_COUNT(SkXfermode) | 17 SK_DEFINE_INST_COUNT(SkXfermode) |
17 | 18 |
18 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) | 19 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) |
19 | 20 |
20 #if 0 | 21 #if 0 |
21 // idea for higher precision blends in xfer procs (and slightly faster) | 22 // idea for higher precision blends in xfer procs (and slightly faster) |
22 // see DstATop as a probable caller | 23 // see DstATop as a probable caller |
23 static U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) { | 24 static U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) { |
24 SkASSERT(a <= 255); | 25 SkASSERT(a <= 255); |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 Db = 0; | 625 Db = 0; |
625 } | 626 } |
626 | 627 |
627 int a = srcover_byte(sa, da); | 628 int a = srcover_byte(sa, da); |
628 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); | 629 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); |
629 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); | 630 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); |
630 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); | 631 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); |
631 return SkPackARGB32(a, r, g, b); | 632 return SkPackARGB32(a, r, g, b); |
632 } | 633 } |
633 | 634 |
634 | 635 const ProcCoeff gProcCoeffs[] = { |
635 struct ProcCoeff { | |
636 SkXfermodeProc fProc; | |
637 SkXfermode::Coeff fSC; | |
638 SkXfermode::Coeff fDC; | |
639 }; | |
640 | |
641 #define CANNOT_USE_COEFF SkXfermode::Coeff(-1) | |
642 | |
643 static const ProcCoeff gProcCoeffs[] = { | |
644 { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, | 636 { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, |
645 { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, | 637 { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, |
646 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, | 638 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, |
647 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, | 639 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, |
648 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, | 640 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, |
649 { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, | 641 { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, |
650 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, | 642 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, |
651 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, | 643 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, |
652 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, | 644 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, |
653 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, | 645 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1345 | 1337 |
1346 static AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermod
e::Mode>(mode), NULL))); | 1338 static AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermod
e::Mode>(mode), NULL))); |
1347 return CreateEffectRef(gEffect); | 1339 return CreateEffectRef(gEffect); |
1348 } | 1340 } |
1349 | 1341 |
1350 #endif | 1342 #endif |
1351 | 1343 |
1352 /////////////////////////////////////////////////////////////////////////////// | 1344 /////////////////////////////////////////////////////////////////////////////// |
1353 /////////////////////////////////////////////////////////////////////////////// | 1345 /////////////////////////////////////////////////////////////////////////////// |
1354 | 1346 |
1355 class SkProcCoeffXfermode : public SkProcXfermode { | |
1356 public: | |
1357 SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) | |
1358 : INHERITED(rec.fProc) { | |
1359 fMode = mode; | |
1360 // these may be valid, or may be CANNOT_USE_COEFF | |
1361 fSrcCoeff = rec.fSC; | |
1362 fDstCoeff = rec.fDC; | |
1363 } | |
1364 | |
1365 virtual bool asMode(Mode* mode) const SK_OVERRIDE { | |
1366 if (mode) { | |
1367 *mode = fMode; | |
1368 } | |
1369 return true; | |
1370 } | |
1371 | |
1372 virtual bool asCoeff(Coeff* sc, Coeff* dc) const SK_OVERRIDE { | |
1373 if (CANNOT_USE_COEFF == fSrcCoeff) { | |
1374 return false; | |
1375 } | |
1376 | |
1377 if (sc) { | |
1378 *sc = fSrcCoeff; | |
1379 } | |
1380 if (dc) { | |
1381 *dc = fDstCoeff; | |
1382 } | |
1383 return true; | |
1384 } | |
1385 | |
1386 #if SK_SUPPORT_GPU | |
1387 virtual bool asNewEffectOrCoeff(GrContext*, | |
1388 GrEffectRef** effect, | |
1389 Coeff* src, | |
1390 Coeff* dst, | |
1391 GrTexture* background) const SK_OVERRIDE { | |
1392 if (this->asCoeff(src, dst)) { | |
1393 return true; | |
1394 } | |
1395 if (XferEffect::IsSupportedMode(fMode)) { | |
1396 if (NULL != effect) { | |
1397 *effect = XferEffect::Create(fMode, background); | |
1398 SkASSERT(NULL != *effect); | |
1399 } | |
1400 return true; | |
1401 } | |
1402 return false; | |
1403 } | |
1404 #endif | |
1405 | |
1406 SK_DEVELOPER_TO_STRING() | |
1407 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) | |
1408 | |
1409 protected: | |
1410 SkProcCoeffXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { | |
1411 fMode = (SkXfermode::Mode)buffer.read32(); | |
1412 | |
1413 const ProcCoeff& rec = gProcCoeffs[fMode]; | |
1414 // these may be valid, or may be CANNOT_USE_COEFF | |
1415 fSrcCoeff = rec.fSC; | |
1416 fDstCoeff = rec.fDC; | |
1417 // now update our function-ptr in the super class | |
1418 this->INHERITED::setProc(rec.fProc); | |
1419 } | |
1420 | |
1421 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { | |
1422 this->INHERITED::flatten(buffer); | |
1423 buffer.write32(fMode); | |
1424 } | |
1425 | |
1426 private: | |
1427 Mode fMode; | |
1428 Coeff fSrcCoeff, fDstCoeff; | |
1429 | |
1430 typedef SkProcXfermode INHERITED; | |
1431 }; | |
1432 | 1347 |
1433 const char* SkXfermode::ModeName(Mode mode) { | 1348 const char* SkXfermode::ModeName(Mode mode) { |
1434 SkASSERT((unsigned) mode <= (unsigned)kLastMode); | 1349 SkASSERT((unsigned) mode <= (unsigned)kLastMode); |
1435 const char* gModeStrings[] = { | 1350 const char* gModeStrings[] = { |
1436 "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", | 1351 "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", |
1437 "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", | 1352 "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", |
1438 "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", | 1353 "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", |
1439 "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion", | 1354 "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion", |
1440 "Multiply", "Hue", "Saturation", "Color", "Luminosity" | 1355 "Multiply", "Hue", "Saturation", "Color", "Luminosity" |
1441 }; | 1356 }; |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1681 } | 1596 } |
1682 | 1597 |
1683 #ifdef SK_DEVELOPER | 1598 #ifdef SK_DEVELOPER |
1684 void SkDstOutXfermode::toString(SkString* str) const { | 1599 void SkDstOutXfermode::toString(SkString* str) const { |
1685 this->INHERITED::toString(str); | 1600 this->INHERITED::toString(str); |
1686 } | 1601 } |
1687 #endif | 1602 #endif |
1688 | 1603 |
1689 /////////////////////////////////////////////////////////////////////////////// | 1604 /////////////////////////////////////////////////////////////////////////////// |
1690 | 1605 |
| 1606 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, SkXf
ermode::Mode mode); |
| 1607 |
1691 SkXfermode* SkXfermode::Create(Mode mode) { | 1608 SkXfermode* SkXfermode::Create(Mode mode) { |
1692 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); | 1609 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); |
1693 SkASSERT((unsigned)mode < kModeCount); | 1610 SkASSERT((unsigned)mode < kModeCount); |
1694 | 1611 |
1695 const ProcCoeff& rec = gProcCoeffs[mode]; | 1612 const ProcCoeff& rec = gProcCoeffs[mode]; |
1696 | 1613 |
| 1614 // check if we have a platform optim for that |
| 1615 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); |
| 1616 if (xfm != NULL) { |
| 1617 return xfm; |
| 1618 } |
| 1619 |
1697 switch (mode) { | 1620 switch (mode) { |
1698 case kClear_Mode: | 1621 case kClear_Mode: |
1699 return SkNEW_ARGS(SkClearXfermode, (rec)); | 1622 return SkNEW_ARGS(SkClearXfermode, (rec)); |
1700 case kSrc_Mode: | 1623 case kSrc_Mode: |
1701 return SkNEW_ARGS(SkSrcXfermode, (rec)); | 1624 return SkNEW_ARGS(SkSrcXfermode, (rec)); |
1702 case kSrcOver_Mode: | 1625 case kSrcOver_Mode: |
1703 return NULL; | 1626 return NULL; |
1704 case kDstIn_Mode: | 1627 case kDstIn_Mode: |
1705 return SkNEW_ARGS(SkDstInXfermode, (rec)); | 1628 return SkNEW_ARGS(SkDstInXfermode, (rec)); |
1706 case kDstOut_Mode: | 1629 case kDstOut_Mode: |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1941 return proc16; | 1864 return proc16; |
1942 } | 1865 } |
1943 | 1866 |
1944 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1867 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
1945 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1868 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
1946 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) | 1869 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) |
1947 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) | 1870 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) |
1948 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) | 1871 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) |
1949 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) | 1872 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) |
1950 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1873 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |