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

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

Issue 23644006: ARM Skia NEON patches - 28 - Xfermode: SIMD modeprocs (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix android build + implement serialization Created 7 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « include/core/SkXfermode.h ('k') | src/core/SkXfermode_proccoeff.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 9
10 #include "SkXfermode.h" 10 #include "SkXfermode.h"
11 #include "SkXfermode_proccoeff.h"
11 #include "SkColorPriv.h" 12 #include "SkColorPriv.h"
12 #include "SkFlattenableBuffers.h" 13 #include "SkFlattenableBuffers.h"
13 #include "SkMathPriv.h" 14 #include "SkMathPriv.h"
14 #include "SkString.h" 15 #include "SkString.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
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 Db = 0; 618 Db = 0;
618 } 619 }
619 620
620 int a = srcover_byte(sa, da); 621 int a = srcover_byte(sa, da);
621 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); 622 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr);
622 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); 623 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg);
623 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); 624 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db);
624 return SkPackARGB32(a, r, g, b); 625 return SkPackARGB32(a, r, g, b);
625 } 626 }
626 627
627 628 const ProcCoeff gProcCoeffs[] = {
628 struct ProcCoeff {
629 SkXfermodeProc fProc;
630 SkXfermode::Coeff fSC;
631 SkXfermode::Coeff fDC;
632 };
633
634 #define CANNOT_USE_COEFF SkXfermode::Coeff(-1)
635
636 static const ProcCoeff gProcCoeffs[] = {
637 { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, 629 { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff },
638 { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, 630 { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff },
639 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, 631 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff },
640 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, 632 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff },
641 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, 633 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff },
642 { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, 634 { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff },
643 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, 635 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff },
644 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, 636 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff },
645 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, 637 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff },
646 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, 638 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff },
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 1330
1339 static AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermod e::Mode>(mode), NULL))); 1331 static AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermod e::Mode>(mode), NULL)));
1340 return CreateEffectRef(gEffect); 1332 return CreateEffectRef(gEffect);
1341 } 1333 }
1342 1334
1343 #endif 1335 #endif
1344 1336
1345 /////////////////////////////////////////////////////////////////////////////// 1337 ///////////////////////////////////////////////////////////////////////////////
1346 /////////////////////////////////////////////////////////////////////////////// 1338 ///////////////////////////////////////////////////////////////////////////////
1347 1339
1348 class SkProcCoeffXfermode : public SkProcXfermode { 1340 bool SkProcCoeffXfermode::asMode(Mode* mode) const {
1349 public: 1341 if (mode) {
1350 SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) 1342 *mode = fMode;
1351 : INHERITED(rec.fProc) { 1343 }
1352 fMode = mode; 1344 return true;
1353 // these may be valid, or may be CANNOT_USE_COEFF 1345 }
1354 fSrcCoeff = rec.fSC; 1346
1355 fDstCoeff = rec.fDC; 1347 bool SkProcCoeffXfermode::asCoeff(Coeff* sc, Coeff* dc) const {
1348 if (CANNOT_USE_COEFF == fSrcCoeff) {
1349 return false;
1356 } 1350 }
1357 1351
1358 virtual bool asMode(Mode* mode) const SK_OVERRIDE { 1352 if (sc) {
1359 if (mode) { 1353 *sc = fSrcCoeff;
1360 *mode = fMode; 1354 }
1355 if (dc) {
1356 *dc = fDstCoeff;
1357 }
1358 return true;
1359 }
1360
1361 #if SK_SUPPORT_GPU
1362 bool SkProcCoeffXfermode::asNewEffectOrCoeff(GrContext*,
1363 GrEffectRef** effect,
1364 Coeff* src,
1365 Coeff* dst,
1366 GrTexture* background) const {
1367 if (this->asCoeff(src, dst)) {
1368 return true;
1369 }
1370 if (XferEffect::IsSupportedMode(fMode)) {
1371 if (NULL != effect) {
1372 *effect = XferEffect::Create(fMode, background);
1373 SkASSERT(NULL != *effect);
1361 } 1374 }
1362 return true; 1375 return true;
1363 } 1376 }
1364 1377 return false;
1365 virtual bool asCoeff(Coeff* sc, Coeff* dc) const SK_OVERRIDE { 1378 }
1366 if (CANNOT_USE_COEFF == fSrcCoeff) {
1367 return false;
1368 }
1369
1370 if (sc) {
1371 *sc = fSrcCoeff;
1372 }
1373 if (dc) {
1374 *dc = fDstCoeff;
1375 }
1376 return true;
1377 }
1378
1379 #if SK_SUPPORT_GPU
1380 virtual bool asNewEffectOrCoeff(GrContext*,
1381 GrEffectRef** effect,
1382 Coeff* src,
1383 Coeff* dst,
1384 GrTexture* background) const SK_OVERRIDE {
1385 if (this->asCoeff(src, dst)) {
1386 return true;
1387 }
1388 if (XferEffect::IsSupportedMode(fMode)) {
1389 if (NULL != effect) {
1390 *effect = XferEffect::Create(fMode, background);
1391 SkASSERT(NULL != *effect);
1392 }
1393 return true;
1394 }
1395 return false;
1396 }
1397 #endif 1379 #endif
1398 1380
1399 SK_DEVELOPER_TO_STRING() 1381 void SkProcCoeffXfermode::flatten(SkFlattenableWriteBuffer& buffer) const {
1400 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) 1382 this->INHERITED::flatten(buffer);
1401 1383 buffer.write32(fMode);
1402 protected: 1384 }
1403 SkProcCoeffXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
1404 fMode = (SkXfermode::Mode)buffer.read32();
1405
1406 const ProcCoeff& rec = gProcCoeffs[fMode];
1407 // these may be valid, or may be CANNOT_USE_COEFF
1408 fSrcCoeff = rec.fSC;
1409 fDstCoeff = rec.fDC;
1410 // now update our function-ptr in the super class
1411 this->INHERITED::setProc(rec.fProc);
1412 }
1413
1414 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
1415 this->INHERITED::flatten(buffer);
1416 buffer.write32(fMode);
1417 }
1418
1419 private:
1420 Mode fMode;
1421 Coeff fSrcCoeff, fDstCoeff;
1422
1423 typedef SkProcXfermode INHERITED;
1424 };
1425 1385
1426 const char* SkXfermode::ModeName(Mode mode) { 1386 const char* SkXfermode::ModeName(Mode mode) {
1427 SkASSERT((unsigned) mode <= (unsigned)kLastMode); 1387 SkASSERT((unsigned) mode <= (unsigned)kLastMode);
1428 const char* gModeStrings[] = { 1388 const char* gModeStrings[] = {
1429 "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", 1389 "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn",
1430 "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", 1390 "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus",
1431 "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", 1391 "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge",
1432 "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion", 1392 "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion",
1433 "Multiply", "Hue", "Saturation", "Color", "Luminosity" 1393 "Multiply", "Hue", "Saturation", "Color", "Luminosity"
1434 }; 1394 };
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 1646
1687 void SkXfermode::Term() { 1647 void SkXfermode::Term() {
1688 SkAutoMutexAcquire ac(gCachedXfermodesMutex); 1648 SkAutoMutexAcquire ac(gCachedXfermodesMutex);
1689 1649
1690 for (size_t i = 0; i < SK_ARRAY_COUNT(gCachedXfermodes); ++i) { 1650 for (size_t i = 0; i < SK_ARRAY_COUNT(gCachedXfermodes); ++i) {
1691 SkSafeUnref(gCachedXfermodes[i]); 1651 SkSafeUnref(gCachedXfermodes[i]);
1692 gCachedXfermodes[i] = NULL; 1652 gCachedXfermodes[i] = NULL;
1693 } 1653 }
1694 } 1654 }
1695 1655
1656 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec,
1657 SkXfermode::Mode mode);
1658
1696 SkXfermode* SkXfermode::Create(Mode mode) { 1659 SkXfermode* SkXfermode::Create(Mode mode) {
1697 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 1660 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
1698 SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount); 1661 SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount);
1699 1662
1700 if ((unsigned)mode >= kModeCount) { 1663 if ((unsigned)mode >= kModeCount) {
1701 // report error 1664 // report error
1702 return NULL; 1665 return NULL;
1703 } 1666 }
1704 1667
1705 // Skia's "defaut" mode is srcover. NULL in SkPaint is interpreted as srcove r 1668 // Skia's "defaut" mode is srcover. NULL in SkPaint is interpreted as srcove r
1706 // so we can just return NULL from the factory. 1669 // so we can just return NULL from the factory.
1707 if (kSrcOver_Mode == mode) { 1670 if (kSrcOver_Mode == mode) {
1708 return NULL; 1671 return NULL;
1709 } 1672 }
1710 1673
1711 // guard our access to gCachedXfermodes, since we may write into it 1674 // guard our access to gCachedXfermodes, since we may write into it
1712 SkAutoMutexAcquire ac(gCachedXfermodesMutex); 1675 SkAutoMutexAcquire ac(gCachedXfermodesMutex);
1713 1676
1714 SkXfermode* xfer = gCachedXfermodes[mode]; 1677 SkXfermode* xfer = gCachedXfermodes[mode];
1715 if (NULL == xfer) { 1678 if (NULL == xfer) {
1716 const ProcCoeff& rec = gProcCoeffs[mode]; 1679 const ProcCoeff& rec = gProcCoeffs[mode];
1717 // All modes can in theory be represented by the ProcCoeff rec, since 1680
1718 // it contains function ptrs. However, a few modes are both simple and 1681 // check if we have a platform optim for that
1719 // commonly used, so we call those out for their own subclasses here. 1682 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode);
1720 switch (mode) { 1683 if (xfm != NULL) {
1721 case kClear_Mode: 1684 xfer = xfm;
1722 xfer = SkNEW_ARGS(SkClearXfermode, (rec)); 1685 } else {
1723 break; 1686 // All modes can in theory be represented by the ProcCoeff rec, sinc e
1724 case kSrc_Mode: 1687 // it contains function ptrs. However, a few modes are both simple a nd
1725 xfer = SkNEW_ARGS(SkSrcXfermode, (rec)); 1688 // commonly used, so we call those out for their own subclasses here .
1726 break; 1689 switch (mode) {
1727 case kSrcOver_Mode: 1690 case kClear_Mode:
1728 SkASSERT(false); // should not land here 1691 xfer = SkNEW_ARGS(SkClearXfermode, (rec));
1729 break; 1692 break;
1730 case kDstIn_Mode: 1693 case kSrc_Mode:
1731 xfer = SkNEW_ARGS(SkDstInXfermode, (rec)); 1694 xfer = SkNEW_ARGS(SkSrcXfermode, (rec));
1732 break; 1695 break;
1733 case kDstOut_Mode: 1696 case kSrcOver_Mode:
1734 xfer = SkNEW_ARGS(SkDstOutXfermode, (rec)); 1697 SkASSERT(false); // should not land here
1735 break; 1698 break;
1736 default: 1699 case kDstIn_Mode:
1737 // no special-case, just rely in the rec and its function-ptrs 1700 xfer = SkNEW_ARGS(SkDstInXfermode, (rec));
1738 xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); 1701 break;
1739 break; 1702 case kDstOut_Mode:
1703 xfer = SkNEW_ARGS(SkDstOutXfermode, (rec));
1704 break;
1705 default:
1706 // no special-case, just rely in the rec and its function-pt rs
1707 xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode));
1708 break;
1709 }
1740 } 1710 }
1741 gCachedXfermodes[mode] = xfer; 1711 gCachedXfermodes[mode] = xfer;
1742 } 1712 }
1743 return SkSafeRef(xfer); 1713 return SkSafeRef(xfer);
1744 } 1714 }
1745 1715
1746 SkXfermodeProc SkXfermode::GetProc(Mode mode) { 1716 SkXfermodeProc SkXfermode::GetProc(Mode mode) {
1747 SkXfermodeProc proc = NULL; 1717 SkXfermodeProc proc = NULL;
1748 if ((unsigned)mode < kModeCount) { 1718 if ((unsigned)mode < kModeCount) {
1749 proc = gProcCoeffs[mode].fProc; 1719 proc = gProcCoeffs[mode].fProc;
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1974 return proc16; 1944 return proc16;
1975 } 1945 }
1976 1946
1977 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 1947 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode)
1978 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 1948 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode)
1979 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) 1949 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode)
1980 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) 1950 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode)
1981 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) 1951 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode)
1982 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) 1952 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode)
1983 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1953 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « include/core/SkXfermode.h ('k') | src/core/SkXfermode_proccoeff.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698